diff --git a/src/common/connection.py b/src/common/connection.py index fa693eb32..3f4840798 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -871,6 +871,15 @@ class Connection: return file_props['receiver'] = self.get_full_jid(iq_obj) si = iq_obj.getTag('si') + file_tag = si.getTag('file') + range_tag = file_tag.getTag('range') + if range_tag: + offset = range_tag.getAttr('offset') + if offset: + file_props['offset'] = int(offset) + length = range_tag.getAttr('length') + if length: + file_props['length'] = int(length) feature = si.setTag('feature') if feature.getNamespace() != common.xmpp.NS_FEATURE: return @@ -1054,6 +1063,9 @@ class Connection: si.setNamespace(common.xmpp.NS_SI) file_tag = si.setTag('file') file_tag.setNamespace(common.xmpp.NS_FILE) + if file_props.has_key('offset') and file_props['offset']: + range_tag = file_tag.setTag('range') + range_tag.setAttr('offset', file_props['offset']) feature = si.setTag('feature') feature.setNamespace(common.xmpp.NS_FEATURE) _feature = common.xmpp.DataForm(typ='submit') diff --git a/src/common/socks5.py b/src/common/socks5.py index 38292c642..ff8e0a42c 100644 --- a/src/common/socks5.py +++ b/src/common/socks5.py @@ -366,6 +366,10 @@ class Socks5: if self.fd == None: try: self.fd = open(self.file_props['file-name'],'rb') + if self.file_props.has_key('offset') and self.file_props['offset']: + self.size = self.file_props['offset'] + self.fd.seek(self.size) + self.file_props['received-len'] = self.size except IOError, e: self.close_file() raise IOError, e @@ -383,11 +387,16 @@ class Socks5: if self.file_props.has_key('fd'): fd = self.file_props['fd'] else: - fd = open(self.file_props['file-name'],'wb') + offset = 0 + opt = 'wb' + if self.file_props.has_key('offset') and self.file_props['offset']: + offset = self.file_props['offset'] + opt = 'ab' + fd = open(self.file_props['file-name'], opt) self.file_props['fd'] = fd self.file_props['elapsed-time'] = 0 self.file_props['last-time'] = time.time() - self.file_props['received-len'] = 0 + self.file_props['received-len'] = offset return fd def rem_fd(self, fd): diff --git a/src/dialogs.py b/src/dialogs.py index 98012d9f7..508147585 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -562,7 +562,30 @@ class ConfirmationDialogCheck(ConfirmationDialog): def is_checked(self): ''' Get active state of the checkbutton ''' return self.checkbutton.get_active() - + +class FTOverwriteConfirmationDialog(ConfirmationDialog): + '''HIG compliant confirmation dialog to overwrite or resume a file transfert''' + def __init__(self, pritext, sectext='', propose_resume=True): + HigDialog.__init__(self, None, gtk.MESSAGE_QUESTION, gtk.BUTTONS_CANCEL, + pritext, sectext) + + if propose_resume: + b = gtk.Button('', gtk.STOCK_REFRESH) + align = b.get_children()[0] + hbox = align.get_children()[0] + label = hbox.get_children()[1] + label.set_text('_Resume') + label.set_use_underline(True) + self.add_action_widget(b, 100) + + b = gtk.Button('', gtk.STOCK_SAVE_AS) + align = b.get_children()[0] + hbox = align.get_children()[0] + label = hbox.get_children()[1] + label.set_text('Re_place') + label.set_use_underline(True) + self.add_action_widget(b, 200) + class InputDialog: '''Class for Input dialog''' def __init__(self, title, label_str, input_str = None, is_modal = True, diff --git a/src/filetransfers_window.py b/src/filetransfers_window.py index 540c0f335..9fac59681 100644 --- a/src/filetransfers_window.py +++ b/src/filetransfers_window.py @@ -300,6 +300,24 @@ _('Connection with peer cannot be established.')) gajim.connections[account].send_file_request(file_props) return True + def confirm_overwrite_cb(self, dialog, file_props): + file_path = dialog.get_filename() + file_path = file_path.decode('utf-8') + if os.path.exists(file_path): + stat = os.stat(file_path) + dl_size = stat.st_size + file_size = file_props['size'] + dl_finished = dl_size >= file_size + dialog = dialogs.FTOverwriteConfirmationDialog( + _('This file already exists'), _('Would you like to overwrite it?'), + not dl_finished) + response = dialog.get_response() + if response == gtk.RESPONSE_CANCEL: + return gtk.FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN + elif response == 100: + file_props['offset'] = dl_size + return gtk.FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME + def show_file_request(self, account, contact, file_props): ''' show dialog asking for comfirmation and store location of new file requested by a contact''' @@ -326,6 +344,8 @@ _('Connection with peer cannot be established.')) gtk28 = False if gtk.gtk_version >= (2, 8, 0) and gtk.pygtk_version >= (2, 8, 0): dialog.props.do_overwrite_confirmation = True + dialog.connect('confirm-overwrite', self.confirm_overwrite_cb, + file_props) gtk28 = True if last_save_dir and os.path.isdir(last_save_dir): dialog.set_current_folder(last_save_dir)