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\
|
>k\xd0\xd3b\x1eG\xb5_d\xde\xb6{\x8f\x95\xc5\
|
||||||
U\xaf\xbc\xfd\xe9\xb5\x9f\xe5\xe3}r\xba?\xbbI\x06\
|
U\xaf\xbc\xfd\xe9\xb5\x9f\xe5\xe3}r\xba?\xbbI\x06\
|
||||||
\xfe\xfc\x0f\xf4\xcd*2\
|
\xfe\xfc\x0f\xf4\xcd*2\
|
||||||
\x00\x00\x06\x95\
|
\x00\x00\x070\
|
||||||
i\
|
i\
|
||||||
mport QtQuick\x0d\x0ai\
|
mport QtQuick\x0d\x0ai\
|
||||||
mport QtQuick.Wi\
|
mport QtQuick.Wi\
|
||||||
@@ -6674,75 +6674,84 @@ ceived\x0d\x0a \
|
|||||||
progressBar.to =\
|
progressBar.to =\
|
||||||
bytesTotal\x0d\x0a \
|
bytesTotal\x0d\x0a \
|
||||||
}\x0d\x0a\x0d\x0a functi\
|
}\x0d\x0a\x0d\x0a functi\
|
||||||
on updateStatus(\
|
on setIndetermin\
|
||||||
arg) {\x0d\x0a \
|
ateBar() {\x0d\x0a \
|
||||||
progressLabel.te\
|
progressBar.\
|
||||||
xt = arg\x0d\x0a }\x0d\
|
indeterminate = \
|
||||||
\x0a\x0d\x0a Page {\x0d\x0a \
|
true\x0d\x0a }\x0d\x0a\x0d\x0a \
|
||||||
id: page\x0d\
|
function upda\
|
||||||
\x0a anchors\
|
teStatus(arg) {\x0d\
|
||||||
.fill: parent\x0d\x0a\x0d\
|
\x0a progres\
|
||||||
\x0a ColumnL\
|
sLabel.text = ar\
|
||||||
ayout {\x0d\x0a \
|
g\x0d\x0a }\x0d\x0a\x0d\x0a \
|
||||||
id: columnL\
|
Page {\x0d\x0a \
|
||||||
ayout\x0d\x0a \
|
id: page\x0d\x0a \
|
||||||
anchors.fill:\
|
anchors.fill: \
|
||||||
parent\x0d\x0a\x0d\x0a \
|
parent\x0d\x0a\x0d\x0a \
|
||||||
Label {\x0d\x0a\
|
ColumnLayout {\
|
||||||
\
|
\x0d\x0a id\
|
||||||
text: qsTr(\x22Down\
|
: columnLayout\x0d\x0a\
|
||||||
loading in progr\
|
anch\
|
||||||
ess...\x22)\x0d\x0a \
|
ors.fill: parent\
|
||||||
Layout\
|
\x0d\x0a\x0d\x0a \
|
||||||
.alignment: Qt.A\
|
Label {\x0d\x0a \
|
||||||
lignHCenter | Qt\
|
|
||||||
.AlignVCenter\x0d\x0a \
|
|
||||||
}\x0d\x0a\x0d\x0a\
|
|
||||||
Prog\
|
|
||||||
ressBar {\x0d\x0a \
|
|
||||||
id: p\
|
|
||||||
rogressBar\x0d\x0a \
|
|
||||||
Layo\
|
|
||||||
ut.rightMargin: \
|
|
||||||
20\x0d\x0a \
|
|
||||||
Layout.leftM\
|
|
||||||
argin: 20\x0d\x0a \
|
|
||||||
Layou\
|
|
||||||
t.fillWidth: tru\
|
|
||||||
e\x0d\x0a \
|
|
||||||
value: 0\x0d\x0a \
|
|
||||||
to:\
|
|
||||||
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\
|
text: q\
|
||||||
sTr(\x22Abort\x22)\x0d\x0a \
|
sTr(\x22Downloading\
|
||||||
ic\
|
in progress...\x22\
|
||||||
on.source: \x22qrc:\
|
)\x0d\x0a \
|
||||||
/images/icons/ab\
|
Layout.alignm\
|
||||||
ort.svg\x22\x0d\x0a \
|
ent: Qt.AlignHCe\
|
||||||
displa\
|
nter | Qt.AlignV\
|
||||||
y: AbstractButto\
|
Center\x0d\x0a \
|
||||||
n.TextBesideIcon\
|
}\x0d\x0a\x0d\x0a \
|
||||||
|
ProgressBar\
|
||||||
|
{\x0d\x0a \
|
||||||
|
id: progress\
|
||||||
|
Bar\x0d\x0a \
|
||||||
|
Layout.righ\
|
||||||
|
tMargin: 20\x0d\x0a \
|
||||||
|
Lay\
|
||||||
|
out.leftMargin: \
|
||||||
|
20\x0d\x0a \
|
||||||
|
Layout.fillW\
|
||||||
|
idth: true\x0d\x0a \
|
||||||
|
inde\
|
||||||
|
terminate: false\
|
||||||
\x0d\x0a \
|
\x0d\x0a \
|
||||||
Layout.alignme\
|
value: 0\x0d\x0a \
|
||||||
nt: Qt.AlignHCen\
|
to: \
|
||||||
ter | Qt.AlignBo\
|
0\x0d\x0a }\
|
||||||
ttom\x0d\x0a \
|
\x0d\x0a\x0d\x0a \
|
||||||
onClicked:\
|
Label {\x0d\x0a \
|
||||||
{ onAbort() }\x0d\x0a\
|
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\
|
}\x0d\x0a }\x0d\x0a}\x0d\x0a\
|
||||||
\x0a}\x0d\x0a\
|
|
||||||
\x00\x00\x05\xac\
|
\x00\x00\x05\xac\
|
||||||
i\
|
i\
|
||||||
mport QtQuick\x0d\x0ai\
|
mport QtQuick\x0d\x0ai\
|
||||||
@@ -7293,12 +7302,12 @@ qt_resource_struct = b"\
|
|||||||
\x00\x00\x01\x8f\xff^8P\
|
\x00\x00\x01\x8f\xff^8P\
|
||||||
\x00\x00\x03<\x00\x01\x00\x00\x00\x01\x00\x01>\xe2\
|
\x00\x00\x03<\x00\x01\x00\x00\x00\x01\x00\x01>\xe2\
|
||||||
\x00\x00\x01\x8f\xff^8P\
|
\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\x01\x8f\xff^8P\
|
||||||
\x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I\x0c\
|
\x00\x00\x03r\x00\x01\x00\x00\x00\x01\x00\x01I\x0c\
|
||||||
\x00\x00\x01\x8f\xff^8_\
|
\x00\x00\x01\x8f\xff^8_\
|
||||||
\x00\x00\x05\x86\x00\x00\x00\x00\x00\x01\x00\x01\x99F\
|
\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\x03X\x00\x02\x00\x00\x00\x04\x00\x00\x00+\
|
||||||
\x00\x00\x00\x00\x00\x00\x00\x00\
|
\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||||
\x00\x00\x04\xc4\x00\x01\x00\x00\x00\x01\x00\x01v\x14\
|
\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\x01\x8f\xff^8P\
|
||||||
\x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xad\
|
\x00\x00\x05\x06\x00\x00\x00\x00\x00\x01\x00\x01\x85\xad\
|
||||||
\x00\x00\x01\x8f\xff^8P\
|
\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\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\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\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_\
|
\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.finished.connect(self.update_manager.post_download_db)
|
||||||
self.downloader.on_start(
|
self.downloader.on_start(
|
||||||
self.update_manager.remote_db_url,
|
self.update_manager.remote_db_url,
|
||||||
self.update_manager.remote_db_size,
|
|
||||||
DATA_DIR
|
DATA_DIR
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
from PySide6.QtQml import QQmlApplicationEngine
|
from PySide6.QtQml import QQmlApplicationEngine
|
||||||
from PySide6.QtCore import QObject, Slot, Signal, QUrl, QSaveFile, QDir, QIODevice
|
from PySide6.QtCore import QObject, Slot, Signal, QUrl, QSaveFile, QDir, QIODevice
|
||||||
from PySide6.QtNetwork import QNetworkReply, QNetworkRequest, QNetworkAccessManager
|
from PySide6.QtNetwork import QNetworkReply, QNetworkRequest, QNetworkAccessManager
|
||||||
@@ -7,11 +9,12 @@ from artemis.utils.constants import Messages
|
|||||||
|
|
||||||
class UIDownloader(QObject):
|
class UIDownloader(QObject):
|
||||||
# Python > QML Signals
|
# Python > QML Signals
|
||||||
finished = Signal()
|
|
||||||
show_ui = Signal()
|
show_ui = Signal()
|
||||||
close_ui = Signal()
|
close_ui = Signal()
|
||||||
update_progress_bar = Signal(int, int)
|
update_progress_bar = Signal(int, int)
|
||||||
|
set_indeterminate_bar = Signal()
|
||||||
update_status = Signal(str)
|
update_status = Signal(str)
|
||||||
|
finished = Signal()
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
@@ -25,6 +28,10 @@ class UIDownloader(QObject):
|
|||||||
|
|
||||||
self.file_url = None
|
self.file_url = None
|
||||||
self.file_size = None
|
self.file_size = None
|
||||||
|
self.dest_file = None
|
||||||
|
self.file = None
|
||||||
|
self.manager = None
|
||||||
|
self.reply = None
|
||||||
|
|
||||||
self._connect()
|
self._connect()
|
||||||
|
|
||||||
@@ -37,17 +44,22 @@ class UIDownloader(QObject):
|
|||||||
self.show_ui.connect(self._window.show)
|
self.show_ui.connect(self._window.show)
|
||||||
self.close_ui.connect(self._window.close)
|
self.close_ui.connect(self._window.close)
|
||||||
self.update_progress_bar.connect(self._window.updateProgressBar)
|
self.update_progress_bar.connect(self._window.updateProgressBar)
|
||||||
|
self.set_indeterminate_bar.connect(self._window.setIndeterminateBar)
|
||||||
self.update_status.connect(self._window.updateStatus)
|
self.update_status.connect(self._window.updateStatus)
|
||||||
|
|
||||||
|
|
||||||
def on_start(self, url, filesize, save_path):
|
def on_start(self, url, save_path):
|
||||||
""" Start the download of the DB taking the needed url and size from
|
""" Start the download process using the specified URL
|
||||||
the attributes of the UpdatesController class
|
|
||||||
|
Args:
|
||||||
|
url (str): url from where download the file
|
||||||
|
save_path (str): path where to save the downloaded file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.show_ui.emit()
|
self.show_ui.emit()
|
||||||
|
|
||||||
self.file_url = QUrl(url)
|
self.file_url = QUrl(url)
|
||||||
self.file_size = filesize
|
self.file_size = self._get_filesize(url)
|
||||||
dest_path = QDir(save_path)
|
dest_path = QDir(save_path)
|
||||||
self.dest_file = dest_path.filePath(self.file_url.fileName())
|
self.dest_file = dest_path.filePath(self.file_url.fileName())
|
||||||
self.file = QSaveFile(self.dest_file)
|
self.file = QSaveFile(self.dest_file)
|
||||||
@@ -69,7 +81,8 @@ class UIDownloader(QObject):
|
|||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def on_abort(self):
|
def on_abort(self):
|
||||||
""" Stop the download when user press abort button """
|
""" Stop the download when user presses the abort button
|
||||||
|
"""
|
||||||
if self.reply:
|
if self.reply:
|
||||||
self.reply.abort()
|
self.reply.abort()
|
||||||
self.update_progress_bar.emit(0, 0)
|
self.update_progress_bar.emit(0, 0)
|
||||||
@@ -80,7 +93,8 @@ class UIDownloader(QObject):
|
|||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def on_ready_read(self):
|
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:
|
||||||
if self.reply.error() == QNetworkReply.NoError:
|
if self.reply.error() == QNetworkReply.NoError:
|
||||||
self.file.write(self.reply.readAll())
|
self.file.write(self.reply.readAll())
|
||||||
@@ -88,8 +102,9 @@ class UIDownloader(QObject):
|
|||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def on_finished(self):
|
def on_finished(self):
|
||||||
""" Delete reply, close the file, check the hash for integrity,
|
""" Finalize the download process and if no errors
|
||||||
extract the database and delete the downloaded zip
|
occurrs emits the finished signal usefulle for
|
||||||
|
a callback
|
||||||
"""
|
"""
|
||||||
if self.reply:
|
if self.reply:
|
||||||
self.reply.deleteLater()
|
self.reply.deleteLater()
|
||||||
@@ -105,10 +120,13 @@ class UIDownloader(QObject):
|
|||||||
|
|
||||||
@Slot(int, int)
|
@Slot(int, int)
|
||||||
def on_progress(self, bytesReceived: 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_status.emit("{:.1f} Mb / {:.1f} Mb".format(bytesReceived/10**6, self.file_size/10**6))
|
||||||
self.update_progress_bar.emit(bytesReceived, self.file_size)
|
self.update_progress_bar.emit(bytesReceived, self.file_size)
|
||||||
|
else:
|
||||||
|
self.update_status.emit("{:.1f} Mb".format(bytesReceived/10**6))
|
||||||
|
|
||||||
|
|
||||||
@Slot(QNetworkReply.NetworkError)
|
@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):
|
def show_popup_error(self, error_msg):
|
||||||
self._parent.dialog_popup(
|
self._parent.dialog_popup(
|
||||||
Messages.DIALOG_TYPE_ERROR,
|
Messages.DIALOG_TYPE_ERROR,
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ Window {
|
|||||||
progressBar.to = bytesTotal
|
progressBar.to = bytesTotal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setIndeterminateBar() {
|
||||||
|
progressBar.indeterminate = true
|
||||||
|
}
|
||||||
|
|
||||||
function updateStatus(arg) {
|
function updateStatus(arg) {
|
||||||
progressLabel.text = arg
|
progressLabel.text = arg
|
||||||
}
|
}
|
||||||
@@ -51,6 +55,7 @@ Window {
|
|||||||
Layout.rightMargin: 20
|
Layout.rightMargin: 20
|
||||||
Layout.leftMargin: 20
|
Layout.leftMargin: 20
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
indeterminate: false
|
||||||
value: 0
|
value: 0
|
||||||
to: 0
|
to: 0
|
||||||
}
|
}
|
||||||
@@ -61,10 +66,11 @@ Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||||
text: qsTr("Abort")
|
text: qsTr("Abort")
|
||||||
icon.source: "qrc:/images/icons/abort.svg"
|
icon.source: "qrc:/images/icons/abort.svg"
|
||||||
display: AbstractButton.TextBesideIcon
|
display: AbstractButton.TextBesideIcon
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
flat: true
|
||||||
onClicked: { onAbort() }
|
onClicked: { onAbort() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user