Add donwloaded megabytes and current download speed to the
download window
This commit is contained in:
@@ -152,6 +152,8 @@ class Constants:
|
|||||||
APPLY = "Apply"
|
APPLY = "Apply"
|
||||||
REMOVE = "Remove"
|
REMOVE = "Remove"
|
||||||
UNKNOWN = "N/A"
|
UNKNOWN = "N/A"
|
||||||
|
EXTRACTING_MSG = "Extracting..."
|
||||||
|
EXTRACTING_CODE = -1
|
||||||
MODULATIONS = ("8VSB",
|
MODULATIONS = ("8VSB",
|
||||||
"AFSK",
|
"AFSK",
|
||||||
"AM",
|
"AM",
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
<height>137</height>
|
<height>157</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Download database</string>
|
<string>Download database</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset resource="icon.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/Artemis3.ico</normaloff>:/icons/Artemis3.ico</iconset>
|
<normaloff>:/icons/Artemis3.ico</normaloff>:/icons/Artemis3.ico</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
@@ -33,7 +33,23 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Downloading database
|
<string>Downloading database
|
||||||
Please wait...</string>
|
Please wait...
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="status_lbl">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>status</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignCenter</set>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal
|
|||||||
from PyQt5.QtWidgets import QWidget
|
from PyQt5.QtWidgets import QWidget
|
||||||
from threads import DownloadThread, ThreadStatus
|
from threads import DownloadThread, ThreadStatus
|
||||||
from utilities import pop_up, resource_path
|
from utilities import pop_up, resource_path
|
||||||
from constants import Messages
|
from constants import Constants, Messages
|
||||||
|
|
||||||
Ui_Download_window, _ = uic.loadUiType(resource_path("download_db_window.ui"))
|
Ui_Download_window, _ = uic.loadUiType(resource_path("download_db_window.ui"))
|
||||||
|
|
||||||
@@ -33,8 +33,23 @@ class DownloadWindow(QWidget, Ui_Download_window):
|
|||||||
|
|
||||||
self.download_thread = DownloadThread()
|
self.download_thread = DownloadThread()
|
||||||
self.download_thread.finished.connect(self.wait_close)
|
self.download_thread.finished.connect(self.wait_close)
|
||||||
|
self.download_thread.progress.connect(self.__display_progress)
|
||||||
self.cancel_btn.clicked.connect(self.terminate_process)
|
self.cancel_btn.clicked.connect(self.terminate_process)
|
||||||
|
|
||||||
|
def __downlaod_format_str(self, n, speed):
|
||||||
|
return f"Downloaded MB: {n}\nSpeed: {speed} MB/s"
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
self.status_lbl.setText(self.__downlaod_format_str(0, 0))
|
||||||
|
super().show()
|
||||||
|
|
||||||
|
@pyqtSlot(int, float)
|
||||||
|
def __display_progress(self, progress, speed):
|
||||||
|
if progress != Constants.EXTRACTING_CODE:
|
||||||
|
self.status_lbl.setText(self.__downlaod_format_str(progress, speed))
|
||||||
|
elif progress == Constants.EXTRACTING_CODE:
|
||||||
|
self.status_lbl.setText(Constants.EXTRACTING_MSG + '\n')
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def terminate_process(self):
|
def terminate_process(self):
|
||||||
if self.download_thread.isRunning():
|
if self.download_thread.isRunning():
|
||||||
|
|||||||
50
threads.py
50
threads.py
@@ -1,12 +1,14 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from math import ceil
|
||||||
import os.path
|
import os.path
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
|
from time import time
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib3
|
import urllib3
|
||||||
from PyQt5.QtCore import QThread
|
from PyQt5.QtCore import QThread, pyqtSignal
|
||||||
from constants import Constants, Database, ChecksumWhat
|
from constants import Constants, Database, ChecksumWhat
|
||||||
from utilities import checksum_ok
|
from utilities import checksum_ok
|
||||||
|
|
||||||
@@ -30,23 +32,56 @@ class BaseDownloadThread(QThread):
|
|||||||
|
|
||||||
|
|
||||||
class DownloadThread(BaseDownloadThread):
|
class DownloadThread(BaseDownloadThread):
|
||||||
|
|
||||||
|
progress = pyqtSignal(int, float)
|
||||||
|
CHUNK = 1024**2
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.reason = 0
|
|
||||||
|
def __pretty_len(self, byte_obj):
|
||||||
|
mega = len(byte_obj) / self.CHUNK
|
||||||
|
if mega.is_integer():
|
||||||
|
return int(mega)
|
||||||
|
else:
|
||||||
|
return ceil(mega)
|
||||||
|
|
||||||
|
def __get_download_speed(self, data, delta):
|
||||||
|
return round(
|
||||||
|
(len(data) / self.CHUNK) / delta,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.status = ThreadStatus.UNDEFINED
|
self.status = ThreadStatus.UNDEFINED
|
||||||
|
raw_data = bytes(0)
|
||||||
try:
|
try:
|
||||||
db = urllib3.PoolManager().request('GET', Database.LINK_LOC)
|
db = urllib3.PoolManager().request(
|
||||||
except urllib3.exceptions.MaxRetryError: # No internet connection.
|
'GET',
|
||||||
|
Database.LINK_LOC,
|
||||||
|
preload_content=False
|
||||||
|
)
|
||||||
|
while True:
|
||||||
|
start = time()
|
||||||
|
data = db.read(self.CHUNK)
|
||||||
|
delta = time() - start
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
raw_data += data
|
||||||
|
self.progress.emit(
|
||||||
|
self.__pretty_len(raw_data),
|
||||||
|
self.__get_download_speed(data, delta)
|
||||||
|
)
|
||||||
|
db.release_conn()
|
||||||
|
except Exception: # No internet connection.
|
||||||
|
db.release_conn()
|
||||||
self.status = ThreadStatus.NO_CONNECTION_ERR
|
self.status = ThreadStatus.NO_CONNECTION_ERR
|
||||||
return
|
return
|
||||||
if db.status != 200:
|
if db.status != 200:
|
||||||
self.reason = db.reason
|
|
||||||
self.status = ThreadStatus.BAD_DOWNLOAD_ERR
|
self.status = ThreadStatus.BAD_DOWNLOAD_ERR
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
is_checksum_ok = checksum_ok(db.data, ChecksumWhat.FOLDER)
|
is_checksum_ok = checksum_ok(raw_data, ChecksumWhat.FOLDER)
|
||||||
except Exception:
|
except Exception:
|
||||||
self.status = ThreadStatus.NO_CONNECTION_ERR
|
self.status = ThreadStatus.NO_CONNECTION_ERR
|
||||||
return
|
return
|
||||||
@@ -57,7 +92,8 @@ class DownloadThread(BaseDownloadThread):
|
|||||||
if os.path.exists(Constants.DATA_FOLDER):
|
if os.path.exists(Constants.DATA_FOLDER):
|
||||||
rmtree(Constants.DATA_FOLDER)
|
rmtree(Constants.DATA_FOLDER)
|
||||||
try:
|
try:
|
||||||
with ZipFile(BytesIO(db.data)) as zipped:
|
self.progress.emit(Constants.EXTRACTING_CODE, 0.0)
|
||||||
|
with ZipFile(BytesIO(raw_data)) as zipped:
|
||||||
zipped.extractall()
|
zipped.extractall()
|
||||||
except Exception:
|
except Exception:
|
||||||
self.status = ThreadStatus.UNKNOWN_ERR
|
self.status = ThreadStatus.UNKNOWN_ERR
|
||||||
|
|||||||
Reference in New Issue
Block a user