use NEC to handle file request (error) events

This commit is contained in:
Yann Leboulanger 2010-12-08 21:17:08 +01:00
parent f6a1397040
commit 2c1f20b773
3 changed files with 115 additions and 84 deletions

View File

@ -1691,3 +1691,64 @@ class AgentInfoErrorReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
self.get_jid_resource()
self.get_id()
return True
class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
name = 'file-request-received'
base_network_events = []
def generate(self):
self.get_id()
self.fjid = self.conn._ft_get_from(self.stanza)
self.jid = gajim.get_jid_without_resource(self.fjid)
self.file_props = {'type': 'r'}
self.file_props['sender'] = self.fjid
self.file_props['request-id'] = self.id_
si = self.stanza.getTag('si')
profile = si.getAttr('profile')
if profile != xmpp.NS_FILE:
self.conn.send_file_rejection(self.file_props, code='400', typ='profile')
raise xmpp.NodeProcessed
feature_tag = si.getTag('feature', namespace=xmpp.NS_FEATURE)
if not feature_tag:
return
form_tag = feature_tag.getTag('x', namespace=xmpp.NS_DATA)
if not form_tag:
return
self.dataform = dataforms.ExtendForm(node=form_tag)
for f in self.dataform.iter_fields():
if f.var == 'stream-method' and f.type == 'list-single':
values = [o[1] for o in f.options]
self.file_props['stream-methods'] = ' '.join(values)
if xmpp.NS_BYTESTREAM in values or xmpp.NS_IBB in values:
break
else:
self.conn.send_file_rejection(self.file_props, code='400', typ='stream')
raise xmpp.NodeProcessed
file_tag = si.getTag('file')
for attribute in file_tag.getAttrs():
if attribute in ('name', 'size', 'hash', 'date'):
val = file_tag.getAttr(attribute)
if val is None:
continue
self.file_props[attribute] = val
file_desc_tag = file_tag.getTag('desc')
if file_desc_tag is not None:
self.file_props['desc'] = file_desc_tag.getData()
mime_type = si.getAttr('mime-type')
if mime_type is not None:
self.file_props['mime-type'] = mime_type
self.file_props['receiver'] = self.conn._ft_get_our_jid()
self.file_props['sid'] = unicode(si.getAttr('id'))
self.file_props['transfered_size'] = []
return True
class FileRequestErrorEvent(nec.NetworkIncomingEvent):
name = 'file-request-error'
base_network_events = []
def generate(self):
self.jid = gajim.get_jid_without_resource(self.jid)
return True

View File

