Last active
August 29, 2015 13:57
-
-
Save akbargumbira/9542300 to your computer and use it in GitHub Desktop.
Improved fix temp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Downloader(object): | |
"""The blueprint for downloading file from url.""" | |
def __init__(self, manager, url, output_path, progress_dialog=None): | |
self.manager = manager | |
self.url = url | |
self.output_path = output_path | |
self.progress_dialog = progress_dialog | |
self.reply = None | |
self.output_file = None | |
self.downloaded_file_buffer = QByteArray() | |
self.is_finish = False | |
def download(self): | |
"""Downloading the file. | |
:returns: True if success, otherwise returns a tuple with format like | |
this (QNetworkReply.NetworkError, error_message) | |
:raises: IOError - when cannot create output_path | |
""" | |
# Prepare output path | |
self.output_file = QFile(self.output_path) | |
if not self.output_file.open(QFile.WriteOnly): | |
raise IOError(self.output_file.errorString()) | |
# Request the url | |
request = QNetworkRequest(QUrl(self.url)) | |
self.reply = self.manager.get(request) | |
self.reply.readyRead.connect(self.get_buffer) | |
self.reply.finished.connect(self.write_data) | |
if self.progress_dialog: | |
# progress bar | |
def progress_event(received, total): | |
"""Update progress. | |
:param received: Data received so far. | |
:type received: int | |
:param total: Total expected data. | |
:type total: int | |
""" | |
# noinspection PyArgumentList | |
QCoreApplication.processEvents() | |
label_text = "%s / %s" % (received, total) | |
self.progress_dialog.setLabelText(label_text) | |
self.progress_dialog.setMaximum(total) | |
self.progress_dialog.setValue(received) | |
# cancel | |
def cancel_action(): | |
"""Cancel download.""" | |
self.reply.abort() | |
self.reply.downloadProgress.connect(progress_event) | |
self.progress_dialog.canceled.connect(cancel_action) | |
# Wait until finished | |
# On Windows 32bit AND QGIS 2.2, self.reply.isFinished() always | |
# return False even after finished slot is called. So, that's why we | |
# are adding self.is_finish (see #864) | |
while not self.reply.isFinished() and not self.is_finish: | |
# noinspection PyArgumentList | |
QCoreApplication.processEvents() | |
result = self.reply.error() | |
if result == QNetworkReply.NoError: | |
return True, None | |
else: | |
return result, str(self.reply.errorString()) | |
def get_buffer(self): | |
"""Get buffer from self.reply and store it to our buffer field.""" | |
buffer_size = self.reply.size() | |
data = self.reply.read(buffer_size) | |
self.downloaded_file_buffer.append(data) | |
def write_data(self): | |
"""Write data to a file.""" | |
self.output_file.write(self.downloaded_file_buffer) | |
self.output_file.close() | |
self.is_finish = True | |
def download_url(manager, url, output_path, progress_dialog=None): | |
"""Download file from url. | |
:param manager: A QNetworkAccessManager instance | |
:type manager: QNetworkAccessManager | |
:param url: URL of file | |
:type url: str | |
:param output_path: Output path | |
:type output_path: str | |
:param progress_dialog: Progress dialog widget | |
""" | |
downloader = Downloader(manager, url, output_path, progress_dialog) | |
try: | |
result = downloader.download() | |
except IOError as ex: | |
raise IOError(ex) | |
return result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment