# -*- coding: ascii -*-

###########################################################################
# clive, video extraction utility
# Copyright (C) 2007-2008 Toni Gundogdu
#
# clive is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 0.1.2-1307 USA
###########################################################################

## The classes used to represent data transfer progress

import os
import sys
import time
import types
import math

__all__ = ['Progress', 'ProgressVerify']


## The class used for file transfers
class Progress:

    ## Constructor
    def __init__(self, opts, v_info):
        self._opts = opts
        self._v_info = v_info

    ## Callback method for urlgrabber
    def start(self, filename, url, basename, length, text):
        self._filename = filename
        self._url = url
        self._basename = basename
        self._length = length
        self._tstarted = time.time()
        self._tthen = time.time()
        self._num_bspaces = 0

    ## Callback method for urlgrabber
    def update(self, read, end=0):
        if not end:
            elapsed = time.time() - self._tthen
            if elapsed < 1.0: return

        text = ''

        fn = os.path.basename(self._filename)
        if len(fn) > 40: fn = fn[:38] + '..'
        text += fn.ljust(40)

        progress = self._percent(read, self._length)
        if progress > 0: text += ('%d%%' % progress).rjust(6)
        else: text += ''.rjust(6)

        text += self._byteshuman(self._length).rjust(10)

        elapsed = time.time() - self._tstarted
        rate = (read - self._v_info['offset']) / elapsed
        left = (self._length - read) / rate
        t = [left,elapsed][end]
        gmt = time.gmtime(t)
        eta = '%02d:%02d:%02d' % (gmt[3], gmt[4], gmt[5])
        text += (self._byteshuman(rate) + '/s').rjust(12)
        text += eta.rjust(10)

        self._write_bspaced(text)
        self._tthen = time.time()

    ## Callback method for urlgrabber
    def end(self, total):
        if total == self._v_info['length_bytes']:
            self.update(total, end=1)
        self._write_stdout('\n')
    
    def _percent(self, i, j):
        if not i or not j: return 0
        return int(float(i) / float(j) * 100)

    def _byteshuman(self, bytes):
        a = ['B','KB','MB','GB','TB']
        try:
            i = int(math.floor(math.log(bytes,1024)))
            b = round(float(bytes/math.pow(1024,i)),2)
        except OverflowError:
            i = 0; b = 0;
        return '%.1f%s' % (b,a[i])

    def _write_bspaced(self, text):
        bspaces = ''
        if self._num_bspaces > 0:
            bspaces = '\b' * self._num_bspaces
        self._write_stdout(bspaces + text)
        self._num_bspaces = len(text)
    
    def _write_stdout(self, text):
        if self._opts.enable_verbose:
            sys.stdout.write(text)
            sys.stdout.flush()


## The class used for video page (HTML) transfers
class ProgressVerify(Progress):

    ## Constructor
    def __init__(self, opts, index):
        self._opts = opts
        self._index = index

    ## Prints out a line using cached data
    def from_cache(self, url, row):
        self._url = url
        (url, self._length, xurl, v_id, low_ql) = row
        self.update(self._length, cached=1)

    ## Callback method for urlgrabber
    def update(self, read, cached=0):
        if read == 0: return
        text = ''

        progress = self._percent(read, self._length)

        if len(self._url) > 60: text += (self._url[:58] + '..')
        else: text += self._url
        text = text.ljust(60)

        if not cached:
            if progress > 0: s = '%d%%' % progress
            else: s = self._byteshuman(read)
        else:
            s = '(cache)'
        text += s.rjust(8)

        if self._index[1] > 1:
            text += ('%d/%d' % (self._index[0]+1, \
                self._index[1])).rjust(10)

        if not cached:
            self._write_bspaced(text)
        else:
            self._write_stdout(text)