@ -37,6 +37,8 @@ from common import xmpp
from common import gajim
from common import helpers
from common import dataforms
from common.connection_handlers_events import FileRequestReceivedEvent
from common import ged
from common.socks5 import Socks5Receiver
@ -79,6 +81,8 @@ class ConnectionBytestream:
def __init__(self):
self.files_props = {}
gajim.ged.register_event_handler('file-request-received', ged.GUI1,
self._nec_file_request_received)
def _ft_get_our_jid(self):
our_jid = gajim.get_jid_from_account(self.name)
@ -212,52 +216,15 @@ class ConnectionBytestream:
raise xmpp.NodeProcessed
def _siSetCB(self, con, iq_obj):
jid = self._ft_get_from(iq_obj)
file_props = {'type': 'r'}
file_props['sender'] = jid
file_props['request-id'] = unicode(iq_obj.getAttr('id'))
si = iq_obj.getTag('si')
profile = si.getAttr('profile')
mime_type = si.getAttr('mime-type')
if profile != xmpp.NS_FILE:
self.send_file_rejection(file_props, code='400', typ='profile')
raise xmpp.NodeProcessed
feature_tag = si.getTag('feature', namespace=xmpp.NS_FEATURE)
if not feature_tag:
return
form_tag = feature_tag.getTag('x', namespace=xmpp.NS_DATA)
if not form_tag:
return
form = dataforms.ExtendForm(node=form_tag)
for f in form.iter_fields():
if f.var == 'stream-method' and f.type == 'list-single':
values = [o[1] for o in f.options]
file_props['stream-methods'] = ' '.join(values)
if xmpp.NS_BYTESTREAM in values or xmpp.NS_IBB in values:
break
else:
self.send_file_rejection(file_props, code='400', typ='stream')
raise xmpp.NodeProcessed
file_tag = si.getTag('file')
for attribute in file_tag.getAttrs():
if attribute in ('name', 'size', 'hash', 'date'):
val = file_tag.getAttr(attribute)
if val is None:
continue
file_props[attribute] = val
file_desc_tag = file_tag.getTag('desc')
if file_desc_tag is not None:
file_props['desc'] = file_desc_tag.getData()
if mime_type is not None:
file_props['mime-type'] = mime_type
file_props['receiver'] = self._ft_get_our_jid()
file_props['sid'] = unicode(si.getAttr('id'))
file_props['transfered_size'] = []
gajim.socks5queue.add_file_props(self.name, file_props)
self.dispatch('FILE_REQUEST', (jid, file_props))
gajim.nec.push_incoming_event(FileRequestReceivedEvent(None, conn=self,
stanza=iq_obj))
raise xmpp.NodeProcessed
def _nec_file_request_received(self, obj):
if obj.conn.name != self.name:
return
gajim.socks5queue.add_file_props(self.name, obj.file_props)
def _siErrorCB(self, con, iq_obj):
si = iq_obj.getTag('si')
profile = si.getAttr('profile')
@ -268,7 +235,8 @@ class ConnectionBytestream:
return
jid = self._ft_get_from(iq_obj)
file_props['error'] = -3
self.dispatch('FILE_REQUEST_ERROR', (jid, file_props, ''))
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
jid=jid, file_props=file_props, error_msg=''))
raise xmpp.NodeProcessed
class ConnectionSocks5Bytestream(ConnectionBytestream):
@ -300,7 +268,9 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
if contact.get_full_jid() == receiver_jid:
file_props['error'] = -5
self.remove_transfer(file_props)
self.dispatch('FILE_REQUEST_ERROR', (contact.jid, file_props, ''))
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
conn=self, jid=contact.jid, file_props=file_props,
error_msg=''))
sender_jid = unicode(file_props['sender'])
if contact.get_full_jid() == sender_jid:
file_props['error'] = -3
@ -336,7 +306,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
if 'idx' in host and host['idx'] > 0:
gajim.socks5queue.remove_receiver(host['idx'])
gajim.socks5queue.remove_sender(host['idx'])
if 'direction' in file_props:
# it's a IBB
sid = file_props['sid']
@ -360,7 +330,8 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
self._result_socks5_sid, file_props['sid'])
if not listener:
file_props['error'] = -5
self.dispatch('FILE_REQUEST_ERROR', (unicode(receiver), file_props, ''))
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
jid=unicode(receiver), file_props=file_props, error_msg=''))
self._connect_error(unicode(receiver), file_props['sid'],
file_props['sid'], code=406)
else:
@ -490,7 +461,8 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
if file_props is not None:
self.disconnect_transfer(file_props)
file_props['error'] = -3
self.dispatch('FILE_REQUEST_ERROR', (to, file_props, msg))
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
conn=self, jid=to, file_props=file_props, error_msg=msg))
def _proxy_auth_ok(self, proxy):
"""
@ -521,7 +493,8 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
return
file_props = self.files_props[id_]
file_props['error'] = -4
self.dispatch('FILE_REQUEST_ERROR', (jid, file_props, ''))
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
jid=jid, file_props=file_props, error_msg=''))
raise xmpp.NodeProcessed
def _bytestreamSetCB(self, con, iq_obj):
@ -799,7 +772,7 @@ class ConnectionIBBytestream(ConnectionBytestream):
{'sid':sid})]))
file_props['completed'] = True
del self.files_props[sid]
def IBBMessageHandler(self, conn, stanza):
"""
Receive next portion of incoming datastream and store it write

View File

