Skip to content
Snippets Groups Projects
Commit 1a5b58b7 authored by Philipp Hörist's avatar Philipp Hörist
Browse files

Merge branch 'master' into 'master'

0.4.3

See merge request !11
parents b6dee2ad ef53098b
No related branches found
No related tags found
No related merge requests found
...@@ -28,6 +28,7 @@ import tempfile ...@@ -28,6 +28,7 @@ import tempfile
import urllib2 import urllib2
import mimetypes # better use the magic packet, but that's not a standard lib import mimetypes # better use the magic packet, but that's not a standard lib
import gtkgui_helpers import gtkgui_helpers
import threading
from Queue import Queue from Queue import Queue
try: try:
from PIL import Image from PIL import Image
...@@ -331,21 +332,28 @@ class Base(object): ...@@ -331,21 +332,28 @@ class Base(object):
mime_type = 'application/octet-stream' # fallback mime type mime_type = 'application/octet-stream' # fallback mime type
log.info("Detected MIME Type of file: " + str(mime_type)) log.info("Detected MIME Type of file: " + str(mime_type))
progress_messages = Queue(8) progress_messages = Queue(8)
progress_window = ProgressWindow(_('HTTP Upload'), _('Requesting HTTP Upload Slot...'), progress_messages, self.plugin) event = threading.Event()
progress_window = ProgressWindow(_('Requesting HTTP Upload Slot...'), progress_messages, self.plugin, event)
def upload_file(stanza): def upload_file(stanza):
if stanza.getType() == 'error':
ErrorDialog(_('Could not request upload slot'),
stanza.getErrorMsg(),
transient_for=self.chat_control.parent_win.window)
log.error(stanza)
progress_window.close_dialog()
return
slot = stanza.getTag("slot") slot = stanza.getTag("slot")
if not slot: if slot:
put = slot.getTag("put")
get = slot.getTag("get")
else:
progress_window.close_dialog() progress_window.close_dialog()
log.error("got unexpected stanza: "+str(stanza)) log.error("got unexpected stanza: " + str(stanza))
error = stanza.getTag("error") ErrorDialog(_('Could not request upload slot'),
if error and error.getTag("text"): _('Got unexpected response from server (see log)'),
ErrorDialog(_('Could not request upload slot'), transient_for=self.chat_control.parent_win.window)
_('Got unexpected response from server: %s') % str(error.getTagData("text")),
transient_for=self.chat_control.parent_win.window)
else:
ErrorDialog(_('Could not request upload slot'),
_('Got unexpected response from server (protocol mismatch??)'),
transient_for=self.chat_control.parent_win.window)
return return
try: try:
...@@ -354,12 +362,12 @@ class Base(object): ...@@ -354,12 +362,12 @@ class Base(object):
iv = os.urandom(16) iv = os.urandom(16)
data = StreamFileWithProgress(path_to_file, data = StreamFileWithProgress(path_to_file,
"rb", "rb",
progress_window.update_progress, progress_window.update_progress, event,
self.encrypted_upload, key, iv) self.encrypted_upload, key, iv)
else: else:
data = StreamFileWithProgress(path_to_file, data = StreamFileWithProgress(path_to_file,
"rb", "rb",
progress_window.update_progress) progress_window.update_progress, event)
except: except:
progress_window.close_dialog() progress_window.close_dialog()
ErrorDialog(_('Could not open file'), ErrorDialog(_('Could not open file'),
...@@ -367,16 +375,6 @@ class Base(object): ...@@ -367,16 +375,6 @@ class Base(object):
transient_for=self.chat_control.parent_win.window) transient_for=self.chat_control.parent_win.window)
raise # fill error log with useful information raise # fill error log with useful information
put = slot.getTag("put")
get = slot.getTag("get")
if not put or not get:
progress_window.close_dialog()
log.error("got unexpected stanza: " + str(stanza))
ErrorDialog(_('Could not request upload slot'),
_('Got unexpected response from server (protocol mismatch??)'),
transient_for=self.chat_control.parent_win.window)
return
def upload_complete(response_code): def upload_complete(response_code):
if isinstance(response_code, str): if isinstance(response_code, str):
# We got a error Message # We got a error Message
...@@ -479,6 +477,8 @@ class Base(object): ...@@ -479,6 +477,8 @@ class Base(object):
transfer = urllib2.urlopen(request, timeout=30) transfer = urllib2.urlopen(request, timeout=30)
log.debug("urllib2 upload request done, response code: " + str(transfer.getcode())) log.debug("urllib2 upload request done, response code: " + str(transfer.getcode()))
return transfer.getcode() return transfer.getcode()
except UploadAbortedException as error:
log.info('Upload Aborted')
except Exception as error: except Exception as error:
gobject.idle_add(progress_window.close_dialog) gobject.idle_add(progress_window.close_dialog)
log.exception('Error') log.exception('Error')
...@@ -564,9 +564,10 @@ class Base(object): ...@@ -564,9 +564,10 @@ class Base(object):
class StreamFileWithProgress(file): class StreamFileWithProgress(file):
def __init__(self, path, mode, callback=None, def __init__(self, path, mode, callback, event,
encrypted_upload=False, key=None, iv=None, *args): encrypted_upload=False, key=None, iv=None, *args):
file.__init__(self, path, mode) file.__init__(self, path, mode)
self.event = event
self.encrypted_upload = encrypted_upload self.encrypted_upload = encrypted_upload
self.seek(0, os.SEEK_END) self.seek(0, os.SEEK_END)
if self.encrypted_upload: if self.encrypted_upload:
...@@ -590,6 +591,8 @@ class StreamFileWithProgress(file): ...@@ -590,6 +591,8 @@ class StreamFileWithProgress(file):
return self._total return self._total
def read(self, size): def read(self, size):
if self.event.isSet():
raise UploadAbortedException
if self.encrypted_upload: if self.encrypted_upload:
data = file.read(self, size) data = file.read(self, size)
if len(data) > 0: if len(data) > 0:
...@@ -600,38 +603,33 @@ class StreamFileWithProgress(file): ...@@ -600,38 +603,33 @@ class StreamFileWithProgress(file):
data += self.encryptor.tag data += self.encryptor.tag
self._seen += TAGSIZE self._seen += TAGSIZE
if self._callback: if self._callback:
self._callback(self._seen, self._total, *self._args) gobject.idle_add(self._callback, self._seen, self._total, *self._args)
return data
else: else:
data = file.read(self, size) data = file.read(self, size)
self._seen += len(data) self._seen += len(data)
if self._callback: if self._callback:
self._callback(self._seen, self._total, *self._args) gobject.idle_add(self._callback, self._seen, self._total, *self._args)
return data return data
class ProgressWindow: class ProgressWindow:
def __init__(self, title_text, during_text, messages_queue, plugin): def __init__(self, during_text, messages_queue, plugin, event):
self.plugin = plugin self.plugin = plugin
self.event = event
self.xml = gtkgui_helpers.get_gtk_builder(self.plugin.local_file_path('upload_progress_dialog.ui')) self.xml = gtkgui_helpers.get_gtk_builder(self.plugin.local_file_path('upload_progress_dialog.ui'))
self.messages_queue = messages_queue self.messages_queue = messages_queue
self.dialog = self.xml.get_object('progress_dialog') self.dialog = self.xml.get_object('progress_dialog')
self.dialog.set_transient_for(plugin.chat_control.parent_win.window)
self.label = self.xml.get_object('label') self.label = self.xml.get_object('label')
self.cancel_button = self.xml.get_object('close_button')
self.label.set_markup('<big>' + during_text + '</big>') self.label.set_markup('<big>' + during_text + '</big>')
self.progressbar = self.xml.get_object('progressbar') self.progressbar = self.xml.get_object('progressbar')
self.progressbar.set_text("") self.progressbar.set_text("")
self.dialog.set_title(title_text)
self.dialog.set_geometry_hints(min_width=400, min_height=96)
self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.dialog.show_all() self.dialog.show_all()
self.xml.connect_signals(self) self.xml.connect_signals(self)
self.stopped = False
self.pulse_progressbar_timeout_id = gobject.timeout_add(100, self.pulse_progressbar) self.pulse_progressbar_timeout_id = gobject.timeout_add(100, self.pulse_progressbar)
self.process_messages_queue_timeout_id = gobject.timeout_add(100, self.process_messages_queue) self.process_messages_queue_timeout_id = gobject.timeout_add(100, self.process_messages_queue)
def pulse_progressbar(self): def pulse_progressbar(self):
if self.dialog: if self.dialog:
self.progressbar.pulse() self.progressbar.pulse()
...@@ -645,22 +643,9 @@ class ProgressWindow: ...@@ -645,22 +643,9 @@ class ProgressWindow:
return True # loop forever return True # loop forever
return False return False
def on_progress_dialog_delete_event(self, widget, event):
self.stopped = True
if self.pulse_progressbar_timeout_id:
gobject.source_remove(self.pulse_progressbar_timeout_id)
gobject.source_remove(self.process_messages_queue_timeout_id)
def on_cancel(self, widget):
self.stopped = True
if self.pulse_progressbar_timeout_id:
gobject.source_remove(self.pulse_progressbar_timeout_id)
gobject.source_remove(self.process_messages_queue_timeout_id)
self.dialog.destroy()
def update_progress(self, seen, total): def update_progress(self, seen, total):
if self.stopped == True: if self.event.isSet():
raise UploadAbortedException return
if self.pulse_progressbar_timeout_id: if self.pulse_progressbar_timeout_id:
gobject.source_remove(self.pulse_progressbar_timeout_id) gobject.source_remove(self.pulse_progressbar_timeout_id)
self.pulse_progressbar_timeout_id = None self.pulse_progressbar_timeout_id = None
...@@ -669,8 +654,15 @@ class ProgressWindow: ...@@ -669,8 +654,15 @@ class ProgressWindow:
self.progressbar.set_text(str(int(pct)) + "%") self.progressbar.set_text(str(int(pct)) + "%")
log.debug('upload progress: %.2f%% (%d of %d bytes)' % (pct, seen, total)) log.debug('upload progress: %.2f%% (%d of %d bytes)' % (pct, seen, total))
def close_dialog(self): def close_dialog(self, *args):
self.on_cancel(None) self.dialog.destroy()
def on_destroy(self, event, *args):
self.event.set()
if self.pulse_progressbar_timeout_id:
gobject.source_remove(self.pulse_progressbar_timeout_id)
gobject.source_remove(self.process_messages_queue_timeout_id)
class UploadAbortedException(Exception): class UploadAbortedException(Exception):
def __str__(self): def __str__(self):
......
[info] [info]
name: HttpUpload name: HttpUpload
short_name: httpupload short_name: httpupload
version: 0.4.2 version: 0.4.3
description: This plugin is designed to send a file to a contact or muc by using httpupload.<br/> description: This plugin is designed to send a file to a contact or muc by using httpupload.<br/>
Your server must support <a href="http://xmpp.org/extensions/xep-0363.html">XEP-0363: HTTP Upload</a>.<br/> Your server must support <a href="http://xmpp.org/extensions/xep-0363.html">XEP-0363: HTTP Upload</a>.<br/>
Conversations supported this.<br/> Conversations supported this.<br/>
......
...@@ -4,12 +4,15 @@ ...@@ -4,12 +4,15 @@
<requires lib="gtk+" version="2.16"/> <requires lib="gtk+" version="2.16"/>
<object class="GtkDialog" id="progress_dialog"> <object class="GtkDialog" id="progress_dialog">
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="title" translatable="yes">HTTP Upload</property>
<property name="resizable">False</property> <property name="resizable">False</property>
<property name="window_position">center-on-parent</property>
<property name="destroy_with_parent">True</property>
<property name="icon_name">upload-media</property> <property name="icon_name">upload-media</property>
<property name="type_hint">dialog</property> <property name="type_hint">dialog</property>
<signal name="delete-event" handler="on_progress_dialog_delete_event" swapped="no"/>
<child internal-child="vbox"> <child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox"> <object class="GtkBox" id="dialog-vbox">
<property name="width_request">250</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
...@@ -25,7 +28,6 @@ ...@@ -25,7 +28,6 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="top_padding">2</property> <property name="top_padding">2</property>
<property name="bottom_padding">4</property> <property name="bottom_padding">4</property>
<property name="left_padding">0</property>
<property name="right_padding">3</property> <property name="right_padding">3</property>
<child> <child>
<object class="GtkButton" id="close_button"> <object class="GtkButton" id="close_button">
...@@ -35,7 +37,8 @@ ...@@ -35,7 +37,8 @@
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="clicked" handler="on_cancel" swapped="no"/> <signal name="clicked" handler="close_dialog" swapped="no"/>
<signal name="destroy" handler="on_destroy" swapped="no"/>
</object> </object>
</child> </child>
</object> </object>
...@@ -65,8 +68,8 @@ ...@@ -65,8 +68,8 @@
<object class="GtkLabel" id="label"> <object class="GtkLabel" id="label">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="use_markup">True</property> <property name="use_markup">True</property>
<property name="xalign">0</property>
</object> </object>
</child> </child>
</object> </object>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment