From 319dd1cc0ad1f814a7164cd24d6e4d60db0bff09 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Sun, 26 Mar 2017 23:14:47 +0200 Subject: [PATCH] Improve download code --- projectgenerator/libili2pg/downloader.py | 31 ----------- projectgenerator/libili2pg/iliimporter.py | 35 +++++++----- projectgenerator/utils/qt_utils.py | 67 +++++++++++++++++++++-- 3 files changed, 82 insertions(+), 51 deletions(-) delete mode 100644 projectgenerator/libili2pg/downloader.py diff --git a/projectgenerator/libili2pg/downloader.py b/projectgenerator/libili2pg/downloader.py deleted file mode 100644 index cc0af3705..000000000 --- a/projectgenerator/libili2pg/downloader.py +++ /dev/null @@ -1,31 +0,0 @@ -from qgis.PyQt.QtCore import QObject, QFile, QIODevice, QEventLoop -from qgis.PyQt.QtCore import QUrl -from qgis.PyQt.QtNetwork import QNetworkRequest -from qgis.core import QgsNetworkAccessManager - -class Downloader(QObject): - def __init__(self): - QObject.__init__(self) - self.filename = '' - self.url = '' - - def download(self, url, filename): - networkAccessManager = QgsNetworkAccessManager.instance() - - print('Starting download {}'.format(url)) - req = QNetworkRequest(QUrl(url)) - reply = networkAccessManager.get(req) - - def finished(): - print('Download finished {} ({})'.format(filename, reply.error())) - file = QFile(filename) - file.open(QIODevice.WriteOnly) - file.write(reply.readAll()) - file.close() - reply.deleteLater() - - reply.finished.connect(finished) - - loop = QEventLoop() - reply.finished.connect(loop.quit) - loop.exec() diff --git a/projectgenerator/libili2pg/iliimporter.py b/projectgenerator/libili2pg/iliimporter.py index 34dc78489..9b850acb2 100644 --- a/projectgenerator/libili2pg/iliimporter.py +++ b/projectgenerator/libili2pg/iliimporter.py @@ -5,12 +5,14 @@ import tempfile import zipfile -from projectgenerator.libili2pg.downloader import Downloader from qgis.PyQt.QtCore import QObject, pyqtSignal -ILI2PG_VERSION='3.6.2' +from projectgenerator.utils.qt_utils import download_file + +ILI2PG_VERSION = '3.6.2' ILI2PG_URL = 'http://www.eisenhutinformatik.ch/interlis/ili2pg/ili2pg-{}.zip'.format(ILI2PG_VERSION) + class Configuration(object): def __init__(self): self.host = '' @@ -23,7 +25,7 @@ def __init__(self): @property def uri(self): - uri =[] + uri = [] uri += ['dbname={}'.format(self.database)] uri += ['user={}'.format(self.user)] if self.password: @@ -34,6 +36,7 @@ def uri(self): return ' '.join(uri) + class Importer(QObject): SUCCESS = 0 # TODO: Insert more codes? @@ -60,20 +63,24 @@ def run(self): except FileExistsError: pass - self.stdout.emit('Downloading ili2pg ...') - - downloader = Downloader() tmpfile = tempfile.NamedTemporaryFile(suffix='.zip', delete=False) - downloader.download(ILI2PG_URL, tmpfile.name) - with zipfile.ZipFile(tmpfile.name, "r") as z: - z.extractall(os.path.join(dir_path, 'bin')) + + self.stdout.emit(self.tr('Downloading ili2pg version {version}...'.format(ILI2PG_VERSION))) + download_file(ILI2PG_URL, tmpfile.name, on_progress=lambda received, total: self.stdout.emit('.')) + + try: + with zipfile.ZipFile(tmpfile.name, "r") as z: + z.extractall(os.path.join(dir_path, 'bin')) + except zipfile.BadZipFile: + # We will realize soon enough that the files were not extracted + pass if not os.path.isfile(ili2pg_file): self.stderr.emit( - 'File "{file}" not found. Please download and extract http://www.eisenhutinformatik.ch/interlis/ili2pg/ili2pg-{version}.zip.'.format( - file=ili2pg_file, - version=ILI2PG_VERSION)) - + self.tr( + 'File "{file}" not found. Please download and extract {ili2pg_url}.'.format( + file=ili2pg_file, + ili2pg_url=ILI2PG_URL))) args = ["java"] args += ["-jar", ili2pg_file] @@ -118,4 +125,4 @@ def run(self): pass self.process_finished.emit(proc.returncode, result) - return result \ No newline at end of file + return result diff --git a/projectgenerator/utils/qt_utils.py b/projectgenerator/utils/qt_utils.py index 208a9992c..77be472e7 100644 --- a/projectgenerator/utils/qt_utils.py +++ b/projectgenerator/utils/qt_utils.py @@ -20,17 +20,72 @@ """ import inspect -from qgis.PyQt import QtWidgets -from qgis.PyQt.QtCore import QCoreApplication +from qgis.PyQt.QtWidgets import QFileDialog +from qgis.PyQt.QtCore import ( + QCoreApplication, + QObject, + QFile, + QIODevice, + QEventLoop, + QUrl +) +from qgis.PyQt.QtNetwork import QNetworkRequest +from qgis.core import QgsNetworkAccessManager from functools import partial -import importlib -from qgis.PyQt.QtCore import qVersion - def selectFolder(line_edit_widget, title, file_filter, parent): - filename, matched_filter = QtWidgets.QFileDialog.getOpenFileName(parent, title, line_edit_widget.text(), file_filter) + filename, matched_filter = QFileDialog.getOpenFileName(parent, title, line_edit_widget.text(), file_filter) line_edit_widget.setText(filename) def make_file_selector(widget, title=QCoreApplication.translate('projectgenerator', 'Open File'), file_filter=QCoreApplication.translate('projectgenerator', 'Any file(*)'), parent=None): return partial(selectFolder, line_edit_widget=widget, title=title, file_filter=file_filter, parent=parent) + + +class NetworkError(RuntimeError): + def __init__(self, error_code, msg): + self.msg = msg + self.error_code = error_code + + +def download_file(url, filename, on_progress=None): + """ + Will download the file from url to a local filename. + The method will only return once it's finished. + + While downloading it will repeatedly report progress by calling on_progress + with two parameters bytes_received and bytes_total. + + If an error occurs, it raises a NetworkError exception. + + It will return the filename if everything was ok. + """ + network_access_manager = QgsNetworkAccessManager.instance() + + req = QNetworkRequest(QUrl(url)) + reply = network_access_manager.get(req) + + def on_download_progress(bytes_received, bytes_total): + on_progress(bytes_received, bytes_total) + + def finished(): + print('Download finished {} ({})'.format(filename, reply.error())) + file = QFile(filename) + file.open(QIODevice.WriteOnly) + file.write(reply.readAll()) + file.close() + + if on_progress: + reply.downloadProgress.connect(on_download_progress) + + reply.finished.connect(finished) + + loop = QEventLoop() + reply.finished.connect(loop.quit) + loop.exec_() + reply.deleteLater() + + if reply.error(): + raise NetworkError(reply.error(), reply.errorMessage) + else: + return filename \ No newline at end of file