@ -166,8 +166,9 @@ class Interface:
file_props['error'] = -3
else:
file_props['error'] = -4
self.handle_event_file_request_error(obj.conn.name, (obj.fjid,
file_props, obj.errmsg))
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
conn=self, jid=obj.jid, file_props=file_props,
error_msg=obj.errmsg))
obj.conn.disconnect_transfer(file_props)
return
elif unicode(obj.errcode) == '404':
@ -819,19 +820,17 @@ class Interface:
notify.popup(_('New E-mail'), jid, obj.conn.name, 'gmail',
path_to_image=path, title=title, text=text)
def handle_event_file_request_error(self, account, array):
def handle_event_file_request_error(self, obj):
# ('FILE_REQUEST_ERROR', account, (jid, file_props, error_msg))
jid, file_props, errmsg = array
jid = gajim.get_jid_without_resource(jid)
ft = self.instances['file_transfers']
ft.set_status(file_props['type'], file_props['sid'], 'stop')
errno = file_props['error']
ft.set_status(obj.file_props['type'], obj.file_props['sid'], 'stop')
errno = obj.file_props['error']
if helpers.allow_popup_window(account):
if helpers.allow_popup_window(obj.conn.name):
if errno in (-4, -5):
ft.show_stopped(jid, file_props, errmsg)
ft.show_stopped(obj.jid, obj.file_props, obj.error_msg)
else:
ft.show_request_error(file_props)
ft.show_request_error(obj.file_props)
return
if errno in (-4, -5):
@ -839,45 +838,43 @@ class Interface:
else:
msg_type = 'file-request-error'
self.add_event(account, jid, msg_type, file_props)
self.add_event(obj.conn.name, obj.jid, msg_type, obj.file_props)
if helpers.allow_showing_notification(account):
if helpers.allow_showing_notification(obj.conn.name):
# check if we should be notified
path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
event_type = _('File Transfer Error')
notify.popup(event_type, jid, account, msg_type, path,
title = event_type, text = file_props['name'])
notify.popup(event_type, obj.jid, obj.conn.name, msg_type, path,
title=event_type, text=obj.file_props['name'])
def handle_event_file_request(self, account, array):
jid = array[0]
jid = gajim.get_jid_without_resource(jid)
if jid not in gajim.contacts.get_jid_list(account):
def handle_event_file_request(self, obj):
account = obj.conn.name
if obj.jid not in gajim.contacts.get_jid_list(account):
keyID = ''
attached_keys = gajim.config.get_per('accounts', account,
'attached_gpg_keys').split()
if jid in attached_keys:
keyID = attached_keys[attached_keys.index(jid) + 1]
contact = gajim.contacts.create_not_in_roster_contact(jid=jid,
account=account, keyID=keyID)
'attached_gpg_keys').split()
if obj.jid in attached_keys:
keyID = attached_keys[attached_keys.index(obj.jid) + 1]
contact = gajim.contacts.create_not_in_roster_contact(jid=obj.jid,
account=account, keyID=keyID)
gajim.contacts.add_contact(account, contact)
self.roster.add_contact(contact.jid, account)
file_props = array[1]
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
self.roster.add_contact(obj.jid, account)
contact = gajim.contacts.get_first_contact_from_jid(account, obj.jid)
if helpers.allow_popup_window(account):
self.instances['file_transfers'].show_file_request(account, contact,
file_props)
obj.file_props)
return
self.add_event(account, jid, 'file-request', file_props)
self.add_event(account, obj.jid, 'file-request', obj.file_props)
if helpers.allow_showing_notification(account):
path = gtkgui_helpers.get_icon_path('gajim-ft_request', 48)
txt = _('%s wants to send you a file.') % gajim.get_name_from_jid(
account, jid)
account, obj.jid)
event_type = _('File Transfer Request')
notify.popup(event_type, jid, account, 'file-request',
path_to_image = path, title = event_type, text = txt)
notify.popup(event_type, obj.jid, account, 'file-request',
path_to_image=path, title=event_type, text=txt)
def handle_event_file_error(self, title, message):
dialogs.ErrorDialog(title, message)
@ -1376,14 +1373,14 @@ class Interface:
'ERROR': [self.handle_event_error],
'DB_ERROR': [self.handle_event_db_error],
'INFORMATION': [self.handle_event_information],
'FILE_REQUEST': [self.handle_event_file_request],
'FILE_REQUEST_ERROR': [self.handle_event_file_request_error],
'FILE_SEND_ERROR': [self.handle_event_file_send_error],
'atom-entry-received': [self.handle_atom_entry],
'bad-gpg-passphrase': [self.handle_event_bad_gpg_passphrase],
'bookmarks-received': [self.handle_event_bookmarks],
'connection-lost': [self.handle_event_connection_lost],
'failed-decrypt': [(self.handle_event_failed_decrypt, ged.GUI2)],
'file-request-error': [self.handle_event_file_request_error],
'file-request-received': [self.handle_event_file_request],
'fingerprint-error': [self.handle_event_fingerprint_error],
'gc-invitation-received': [self.handle_event_gc_invitation],
'gc-presence-received': [self.handle_event_gc_presence],