From 54eeb183e6f47811715643575c64a724bf8c49dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Mon, 27 Feb 2017 21:08:40 +0100 Subject: [PATCH] [httpupload] Refactor upload methods --- httpupload/httpupload.py | 132 +++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/httpupload/httpupload.py b/httpupload/httpupload.py index f4ae65e..e792e91 100644 --- a/httpupload/httpupload.py +++ b/httpupload/httpupload.py @@ -19,12 +19,14 @@ from gi.repository import GObject, Gtk, GLib import os import sys import time +import threading from urllib.request import Request, urlopen import mimetypes # better use the magic packet, but that's not a standard lib import gtkgui_helpers import logging from queue import Queue import binascii +import certifi from common import gajim from common import ged @@ -210,7 +212,7 @@ class Base(object): mime = mimetypes.MimeTypes().guess_type(path)[0] if not mime: mime = 'application/octet-stream' # fallback mime type - log.info("Detected MIME type of file: ", mime) + log.info("Detected MIME type of file: %s", mime) progress_messages = Queue(8) progress_window = ProgressWindow(_('HTTP Upload'), _('Requesting HTTP Upload Slot...'), @@ -221,65 +223,6 @@ class Base(object): progress=progress_window) self.request_slot(file) - def upload_file(stanza): - - def upload_complete(response_code): - if response_code == 0: - return # Upload was aborted - if 200 <= response_code < 300: - log.info("Upload completed successfully") - xhtml = None - is_image = mime_type.split('/', 1)[0] == 'image' - progress_window.close_dialog() - id_ = gajim.get_an_id() - def add_oob_tag(): - pass - if self.encrypted_upload: - keyAndIv = '#' + binascii.hexlify(iv) + binascii.hexlify(key) - self.chat_control.send_message(message=get.getData() + keyAndIv, xhtml=None) - else: - self.chat_control.send_message(message=get.getData(), xhtml=xhtml) - self.chat_control.msg_textview.grab_focus() - else: - progress_window.close_dialog() - log.error("got unexpected http upload response code: " + str(response_code)) - ErrorDialog(_('Could not upload file'), - _('Got unexpected http response code from server: ') + str(response_code), - transient_for=self.chat_control.parent_win.window) - - def on_upload_error(): - progress_window.close_dialog() - ErrorDialog(_('Could not upload file'), - _('Got unexpected exception while uploading file' - ' (see error log for more information)'), - transient_for=self.chat_control.parent_win.window) - return 0 - - def uploader(): - progress_messages.put(_('Uploading file via HTTP...')) - try: - headers = {'User-Agent': 'Gajim %s' % gajim.version, - 'Content-Type': mime_type} - request = Request(put.getData(), data=data, headers=headers, method='PUT') - log.debug("opening urllib upload request...") - transfer = urlopen(request, timeout=30) - data.close() - log.debug("urllib upload request done, response code: " + str(transfer.getcode())) - return transfer.getcode() - except UploadAbortedException: - log.info("Upload aborted") - except: - log.error("Exception during upload", exc_info=sys.exc_info()) - GLib.idle_add(on_upload_error) - return 0 - - log.info("Uploading file to '%s'..." % str(put.getData())) - log.info("Please download from '%s' later..." % str(get.getData())) - - gajim.thread_interface(uploader, [], upload_complete) - - self.chat_control.msg_textview.grab_focus() - def on_file_button_clicked(self, widget, jid, chat_control): FileChooserDialog( on_response_ok=lambda widget: self.on_file_dialog_ok(widget, jid, @@ -314,8 +257,8 @@ class Base(object): return try: - file.put = stanza.getTag("slot").getTag("put") - file.get = stanza.getTag("slot").getTag("get") + file.put = stanza.getTag("slot").getTag("put").getData() + file.get = stanza.getTag("slot").getTag("get").getData() except Exception as exc: file.progress.close_dialog() log.error("Got unexpected stanza: ", stanza) @@ -335,6 +278,60 @@ class Base(object): transient_for=file.control.parent_win.window) return + log.info('Uploading file to %s', file.put) + log.info('Please download from %s', file.get) + + thread = threading.Thread(target=self.upload_file, args=(file,)) + thread.daemon = True + thread.start() + + def upload_file(self, file): + + # progress_messages.put(_('Uploading file via HTTP...')) + try: + headers = {'User-Agent': 'Gajim %s' % gajim.version, + 'Content-Type': file.mime} + request = Request(file.put, data=file.stream, headers=headers, method='PUT') + log.debug("opening urllib upload request...") + if os.name == 'nt': + transfer = urlopen(request, cafile=certifi.where(), timeout=30) + else: + transfer = urlopen(request, timeout=30) + file.stream.close() + log.debug('urllib upload request done, response code: ', transfer.getcode()) + GLib.idle_add(self.upload_complete, transfer.getcode(), file) + except: + log.error("Exception during upload", exc_info=sys.exc_info()) + GLib.idle_add(file.progress.close_dialog) + GLib.idle_add(self.on_upload_error, file) + + def upload_complete(self, response_code, file): + if response_code == 0: + return # Upload was aborted + if 200 <= response_code < 300: + log.info("Upload completed successfully") + file.progress.close_dialog() + message = file.get + if file.encrypted: + message += '#' + binascii.hexlify(file.iv + file.key) + file.control.send_message(message=message) + file.control.msg_textview.grab_focus() + else: + file.progress.close_dialog() + log.error('Got unexpected http upload response code: ', + response_code) + ErrorDialog( + _('Could not upload file'), + _('HTTP response code from server: %s') % response_code, + transient_for=file.control.parent_win.window) + + def on_upload_error(self, file): + file.progress.close_dialog() + ErrorDialog(_('Could not upload file'), + _('Got unexpected exception while uploading file' + ' (see log)'), + transient_for=file.control.parent_win.window) + class File: def __init__(self, **kwargs): @@ -381,13 +378,15 @@ class StreamFileWithProgress: data += self.encryptor.tag self._seen += TAGSIZE if self._callback: - self._callback(self._seen, self._total, *self._args) + GLib.idle_add( + self._callback, self._seen, self._total, *self._args) return data else: data = self.backing.read(size) self._seen += len(data) if self._callback: - self._callback(self._seen, self._total, *self._args) + GLib.idle_add( + self._callback, self._seen, self._total, *self._args) return data def close(self): @@ -445,7 +444,7 @@ class ProgressWindow: def update_progress(self, seen, total): if self.stopped == True: - raise UploadAbortedException + raise if self.pulse_progressbar_timeout_id: GLib.source_remove(self.pulse_progressbar_timeout_id) self.pulse_progressbar_timeout_id = None @@ -457,6 +456,7 @@ class ProgressWindow: def close_dialog(self): self.on_cancel(None) + class UploadAbortedException(Exception): def __str__(self): - return "Upload Aborted" + return "Upload Aborted" \ No newline at end of file