Add a rolling average of dl speed for time estimation
This commit is contained in:
parent
d80c05b0b1
commit
85ee71b739
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QTimer
|
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QTimer
|
||||||
from PyQt5.QtNetwork import QNetworkReply
|
from PyQt5.QtNetwork import QNetworkReply
|
||||||
@ -37,6 +38,8 @@ class DownloadItem(QObject):
|
|||||||
|
|
||||||
Class attributes:
|
Class attributes:
|
||||||
SPEED_REFRESH_INTERVAL: How often to refresh the speed, in msec.
|
SPEED_REFRESH_INTERVAL: How often to refresh the speed, in msec.
|
||||||
|
SPEED_AVG_WINDOW: How many seconds of speed data to average to
|
||||||
|
estimate the remaining time.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
reply: The QNetworkReply associated with this download.
|
reply: The QNetworkReply associated with this download.
|
||||||
@ -47,6 +50,7 @@ class DownloadItem(QObject):
|
|||||||
fileobj: The file object to download the file to.
|
fileobj: The file object to download the file to.
|
||||||
filename: The filename of the download.
|
filename: The filename of the download.
|
||||||
is_cancelled: Whether the download was cancelled.
|
is_cancelled: Whether the download was cancelled.
|
||||||
|
speed_avg: A rolling average of speeds.
|
||||||
_last_done: The count of bytes which where downloaded when calculating
|
_last_done: The count of bytes which where downloaded when calculating
|
||||||
the speed the last time.
|
the speed the last time.
|
||||||
_last_percentage: The remembered percentage for data_changed.
|
_last_percentage: The remembered percentage for data_changed.
|
||||||
@ -60,6 +64,7 @@ class DownloadItem(QObject):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
SPEED_REFRESH_INTERVAL = 500
|
SPEED_REFRESH_INTERVAL = 500
|
||||||
|
SPEED_AVG_WINDOW = 30
|
||||||
data_changed = pyqtSignal()
|
data_changed = pyqtSignal()
|
||||||
finished = pyqtSignal()
|
finished = pyqtSignal()
|
||||||
error = pyqtSignal(str)
|
error = pyqtSignal(str)
|
||||||
@ -77,6 +82,9 @@ class DownloadItem(QObject):
|
|||||||
self.bytes_total = None
|
self.bytes_total = None
|
||||||
self.speed = None
|
self.speed = None
|
||||||
self.basename = '???'
|
self.basename = '???'
|
||||||
|
samples = int(self.SPEED_AVG_WINDOW *
|
||||||
|
(1000 / self.SPEED_REFRESH_INTERVAL))
|
||||||
|
self.speed_avg = deque(maxlen=samples)
|
||||||
self.fileobj = None
|
self.fileobj = None
|
||||||
self.filename = None
|
self.filename = None
|
||||||
self.is_cancelled = False
|
self.is_cancelled = False
|
||||||
@ -137,9 +145,11 @@ class DownloadItem(QObject):
|
|||||||
def remaining_time(self):
|
def remaining_time(self):
|
||||||
"""Property to get the remaining download time in seconds."""
|
"""Property to get the remaining download time in seconds."""
|
||||||
if (self.bytes_total is None or self.bytes_total <= 0 or
|
if (self.bytes_total is None or self.bytes_total <= 0 or
|
||||||
self.speed is None or self.speed == 0):
|
self.speed is None or not self.speed_avg):
|
||||||
return None
|
return None
|
||||||
return (self.bytes_total - self.bytes_done) / self.speed
|
remaining_bytes = self.bytes_total - self.bytes_done
|
||||||
|
speed = sum(self.speed_avg) / len(self.speed_avg)
|
||||||
|
return remaining_bytes / speed
|
||||||
|
|
||||||
def bg_color(self):
|
def bg_color(self):
|
||||||
"""Background color to be shown."""
|
"""Background color to be shown."""
|
||||||
@ -267,7 +277,7 @@ class DownloadItem(QObject):
|
|||||||
else:
|
else:
|
||||||
delta = self.bytes_done - self._last_done
|
delta = self.bytes_done - self._last_done
|
||||||
self.speed = delta * 1000 / self.SPEED_REFRESH_INTERVAL
|
self.speed = delta * 1000 / self.SPEED_REFRESH_INTERVAL
|
||||||
logger.debug("Download speed: {} bytes/sec".format(self.speed))
|
self.speed_avg.append(self.speed)
|
||||||
self._last_done = self.bytes_done
|
self._last_done = self.bytes_done
|
||||||
self.data_changed.emit()
|
self.data_changed.emit()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user