File size request from HTTP header, handled the indeterminate size case
This commit is contained in:
@@ -6635,7 +6635,7 @@ G@\x11\x10HG\x93Hp\xec\x0au\xe3\xcd\x1e\xf4\
|
||||
>k\xd0\xd3b\x1eG\xb5_d\xde\xb6{\x8f\x95\xc5\
|
||||
U\xaf\xbc\xfd\xe9\xb5\x9f\xe5\xe3}r\xba?\xbbI\x06\
|
||||
\xfe\xfc\x0f\xf4\xcd*2\
|
||||
\x00\x00\x06\x95\
|
||||
\x00\x00\x070\
|
||||
i\
|
||||
mport QtQuick\x0d\x0ai\
|
||||
mport QtQuick.Wi\
|
||||
@@ -6674,75 +6674,84 @@ ceived\x0d\x0a \
|
||||
progressBar.to =\
|
||||
bytesTotal\x0d\x0a \
|
||||
}\x0d\x0a\x0d\x0a functi\
|
||||
on updateStatus(\
|
||||
arg) {\x0d\x0a \
|
||||
progressLabel.te\
|
||||
xt = arg\x0d\x0a }\x0d\
|
||||
\x0a\x0d\x0a Page {\x0d\x0a \
|
||||
id: page\x0d\
|
||||
\x0a anchors\
|
||||
.fill: parent\x0d\x0a\x0d\
|
||||
\x0a ColumnL\
|
||||
ayout {\x0d\x0a \
|
||||
id: columnL\
|
||||
ayout\x0d\x0a \
|
||||
on setIndetermin\
|
||||
ateBar() {\x0d\x0a \
|
||||
progressBar.\
|
||||
indeterminate = \
|
||||
true\x0d\x0a }\x0d\x0a\x0d\x0a \
|
||||
function upda\
|
||||
teStatus(arg) {\x0d\
|
||||
\x0a progres\
|
||||
sLabel.text = ar\
|
||||
g\x0d\x0a }\x0d\x0a\x0d\x0a \
|
||||
Page {\x0d\x0a \
|
||||
id: page\x0d\x0a \
|
||||
anchors.fill: \
|
||||
parent\x0d\x0a\x0d\x0a \
|
||||
ColumnLayout {\
|
||||
\x0d\x0a id\
|
||||
: columnLayout\x0d\x0a\
|
||||
anch\
|
||||
ors.fill: parent\
|
||||
\x0d\x0a\x0d\x0a \
|
||||
Label {\x0d\x0a \
|
||||
\
|
||||
text: qsTr(\x22Down\
|
||||
loading in progr\
|
||||
ess...\x22)\x0d\x0a \
|
||||
Layout\
|
||||
.alignment: Qt.A\
|
||||
lignHCenter | Qt\
|
||||
.AlignVCenter\x0d\x0a \
|
||||
text: q\
|
||||
sTr(\x22Downloading\
|
||||
in progress...\x22\
|
||||
)\x0d\x0a \
|
||||
Layout.alignm\
|
||||
ent: Qt.AlignHCe\
|
||||
nter | Qt.AlignV\
|
||||
Center\x0d\x0a \
|
||||
}\x0d\x0a\x0d\x0a \
|
||||
Prog\
|
||||
ressBar {\x0d\x0a \
|
||||
id: p\
|
||||
rogressBar\x0d\x0a \
|
||||
Layo\
|
||||
ut.rightMargin: \
|
||||
ProgressBar\
|
||||
{\x0d\x0a \
|
||||
id: progress\
|
||||
Bar\x0d\x0a \
|
||||
Layout.righ\
|
||||
tMargin: 20\x0d\x0a \
|
||||
Lay\
|
||||
out.leftMargin: \
|
||||
20\x0d\x0a \
|
||||
Layout.leftM\
|
||||
argin: 20\x0d\x0a \
|
||||
Layou\
|
||||
t.fillWidth: tru\
|
||||
e\x0d\x0a \
|
||||
Layout.fillW\
|
||||
idth: true\x0d\x0a \
|
||||
inde\
|
||||
terminate: false\
|
||||
\x0d\x0a \
|
||||
value: 0\x0d\x0a \
|
||||
to: \
|
||||
0\x0d\x0a \
|
||||
}\x0d\x0a\x0d\x0a \
|
||||
0\x0d\x0a }\
|
||||
\x0d\x0a\x0d\x0a \
|
||||
Label {\x0d\x0a \
|
||||
id: pr\
|
||||
ogressLabel\x0d\x0a \
|
||||
Lay\
|
||||
out.alignment: Q\
|
||||
t.AlignHCenter |\
|
||||
Qt.AlignVCenter\
|
||||
\x0d\x0a }\x0d\
|
||||
\x0a\x0d\x0a B\
|
||||
utton {\x0d\x0a \
|
||||
text: q\
|
||||
sTr(\x22Abort\x22)\x0d\x0a \
|
||||
ic\
|
||||
on.source: \x22qrc:\
|
||||
/images/icons/ab\
|
||||
ort.svg\x22\x0d\x0a \
|
||||
displa\
|
||||
y: AbstractButto\
|
||||
n.TextBesideIcon\
|
||||
\x0d\x0a \
|
||||
Layout.alignme\
|
||||
nt: Qt.AlignHCen\
|
||||
ter | Qt.AlignBo\
|
||||
ttom\x0d\x0a \
|
||||
onClicked:\
|
||||
{ onAbort() }\x0d\x0a\
|
||||
}\x0d\x0a \
|
||||
}\x0d\x0a }\x0d\
|
||||
id: pro\
|
||||
gressLabel\x0d\x0a \
|
||||
Layo\
|
||||
ut.alignment: Qt\
|
||||
.AlignHCenter | \
|
||||
Qt.AlignVCenter\x0d\
|
||||
\x0a }\x0d\x0a\
|
||||
\x0d\x0a Bu\
|
||||
tton {\x0d\x0a \
|
||||
Layout.a\
|
||||
lignment: Qt.Ali\
|
||||
gnHCenter | Qt.A\
|
||||
lignBottom\x0d\x0a \
|
||||
text\
|
||||
: qsTr(\x22Abort\x22)\x0d\
|
||||
\x0a \
|
||||
icon.source: \x22q\
|
||||
rc:/images/icons\
|
||||
/abort.svg\x22\x0d\x0a \
|
||||
dis\
|
||||
play: AbstractBu\
|
||||
tton.TextBesideI\
|
||||
con\x0d\x0a \
|
||||
flat: true\x0d\
|
||||
\x0a \
|
||||
onClicked: { on\
|
||||
Abort() }\x0d\x0a \
|
||||
}\x0d\x0a \
|
||||
}\x0d\x0a }\x0d\x0a}\x0d\x0a\
|
||||
\x00\x00\x05\xac\
|
||||
i\
|
||||
mport QtQuick\x0d\x0ai\
|
||||
@@ -7293,12 +7302,12 @@ qt_resource_struct = b"\
|
||||
\x00\x00\x01\x8f\xff^8P\
|
||||
\x00\x00\x03<\x00\x01\x00\x00\x00\x01\x00\x01>\xe2\
|
||||
\x00\x00\x01\x8f\xff^8P\
|
||||
\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\x9f\xdf\
|
||||
\x00\x00\x05\xa8\x00\x00\x00\x00\x00\x01\x00\x01\xa0z\
|
||||
\x00\x00\x01\x8f\xff^8P\
|
||||
\x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I\x0c\
|
||||
\x00\x00\x01\x8f\xff^8_\
|
||||
\x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99F\
|
||||
\x00\x00\x01\x90\x03\xb0\x82B\
|
||||
\x00\x00\x01\x90\x0e\xde\xeeO\
|
||||
\x00\x00\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01v\x14\
|
||||
@@ -7317,13 +7326,13 @@ qt_resource_struct = b"\
|
||||
\x00\x00\x01\x8f\xff^8P\
|
||||
\x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xad\
|
||||
\x00\x00\x01\x8f\xff^8P\
|
||||
\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa8\x92\
|
||||
\x00\x00\x05\xdc\x00\x01\x00\x00\x00\x01\x00\x01\xa9-\
|
||||
\x00\x00\x01\x8f\xff^8_\
|
||||
\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xae\xd7\
|
||||
\x00\x00\x06$\x00\x01\x00\x00\x00\x01\x00\x01\xafr\
|
||||
\x00\x00\x01\x8f\xff^8_\
|
||||
\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa5\x8f\
|
||||
\x00\x00\x05\xc0\x00\x01\x00\x00\x00\x01\x00\x01\xa6*\
|
||||
\x00\x00\x01\x8f\xff^8_\
|
||||
\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xabU\
|
||||
\x00\x00\x06\x00\x00\x01\x00\x00\x00\x01\x00\x01\xab\xf0\
|
||||
\x00\x00\x01\x8f\xff^8_\
|
||||
"
|
||||
|
||||
|
||||
@@ -226,7 +226,6 @@ class UIArtemis(QObject):
|
||||
self.downloader.finished.connect(self.update_manager.post_download_db)
|
||||
self.downloader.on_start(
|
||||
self.update_manager.remote_db_url,
|
||||
self.update_manager.remote_db_size,
|
||||
DATA_DIR
|
||||
)
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import requests
|
||||
|
||||
from PySide6.QtQml import QQmlApplicationEngine
|
||||
from PySide6.QtCore import QObject, Slot, Signal, QUrl, QSaveFile, QDir, QIODevice
|
||||
from PySide6.QtNetwork import QNetworkReply, QNetworkRequest, QNetworkAccessManager
|
||||
@@ -7,11 +9,12 @@ from artemis.utils.constants import Messages
|
||||
|
||||
class UIDownloader(QObject):
|
||||
# Python > QML Signals
|
||||
finished = Signal()
|
||||
show_ui = Signal()
|
||||
close_ui = Signal()
|
||||
update_progress_bar = Signal(int, int)
|
||||
set_indeterminate_bar = Signal()
|
||||
update_status = Signal(str)
|
||||
finished = Signal()
|
||||
|
||||
|
||||
def __init__(self, parent):
|
||||
@@ -25,6 +28,10 @@ class UIDownloader(QObject):
|
||||
|
||||
self.file_url = None
|
||||
self.file_size = None
|
||||
self.dest_file = None
|
||||
self.file = None
|
||||
self.manager = None
|
||||
self.reply = None
|
||||
|
||||
self._connect()
|
||||
|
||||
@@ -37,17 +44,22 @@ class UIDownloader(QObject):
|
||||
self.show_ui.connect(self._window.show)
|
||||
self.close_ui.connect(self._window.close)
|
||||
self.update_progress_bar.connect(self._window.updateProgressBar)
|
||||
self.set_indeterminate_bar.connect(self._window.setIndeterminateBar)
|
||||
self.update_status.connect(self._window.updateStatus)
|
||||
|
||||
|
||||
def on_start(self, url, filesize, save_path):
|
||||
""" Start the download of the DB taking the needed url and size from
|
||||
the attributes of the UpdatesController class
|
||||
def on_start(self, url, save_path):
|
||||
""" Start the download process using the specified URL
|
||||
|
||||
Args:
|
||||
url (str): url from where download the file
|
||||
save_path (str): path where to save the downloaded file
|
||||
"""
|
||||
|
||||
self.show_ui.emit()
|
||||
|
||||
self.file_url = QUrl(url)
|
||||
self.file_size = filesize
|
||||
self.file_size = self._get_filesize(url)
|
||||
dest_path = QDir(save_path)
|
||||
self.dest_file = dest_path.filePath(self.file_url.fileName())
|
||||
self.file = QSaveFile(self.dest_file)
|
||||
@@ -69,7 +81,8 @@ class UIDownloader(QObject):
|
||||
|
||||
@Slot()
|
||||
def on_abort(self):
|
||||
""" Stop the download when user press abort button """
|
||||
""" Stop the download when user presses the abort button
|
||||
"""
|
||||
if self.reply:
|
||||
self.reply.abort()
|
||||
self.update_progress_bar.emit(0, 0)
|
||||
@@ -80,7 +93,8 @@ class UIDownloader(QObject):
|
||||
|
||||
@Slot()
|
||||
def on_ready_read(self):
|
||||
""" Get available bytes and store them into the file """
|
||||
""" Write available bytes to the file
|
||||
"""
|
||||
if self.reply:
|
||||
if self.reply.error() == QNetworkReply.NoError:
|
||||
self.file.write(self.reply.readAll())
|
||||
@@ -88,8 +102,9 @@ class UIDownloader(QObject):
|
||||
|
||||
@Slot()
|
||||
def on_finished(self):
|
||||
""" Delete reply, close the file, check the hash for integrity,
|
||||
extract the database and delete the downloaded zip
|
||||
""" Finalize the download process and if no errors
|
||||
occurrs emits the finished signal usefulle for
|
||||
a callback
|
||||
"""
|
||||
if self.reply:
|
||||
self.reply.deleteLater()
|
||||
@@ -105,10 +120,13 @@ class UIDownloader(QObject):
|
||||
|
||||
@Slot(int, int)
|
||||
def on_progress(self, bytesReceived: int):
|
||||
""" Update progress bar and label
|
||||
""" Update progress bar and status label
|
||||
"""
|
||||
if self.file_size is not None:
|
||||
self.update_status.emit("{:.1f} Mb / {:.1f} Mb".format(bytesReceived/10**6, self.file_size/10**6))
|
||||
self.update_progress_bar.emit(bytesReceived, self.file_size)
|
||||
else:
|
||||
self.update_status.emit("{:.1f} Mb".format(bytesReceived/10**6))
|
||||
|
||||
|
||||
@Slot(QNetworkReply.NetworkError)
|
||||
@@ -122,6 +140,22 @@ class UIDownloader(QObject):
|
||||
)
|
||||
|
||||
|
||||
def _get_filesize(self, url):
|
||||
""" Get the file size by sending a HEAD request to the URL.
|
||||
If the Content-Length in HTTP headers is missing, returns None
|
||||
|
||||
Args:
|
||||
url (str): URL to check the file size
|
||||
"""
|
||||
try:
|
||||
response = requests.get(url, stream=True)
|
||||
size = int(response.headers.get('content-length'))
|
||||
return size
|
||||
except:
|
||||
self.set_indeterminate_bar.emit()
|
||||
return None
|
||||
|
||||
|
||||
def show_popup_error(self, error_msg):
|
||||
self._parent.dialog_popup(
|
||||
Messages.DIALOG_TYPE_ERROR,
|
||||
|
||||
@@ -29,6 +29,10 @@ Window {
|
||||
progressBar.to = bytesTotal
|
||||
}
|
||||
|
||||
function setIndeterminateBar() {
|
||||
progressBar.indeterminate = true
|
||||
}
|
||||
|
||||
function updateStatus(arg) {
|
||||
progressLabel.text = arg
|
||||
}
|
||||
@@ -51,6 +55,7 @@ Window {
|
||||
Layout.rightMargin: 20
|
||||
Layout.leftMargin: 20
|
||||
Layout.fillWidth: true
|
||||
indeterminate: false
|
||||
value: 0
|
||||
to: 0
|
||||
}
|
||||
@@ -61,10 +66,11 @@ Window {
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
text: qsTr("Abort")
|
||||
icon.source: "qrc:/images/icons/abort.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
flat: true
|
||||
onClicked: { onAbort() }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user