changeset a26a69ba790c in /home/hg/repos/gajim
details:http://hg.gajim.org/gajim?cmd=changeset;node=a26a69ba790c description: first show to use NEC to handle presence events
diffstat:
src/common/connection_handlers.py | 343 +---------------------------- src/common/connection_handlers_events.py | 368 +++++++++++++++++++++++++++++++ src/gui_interface.py | 161 +++++------- src/remote_control.py | 17 +- 4 files changed, 458 insertions(+), 431 deletions(-)
diffs (truncated from 1120 to 300 lines):
diff -r 8f32c19838fa -r a26a69ba790c src/common/connection_handlers.py --- a/src/common/connection_handlers.py Fri Sep 17 12:41:00 2010 +0200 +++ b/src/common/connection_handlers.py Fri Sep 17 12:41:30 2010 +0200 @@ -1089,6 +1089,7 @@ PrivateStorageRosternotesReceivedEvent) gajim.nec.register_incoming_event(RosternotesReceivedEvent) gajim.nec.register_incoming_event(StreamConflictReceivedEvent) + gajim.nec.register_incoming_event(PresenceReceivedEvent)
gajim.ged.register_event_handler('http-auth-received', ged.CORE, self._nec_http_auth_received) @@ -1738,347 +1739,9 @@ """ Called when we receive a presence """ + log.debug('PresenceCB') gajim.nec.push_incoming_event(NetworkEvent('raw-pres-received', - conn=con, xmpp_pres=prs)) - ptype = prs.getType() - if ptype == 'available': - ptype = None - rfc_types = ('unavailable', 'error', 'subscribe', 'subscribed', - 'unsubscribe', 'unsubscribed') - if ptype and not ptype in rfc_types: - ptype = None - log.debug('PresenceCB: %s' % ptype) - if not self.connection or self.connected < 2: - log.debug('account is no more connected') - return - try: - who = helpers.get_full_jid_from_iq(prs) - except Exception: - if prs.getTag('error') and prs.getTag('error').getTag('jid-malformed'): - # wrong jid, we probably tried to change our nick in a room to a non - # valid one - who = str(prs.getFrom()) - jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who) - self.dispatch('GC_MSG', (jid_stripped, - _('Nickname not allowed: %s') % resource, None, False, None, [])) - return - jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who) - timestamp = None - id_ = prs.getID() - is_gc = False # is it a GC presence ? - sigTag = None - ns_muc_user_x = None - avatar_sha = None - # XEP-0172 User Nickname - user_nick = prs.getTagData('nick') - if not user_nick: - user_nick = '' - contact_nickname = None - transport_auto_auth = False - # XEP-0203 - delay_tag = prs.getTag('delay', namespace=common.xmpp.NS_DELAY2) - if delay_tag: - tim = prs.getTimestamp2() - tim = helpers.datetime_tuple(tim) - timestamp = localtime(timegm(tim)) - xtags = prs.getTags('x') - for x in xtags: - namespace = x.getNamespace() - if namespace.startswith(common.xmpp.NS_MUC): - is_gc = True - if namespace == common.xmpp.NS_MUC_USER and x.getTag('destroy'): - ns_muc_user_x = x - elif namespace == common.xmpp.NS_SIGNED: - sigTag = x - elif namespace == common.xmpp.NS_VCARD_UPDATE: - avatar_sha = x.getTagData('photo') - contact_nickname = x.getTagData('nickname') - elif namespace == common.xmpp.NS_DELAY and not timestamp: - # XEP-0091 - tim = prs.getTimestamp() - tim = helpers.datetime_tuple(tim) - timestamp = localtime(timegm(tim)) - elif namespace == 'http://delx.cjb.net/protocol/roster-subsync': - # see http://trac.gajim.org/ticket/326 - agent = gajim.get_server_from_jid(jid_stripped) - if self.connection.getRoster().getItem(agent): # to be sure it's a transport contact - transport_auto_auth = True - - if not is_gc and id_ and id_.startswith('gajim_muc_') and \ - ptype == 'error': - # Error presences may not include sent stanza, so we don't detect it's - # a muc preence. So detect it by ID - h = hmac.new(self.secret_hmac, jid_stripped).hexdigest()[:6] - if id_.split('_')[-1] == h: - is_gc = True - status = prs.getStatus() or '' - show = prs.getShow() - if show not in ('chat', 'away', 'xa', 'dnd'): - show = '' # We ignore unknown show - if not ptype and not show: - show = 'online' - elif ptype == 'unavailable': - show = 'offline' - - prio = prs.getPriority() - try: - prio = int(prio) - except Exception: - prio = 0 - keyID = '' - if sigTag and self.USE_GPG and ptype != 'error': - # error presences contain our own signature - # verify - sigmsg = sigTag.getData() - keyID = self.gpg.verify(status, sigmsg) - - if is_gc: - if ptype == 'error': - errcon = prs.getError() - errmsg = prs.getErrorMsg() - errcode = prs.getErrorCode() - room_jid, nick = gajim.get_room_and_nick_from_fjid(who) - - gc_control = gajim.interface.msg_win_mgr.get_gc_control(room_jid, - self.name) - - # If gc_control is missing - it may be minimized. Try to get it from - # there. If it's not there - then it's missing anyway and will - # remain set to None. - if gc_control is None: - minimized = gajim.interface.minimized_controls[self.name] - gc_control = minimized.get(room_jid) - - if errcode == '502': - # Internal Timeout: - self.dispatch('NOTIFY', (jid_stripped, 'error', errmsg, resource, - prio, keyID, timestamp, None)) - elif (errcode == '503'): - if gc_control is None or gc_control.autorejoin is None: - # maximum user number reached - self.dispatch('GC_ERROR', (gc_control, - _('Unable to join group chat'), - _('Maximum number of users for %s has been ' - 'reached') % room_jid)) - elif (errcode == '401') or (errcon == 'not-authorized'): - # password required to join - self.dispatch('GC_PASSWORD_REQUIRED', (room_jid, nick)) - elif (errcode == '403') or (errcon == 'forbidden'): - # we are banned - self.dispatch('GC_ERROR', (gc_control, - _('Unable to join group chat'), - _('You are banned from group chat %s.') % room_jid)) - elif (errcode == '404') or (errcon in ('item-not-found', - 'remote-server-not-found')): - if gc_control is None or gc_control.autorejoin is None: - # group chat does not exist - self.dispatch('GC_ERROR', (gc_control, - _('Unable to join group chat'), - _('Group chat %s does not exist.') % room_jid)) - elif (errcode == '405') or (errcon == 'not-allowed'): - self.dispatch('GC_ERROR', (gc_control, - _('Unable to join group chat'), - _('Group chat creation is restricted.'))) - elif (errcode == '406') or (errcon == 'not-acceptable'): - self.dispatch('GC_ERROR', (gc_control, - _('Unable to join group chat'), - _('Your registered nickname must be used in group chat ' - '%s.') % room_jid)) - elif (errcode == '407') or (errcon == 'registration-required'): - self.dispatch('GC_ERROR', (gc_control, - _('Unable to join group chat'), - _('You are not in the members list in groupchat %s.') %\ - room_jid)) - elif (errcode == '409') or (errcon == 'conflict'): - # nick conflict - room_jid = gajim.get_room_from_fjid(who) - self.dispatch('ASK_NEW_NICK', (room_jid,)) - else: # print in the window the error - self.dispatch('ERROR_ANSWER', ('', jid_stripped, - errmsg, errcode)) - if not ptype or ptype == 'unavailable': - if gajim.config.get('log_contact_status_changes') and \ - gajim.config.should_log(self.name, jid_stripped): - gc_c = gajim.contacts.get_gc_contact(self.name, jid_stripped, - resource) - st = status or '' - if gc_c: - jid = gc_c.jid - else: - jid = prs.getJid() - if jid: - # we know real jid, save it in db - st += ' (%s)' % jid - try: - gajim.logger.write('gcstatus', who, st, show) - except exceptions.PysqliteOperationalError, e: - self.dispatch('DB_ERROR', (_('Disk Write Error'), - str(e))) - except exceptions.DatabaseMalformed: - pritext = _('Database Error') - sectext = _('The database file (%s) cannot be read. Try to ' - 'repair it (see http://trac.gajim.org/wiki/DatabaseBackup)' - ' or remove it (all history will be lost).') % \ - common.logger.LOG_DB_PATH - self.dispatch('DB_ERROR', (pritext, sectext)) - if avatar_sha or avatar_sha == '': - if avatar_sha == '': - # contact has no avatar - puny_nick = helpers.sanitize_filename(resource) - gajim.interface.remove_avatar_files(jid_stripped, puny_nick) - # if it's a gc presence, don't ask vcard here. We may ask it to - # real jid in gui part. - if ns_muc_user_x: - # Room has been destroyed. see - # http://www.xmpp.org/extensions/xep-0045.html#destroyroom - reason = _('Room has been destroyed') - destroy = ns_muc_user_x.getTag('destroy') - r = destroy.getTagData('reason') - if r: - reason += ' (%s)' % r - if destroy.getAttr('jid'): - try: - jid = helpers.parse_jid(destroy.getAttr('jid')) - reason += '\n' + _('You can join this room instead: %s') \ - % jid - except common.helpers.InvalidFormat: - pass - statusCode = ['destroyed'] - else: - reason = prs.getReason() - statusCode = prs.getStatusCode() - self.dispatch('GC_NOTIFY', (jid_stripped, show, status, resource, - prs.getRole(), prs.getAffiliation(), prs.getJid(), - reason, prs.getActor(), statusCode, prs.getNewNick(), - avatar_sha)) - return - - if ptype == 'subscribe': - log.debug('subscribe request from %s' % who) - if who.find('@') <= 0 and who in self.agent_registrations: - self.agent_registrations[who]['sub_received'] = True - if not self.agent_registrations[who]['roster_push']: - # We'll reply after roster push result - return - if gajim.config.get_per('accounts', self.name, 'autoauth') or \ - who.find('@') <= 0 or jid_stripped in self.jids_for_auto_auth or \ - transport_auto_auth: - if self.connection: - p = common.xmpp.Presence(who, 'subscribed') - p = self.add_sha(p) - self.connection.send(p) - if who.find('@') <= 0 or transport_auto_auth: - self.dispatch('NOTIFY', (jid_stripped, 'offline', 'offline', - resource, prio, keyID, timestamp, None)) - if transport_auto_auth: - self.automatically_added.append(jid_stripped) - self.request_subscription(jid_stripped, name = user_nick) - else: - if not status: - status = _('I would like to add you to my roster.') - self.dispatch('SUBSCRIBE', (jid_stripped, status, user_nick)) - elif ptype == 'subscribed': - if jid_stripped in self.automatically_added: - self.automatically_added.remove(jid_stripped) - else: - # detect a subscription loop - if jid_stripped not in self.subscribed_events: - self.subscribed_events[jid_stripped] = [] - self.subscribed_events[jid_stripped].append(time_time()) - block = False - if len(self.subscribed_events[jid_stripped]) > 5: - if time_time() - self.subscribed_events[jid_stripped][0] < 5: - block = True - self.subscribed_events[jid_stripped] = self.subscribed_events[jid_stripped][1:] - if block: - gajim.config.set_per('account', self.name, - 'dont_ack_subscription', True) - else: - self.dispatch('SUBSCRIBED', (jid_stripped, resource)) - # BE CAREFUL: no con.updateRosterItem() in a callback - log.debug(_('we are now subscribed to %s') % who) - elif ptype == 'unsubscribe': - log.debug(_('unsubscribe request from %s') % who) - elif ptype == 'unsubscribed': - log.debug(_('we are now unsubscribed from %s') % who) - # detect a unsubscription loop - if jid_stripped not in self.subscribed_events: - self.subscribed_events[jid_stripped] = [] - self.subscribed_events[jid_stripped].append(time_time()) - block = False - if len(self.subscribed_events[jid_stripped]) > 5: - if time_time() - self.subscribed_events[jid_stripped][0] < 5: - block = True - self.subscribed_events[jid_stripped] = self.subscribed_events[jid_stripped][1:] - if block: - gajim.config.set_per('account', self.name, 'dont_ack_subscription', - True) - else: - self.dispatch('UNSUBSCRIBED', jid_stripped) - elif ptype == 'error': - errmsg = prs.getError() - errcode = prs.getErrorCode() - if errcode != '502': # Internal Timeout: - # print in the window the error - self.dispatch('ERROR_ANSWER', ('', jid_stripped, - errmsg, errcode))