mirror of
https://github.com/spaam/svtplay-dl.git
synced 2024-11-24 12:15:40 +01:00
b31834fd6e
The progressbar() currently does not handle the case where the total size is unknown. But with this change, progress() will internally use progressbar() for its bar generation, while still supporting a more basic progress info when total size is unknown.
110 lines
3.0 KiB
Python
110 lines
3.0 KiB
Python
# ex:ts=4:sw=4:sts=4:et
|
|
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
|
from __future__ import absolute_import
|
|
import sys
|
|
import os
|
|
import time
|
|
from datetime import timedelta
|
|
|
|
progress_stream = sys.stderr
|
|
|
|
class ETA(object):
|
|
"""
|
|
An ETA class, used to calculate how long it takes to process
|
|
an arbitrary set of items. By initiating the object with the
|
|
number of items and continuously updating with current
|
|
progress, the class can calculate an estimation of how long
|
|
time remains.
|
|
"""
|
|
|
|
def __init__(self, end, start=0):
|
|
"""
|
|
Parameters:
|
|
end: the end (or size, of start is 0)
|
|
start: the starting position, defaults to 0
|
|
"""
|
|
self.start = start
|
|
self.end = end
|
|
self.pos = start
|
|
|
|
self.now = time.time()
|
|
self.start_time = self.now
|
|
|
|
def update(self, pos):
|
|
"""
|
|
Set new absolute progress position.
|
|
|
|
Parameters:
|
|
pos: new absolute progress
|
|
"""
|
|
self.pos = pos
|
|
self.now = time.time()
|
|
|
|
def increment(self, skip=1):
|
|
"""
|
|
Like update, but set new pos relative to old pos.
|
|
|
|
Parameters:
|
|
skip: progress since last update (defaults to 1)
|
|
"""
|
|
self.update(self.pos + skip)
|
|
|
|
@property
|
|
def left(self):
|
|
"""
|
|
returns: How many item remains?
|
|
"""
|
|
return self.end - self.pos
|
|
|
|
def __str__(self):
|
|
"""
|
|
returns: a time string of the format HH:MM:SS.
|
|
"""
|
|
duration = self.now - self.start_time
|
|
|
|
# Calculate how long it takes to process one item
|
|
try:
|
|
elm_time = duration / (self.end - self.left)
|
|
except ZeroDivisionError:
|
|
return "(unknown)"
|
|
|
|
return str(timedelta(seconds=int(elm_time * self.left)))
|
|
|
|
|
|
def progress(byte, total, extra = ""):
|
|
""" Print some info about how much we have downloaded """
|
|
if total == 0:
|
|
progresstr = "Downloaded %dkB bytes" % (byte >> 10)
|
|
progress_stream.write(progresstr + '\r')
|
|
return
|
|
progressbar(total, byte, extra)
|
|
|
|
def progressbar(total, pos, msg=""):
|
|
"""
|
|
Given a total and a progress position, output a progress bar
|
|
to stderr. It is important to not output anything else while
|
|
using this, as it relies soley on the behavior of carriage
|
|
return (\\r).
|
|
|
|
Can also take an optioal message to add after the
|
|
progressbar. It must not contain newliens.
|
|
|
|
The progress bar will look something like this:
|
|
|
|
[099/500][=========...............................] ETA: 13:36:59
|
|
|
|
Of course, the ETA part should be supplied be the calling
|
|
function.
|
|
"""
|
|
width = 50 # TODO hardcoded progressbar width
|
|
rel_pos = int(float(pos)/total*width)
|
|
bar = ''.join(["=" * rel_pos, "." * (width - rel_pos)])
|
|
|
|
# Determine how many digits in total (base 10)
|
|
digits_total = len(str(total))
|
|
fmt_width = "%0" + str(digits_total) + "d"
|
|
fmt = "\r[" + fmt_width + "/" + fmt_width + "][%s] %s"
|
|
|
|
progress_stream.write(fmt % (pos, total, bar, msg))
|
|
|