handle GUI while checking file hash. Show show re-request dialog when hash is incorrect. TODO: re-request file to sender.

This commit is contained in:
Yann Leboulanger 2012-02-18 21:06:08 +01:00
parent ca1eadaa2d
commit df17f8751d
4 changed files with 104 additions and 19 deletions

View File

@ -1615,16 +1615,15 @@ class YesNoDialog(HigDialog):
"""
def __init__(self, pritext, sectext='', checktext='', on_response_yes=None,
on_response_no=None):
on_response_no=None, type_=gtk.MESSAGE_QUESTION):
self.user_response_yes = on_response_yes
self.user_response_no = on_response_no
if hasattr(gajim.interface, 'roster') and gajim.interface.roster:
parent = gajim.interface.roster.window
else:
parent = None
HigDialog.__init__(self, parent, gtk.MESSAGE_QUESTION,
gtk.BUTTONS_YES_NO, pritext, sectext,
on_response_yes=self.on_response_yes,
HigDialog.__init__(self, parent, type_, gtk.BUTTONS_YES_NO, pritext,
sectext, on_response_yes=self.on_response_yes,
on_response_no=self.on_response_no)
if checktext:

View File

@ -46,7 +46,8 @@ C_FILE = 2
C_TIME = 3
C_PROGRESS = 4
C_PERCENT = 5
C_SID = 6
C_PULSE = 6
C_SID = 7
class FileTransfersWindow:
@ -65,7 +66,8 @@ class FileTransfersWindow:
shall_notify = gajim.config.get('notify_on_file_complete')
self.notify_ft_checkbox.set_active(shall_notify
)
self.model = gtk.ListStore(gtk.gdk.Pixbuf, str, str, str, str, int, str)
self.model = gtk.ListStore(gtk.gdk.Pixbuf, str, str, str, str, int,
int, str)
self.tree.set_model(self.model)
col = gtk.TreeViewColumn()
@ -112,6 +114,7 @@ class FileTransfersWindow:
col.pack_start(renderer, expand=False)
col.add_attribute(renderer, 'text', C_PROGRESS)
col.add_attribute(renderer, 'value', C_PERCENT)
col.add_attribute(renderer, 'pulse', C_PULSE)
col.set_resizable(True)
col.set_expand(False)
self.tree.append_column(col)
@ -125,6 +128,8 @@ class FileTransfersWindow:
'pause': gtk.STOCK_MEDIA_PAUSE,
'continue': gtk.STOCK_MEDIA_PLAY,
'ok': gtk.STOCK_APPLY,
'computing': gtk.STOCK_EXECUTE,
'hash_error': gtk.STOCK_STOP,
}
self.tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
@ -244,6 +249,21 @@ class FileTransfersWindow:
dialogs.ErrorDialog(_('File transfer stopped'), sectext)
self.tree.get_selection().unselect_all()
def show_hash_error(self, jid, file_props):
def on_yes(dummy):
# TODO: Request the file to the sender
pass
if file_props['type'] == 'r':
file_name = os.path.basename(file_props['file-name'])
else:
file_name = file_props['name']
dialogs.YesNoDialog(('File transfer error'),
_('The file %(file)s has been fully received, but it seems to be '
'wrongly received.\nDo you want to reload it?') % \
{'file': file_name}, on_response_yes=on_yes,
type_=gtk.MESSAGE_ERROR)
def show_file_send_request(self, account, contact):
win = gtk.ScrolledWindow()
win.set_shadow_type(gtk.SHADOW_IN)
@ -449,6 +469,36 @@ class FileTransfersWindow:
file_props['stopped'] = True
elif status == 'ok':
file_props['completed'] = True
text = self._format_percent(100)
received_size = int(file_props['received-len'])
full_size = int(file_props['size'])
text += helpers.convert_bytes(received_size) + '/' + \
helpers.convert_bytes(full_size)
self.model.set(iter_, C_PROGRESS, text)
self.model.set(iter_, C_PULSE, gobject.constants.G_MAXINT)
elif status == 'computing':
self.model.set(iter_, C_PULSE, 1)
text = _('Checking file...') + '\n'
received_size = int(file_props['received-len'])
full_size = int(file_props['size'])
text += helpers.convert_bytes(received_size) + '/' + \
helpers.convert_bytes(full_size)
self.model.set(iter_, C_PROGRESS, text)
def pulse():
p = self.model.get(iter_, C_PULSE)[0]
if p == gobject.constants.G_MAXINT:
return False
self.model.set(iter_, C_PULSE, p + 1)
return True
gobject.timeout_add(100, pulse)
elif status == 'hash_error':
text = _('File error') + '\n'
received_size = int(file_props['received-len'])
full_size = int(file_props['size'])
text += helpers.convert_bytes(received_size) + '/' + \
helpers.convert_bytes(full_size)
self.model.set(iter_, C_PROGRESS, text)
self.model.set(iter_, C_PULSE, gobject.constants.G_MAXINT)
self.model.set(iter_, C_IMAGE, self.get_icon(status))
path = self.model.get_path(iter_)
self.select_func(path)
@ -589,7 +639,10 @@ class FileTransfersWindow:
status = 'stop'
self.model.set(iter_, 0, self.get_icon(status))
if transfered_size == full_size:
self.set_status(typ, sid, 'ok')
if file_props['type'] == 'r':
self.set_status(typ, sid, 'computing')
else:
self.set_status(typ, sid, 'ok')
elif just_began:
path = self.model.get_path(iter_)
self.select_func(path)
@ -655,7 +708,7 @@ class FileTransfersWindow:
file_name = file_props['name']
text_props = gobject.markup_escape_text(file_name) + '\n'
text_props += contact.get_shown_name()
self.model.set(iter_, 1, text_labels, 2, text_props, C_SID,
self.model.set(iter_, 1, text_labels, 2, text_props, C_PULSE, -1, C_SID,
file_props['type'] + file_props['sid'])
self.set_progress(file_props['type'], file_props['sid'], 0, iter_)
if 'started' in file_props and file_props['started'] is False:

View File

@ -913,6 +913,12 @@ class Interface:
def __compare_hashes(self, account, file_props):
session = gajim.connections[account].get_jingle_session(jid=None,
sid=file_props['session-sid'])
ft_win = self.instances['file_transfers']
if not session.file_hash:
# We disn't get the hash, sender probably don't support that
jid = unicode(file_props['sender'])
self.popup_ft_result(account, jid, file_props)
ft_win.set_status(file_props['type'], file_props['sid'], 'ok')
h = Hashes()
try:
file_ = open(file_props['file-name'], 'r')
@ -922,8 +928,16 @@ class Interface:
file_.close()
# If the hash we received and the hash of the file are the same,
# then the file is not corrupt
if session.file_hash == hash_:
print "they are te same"
jid = unicode(file_props['sender'])
if session.file_hash != hash_:
self.popup_ft_result(account, jid, file_props)
ft_win.set_status(file_props['type'], file_props['sid'], 'ok')
else:
# wrong hash, we need to get the file again!
file_props['error'] = -10
self.popup_ft_result(account, jid, file_props)
ft_win.set_status(file_props['type'], file_props['sid'],
'hash_error')
# End jingle session
if session:
session.end_session()
@ -949,7 +963,10 @@ class Interface:
else: # we send a file
jid = unicode(file_props['receiver'])
gajim.socks5queue.remove_sender(file_props['sid'], True, True)
self.popup_ft_result(account, jid, file_props)
def popup_ft_result(self, account, jid, file_props):
ft = self.instances['file_transfers']
if helpers.allow_popup_window(account):
if file_props['error'] == 0:
if gajim.config.get('notify_on_file_complete'):
@ -960,6 +977,8 @@ class Interface:
elif file_props['error'] == -6:
ft.show_stopped(jid, file_props,
error_msg=_('Error opening file'))
elif file_props['error'] == -10:
ft.show_hash_error(jid, file_props)
return
msg_type = ''
@ -971,6 +990,9 @@ class Interface:
elif file_props['error'] in (-1, -6):
msg_type = 'file-stopped'
event_type = _('File Transfer Stopped')
elif file_props['error'] == -10:
msg_type = 'file-hash-error'
event_type = _('File Transfer Failed')
if event_type == '':
# FIXME: ugly workaround (this can happen Gajim sent, Gaim recvs)
@ -988,16 +1010,20 @@ class Interface:
# get the name of the sender, as it is in the roster
sender = unicode(file_props['sender']).split('/')[0]
name = gajim.contacts.get_first_contact_from_jid(account,
sender).get_shown_name()
sender).get_shown_name()
filename = os.path.basename(file_props['file-name'])
if event_type == _('File Transfer Completed'):
txt = _('You successfully received %(filename)s from '
'%(name)s.') % {'filename': filename, 'name': name}
img_name = 'gajim-ft_done'
else: # ft stopped
elif event_type == _('File Transfer Stopped'):
txt = _('File transfer of %(filename)s from %(name)s '
'stopped.') % {'filename': filename, 'name': name}
img_name = 'gajim-ft_stopped'
else: # ft hash error
txt = _('File transfer of %(filename)s from %(name)s '
'failed.') % {'filename': filename, 'name': name}
img_name = 'gajim-ft_stopped'
else:
receiver = file_props['receiver']
if hasattr(receiver, 'jid'):
@ -1005,24 +1031,28 @@ class Interface:
receiver = receiver.split('/')[0]
# get the name of the contact, as it is in the roster
name = gajim.contacts.get_first_contact_from_jid(account,
receiver).get_shown_name()
receiver).get_shown_name()
filename = os.path.basename(file_props['file-name'])
if event_type == _('File Transfer Completed'):
txt = _('You successfully sent %(filename)s to %(name)s.')\
% {'filename': filename, 'name': name}
% {'filename': filename, 'name': name}
img_name = 'gajim-ft_done'
else: # ft stopped
elif event_type == _('File Transfer Stopped'):
txt = _('File transfer of %(filename)s to %(name)s '
'stopped.') % {'filename': filename, 'name': name}
img_name = 'gajim-ft_stopped'
else: # ft hash error
txt = _('File transfer of %(filename)s to %(name)s '
'failed.') % {'filename': filename, 'name': name}
img_name = 'gajim-ft_stopped'
path = gtkgui_helpers.get_icon_path(img_name, 48)
else:
txt = ''
path = ''
if gajim.config.get('notify_on_file_complete') and \
(gajim.config.get('autopopupaway') or \
gajim.connections[account].connected in (2, 3)):
(gajim.config.get('autopopupaway') or \
gajim.connections[account].connected in (2, 3)):
# we want to be notified and we are online/chat or we don't mind
# bugged when away/na/busy
notify.popup(event_type, jid, account, msg_type, path_to_image=path,
@ -1514,7 +1544,7 @@ class Interface:
no_queue = len(gajim.events.get_events(account, jid)) == 0
# type_ can be gc-invitation file-send-error file-error
# file-request-error file-request file-completed file-stopped
# jingle-incoming
# file-hash-error jingle-incoming
# event_type can be in advancedNotificationWindow.events_list
event_types = {'file-request': 'ft_request',
'file-completed': 'ft_finished'}
@ -1643,7 +1673,7 @@ class Interface:
w = ctrl.parent_win
elif type_ in ('normal', 'file-request', 'file-request-error',
'file-send-error', 'file-error', 'file-stopped', 'file-completed',
'jingle-incoming'):
'file-hash-error', 'jingle-incoming'):
# Get the first single message event
event = gajim.events.get_first_event(account, fjid, type_)
if not event:

View File

@ -1917,6 +1917,9 @@ class RosterWindow:
ft.show_stopped(jid, data, error_msg=msg_err)
gajim.events.remove_events(account, jid, event)
return True
elif event.type_ == 'file-hash-error':
ft.show_hash_error(jid, data)
gajim.events.remove_events(account, jid, event)
elif event.type_ == 'file-completed':
ft.show_completed(jid, data)
gajim.events.remove_events(account, jid, event)