diff --git a/gajim/common/connection.py b/gajim/common/connection.py index e637006c2..7e72bfead 100644 --- a/gajim/common/connection.py +++ b/gajim/common/connection.py @@ -75,7 +75,9 @@ from gajim.common.modules.vcard_temp import VCardTemp from gajim.common.modules.vcard_avatars import VCardAvatars from gajim.common.modules.pubsub import PubSub from gajim.common.modules.bookmarks import Bookmarks +from gajim.common.modules.pep import PEP from gajim.common.modules.user_avatar import UserAvatar +from gajim.common.modules.user_activity import UserActivity from gajim.common.connection_handlers import * from gajim.common.contacts import GC_Contact from gajim.gtkgui_helpers import get_action @@ -179,7 +181,10 @@ class CommonConnection: return self._modules[name] def get_module_handlers(self): - return self._modules.values() + handlers = [] + for module in self._modules.values(): + handlers += module.handlers + return handlers def register_module(self, name, cls, *args, **kwargs): self._modules[name] = cls(*args, **kwargs) @@ -661,8 +666,10 @@ class Connection(CommonConnection, ConnectionHandlers): self.register_module('VCardTemp', VCardTemp, self) self.register_module('VCardAvatars', VCardAvatars, self) self.register_module('PubSub', PubSub, self) + self.register_module('PEP', PEP, self) self.register_module('Bookmarks', Bookmarks, self) self.register_module('UserAvatar', UserAvatar, self) + self.register_module('UserActivity', UserActivity, self) app.ged.register_event_handler('privacy-list-received', ged.CORE, self._nec_privacy_list_received) @@ -749,6 +756,7 @@ class Connection(CommonConnection, ConnectionHandlers): def disconnect(self, on_purpose=False): app.interface.music_track_changed(None, None, self.name) self.reset_awaiting_pep() + self.get_module('PEP').reset_stored_publish() self.on_purpose = on_purpose self.connected = 0 self.time_to_reconnect = None diff --git a/gajim/common/connection_handlers.py b/gajim/common/connection_handlers.py index 3f79a2961..5f768721e 100644 --- a/gajim/common/connection_handlers.py +++ b/gajim/common/connection_handlers.py @@ -295,7 +295,6 @@ class ConnectionPEP(object): self._account = new_name def reset_awaiting_pep(self): - self.to_be_sent_activity = None self.to_be_sent_mood = None self.to_be_sent_tune = None self.to_be_sent_nick = None @@ -305,8 +304,6 @@ class ConnectionPEP(object): """ Send pep info that were waiting for connection """ - if self.to_be_sent_activity: - self.send_activity(*self.to_be_sent_activity) if self.to_be_sent_mood: self.send_mood(*self.to_be_sent_mood) if self.to_be_sent_tune: @@ -317,37 +314,6 @@ class ConnectionPEP(object): self.send_location(self.to_be_sent_location) self.reset_awaiting_pep() - def _pubsubEventCB(self, xmpp_dispatcher, msg): - ''' Called when we receive with pubsub event. ''' - app.nec.push_incoming_event(PEPReceivedEvent(None, conn=self, - stanza=msg)) - - def send_activity(self, activity, subactivity=None, message=None): - if self.connected == 1: - # We are connecting, keep activity in mem and send it when we'll be - # connected - self.to_be_sent_activity = (activity, subactivity, message) - return - if not self.pep_supported: - return - item = nbxmpp.Node('activity', {'xmlns': nbxmpp.NS_ACTIVITY}) - if activity: - i = item.addChild(activity) - if subactivity: - i.addChild(subactivity) - if message: - i = item.addChild('text') - i.addData(message) - self.get_module('PubSub').send_pb_publish( - '', nbxmpp.NS_ACTIVITY, item, '0') - - def retract_activity(self): - if not self.pep_supported: - return - self.send_activity(None) - # not all client support new XEP, so we still retract - self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_ACTIVITY, '0') - def send_mood(self, mood, message=None): if self.connected == 1: # We are connecting, keep mood in mem and send it when we'll be @@ -1187,14 +1153,16 @@ ConnectionHTTPUpload): app.config.set_per('accounts', self.name, 'roster_version', obj.version) - def _messageCB(self, con, msg): + def _messageCB(self, con, stanza): """ Called when we receive a message """ + if nbxmpp.NS_PUBSUB_EVENT in stanza.getProperties(): + return log.debug('MessageCB') app.nec.push_incoming_event(NetworkEvent('raw-message-received', - conn=self, stanza=msg, account=self.name)) + conn=self, stanza=stanza, account=self.name)) def _dispatch_gc_msg_with_captcha(self, stanza, msg_obj): msg_obj.stanza = stanza @@ -1518,6 +1486,7 @@ ConnectionHTTPUpload): # Inform GUI we just signed in app.nec.push_incoming_event(SignedInEvent(None, conn=self)) self.send_awaiting_pep() + self.get_module('PEP').send_stored_publish() self.continue_connect_info = None def _PubkeyGetCB(self, con, iq_obj): @@ -1583,11 +1552,6 @@ ConnectionHTTPUpload): # that defines handlers con.RegisterHandler('message', self._messageCB) con.RegisterHandler('presence', self._presenceCB) - # We use makefirst so that this handler is called before _messageCB, and - # can prevent calling it when it's not needed. - # We also don't check for namespace, else it cannot stop _messageCB to - # be called - con.RegisterHandler('message', self._pubsubEventCB, makefirst=True) con.RegisterHandler('iq', self._rosterSetCB, 'set', nbxmpp.NS_ROSTER) con.RegisterHandler('iq', self._siSetCB, 'set', nbxmpp.NS_SI) con.RegisterHandler('iq', self._siErrorCB, 'error', nbxmpp.NS_SI) @@ -1645,6 +1609,5 @@ ConnectionHTTPUpload): con.RegisterHandler('iq', self._BlockingResultCB, 'result', nbxmpp.NS_BLOCKING) - for module in self.get_module_handlers(): - for handler in module.handlers: - con.RegisterHandler(*handler) + for handler in self.get_module_handlers(): + con.RegisterHandler(*handler) diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py index 52fce3931..8554525b7 100644 --- a/gajim/common/connection_handlers_events.py +++ b/gajim/common/connection_handlers_events.py @@ -1780,7 +1780,6 @@ class PEPReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): if entry: app.nec.push_incoming_event(AtomEntryReceived(None, conn=self.conn, node=entry)) - raise nbxmpp.NodeProcessed class AtomEntryReceived(nec.NetworkIncomingEvent): name = 'atom-entry-received' diff --git a/gajim/common/const.py b/gajim/common/const.py index 66d675bd6..2ea55eb7b 100644 --- a/gajim/common/const.py +++ b/gajim/common/const.py @@ -124,6 +124,108 @@ class BookmarkStorageType(IntEnum): PRIVATE = 0 PUBSUB = 1 +@unique +class PEPHandlerType(IntEnum): + NOTIFY = 0 + RETRACT = 1 + +@unique +class PEPEventType(IntEnum): + ACTIVITY = 0 + + +ACTIVITIES = { + 'doing_chores': { + 'category': _('Doing Chores'), + 'buying_groceries': _('Buying Groceries'), + 'cleaning': _('Cleaning'), + 'cooking': _('Cooking'), + 'doing_maintenance': _('Doing Maintenance'), + 'doing_the_dishes': _('Doing the Dishes'), + 'doing_the_laundry': _('Doing the Laundry'), + 'gardening': _('Gardening'), + 'running_an_errand': _('Running an Errand'), + 'walking_the_dog': _('Walking the Dog')}, + 'drinking': { + 'category': _('Drinking'), + 'having_a_beer': _('Having a Beer'), + 'having_coffee': _('Having Coffee'), + 'having_tea': _('Having Tea')}, + 'eating': { + 'category': _('Eating'), + 'having_a_snack': _('Having a Snack'), + 'having_breakfast': _('Having Breakfast'), + 'having_dinner': _('Having Dinner'), + 'having_lunch': _('Having Lunch')}, + 'exercising': { + 'category': _('Exercising'), + 'cycling': _('Cycling'), + 'dancing': _('Dancing'), + 'hiking': _('Hiking'), + 'jogging': _('Jogging'), + 'playing_sports': _('Playing Sports'), + 'running': _('Running'), + 'skiing': _('Skiing'), + 'swimming': _('Swimming'), + 'working_out': _('Working out')}, + 'grooming': { + 'category': _('Grooming'), + 'at_the_spa': _('At the Spa'), + 'brushing_teeth': _('Brushing Teeth'), + 'getting_a_haircut': _('Getting a Haircut'), + 'shaving': _('Shaving'), + 'taking_a_bath': _('Taking a Bath'), + 'taking_a_shower': _('Taking a Shower')}, + 'having_appointment': { + 'category': _('Having an Appointment')}, + 'inactive': { + 'category': _('Inactive'), + 'day_off': _('Day Off'), + 'hanging_out': _('Hanging out'), + 'hiding': _('Hiding'), + 'on_vacation': _('On Vacation'), + 'praying': _('Praying'), + 'scheduled_holiday': _('Scheduled Holiday'), + 'sleeping': _('Sleeping'), + 'thinking': _('Thinking')}, + 'relaxing': { + 'category': _('Relaxing'), + 'fishing': _('Fishing'), + 'gaming': _('Gaming'), + 'going_out': _('Going out'), + 'partying': _('Partying'), + 'reading': _('Reading'), + 'rehearsing': _('Rehearsing'), + 'shopping': _('Shopping'), + 'smoking': _('Smoking'), + 'socializing': _('Socializing'), + 'sunbathing': _('Sunbathing'), + 'watching_tv': _('Watching TV'), + 'watching_a_movie': _('Watching a Movie')}, + 'talking': { + 'category': _('Talking'), + 'in_real_life': _('In Real Life'), + 'on_the_phone': _('On the Phone'), + 'on_video_phone': _('On Video Phone')}, + 'traveling': { + 'category': _('Traveling'), + 'commuting': _('Commuting'), + 'cycling': _('Cycling'), + 'driving': _('Driving'), + 'in_a_car': _('In a Car'), + 'on_a_bus': _('On a Bus'), + 'on_a_plane': _('On a Plane'), + 'on_a_train': _('On a Train'), + 'on_a_trip': _('On a Trip'), + 'walking': _('Walking')}, + 'working': { + 'category': _('Working'), + 'coding': _('Coding'), + 'in_a_meeting': _('In a Meeting'), + 'studying': _('Studying'), + 'writing': _('Writing')}} + + SSLError = { 2: _("Unable to get issuer certificate"), 3: _("Unable to get certificate CRL"), diff --git a/gajim/common/modules/pep.py b/gajim/common/modules/pep.py new file mode 100644 index 000000000..464dd4e32 --- /dev/null +++ b/gajim/common/modules/pep.py @@ -0,0 +1,139 @@ +# This file is part of Gajim. +# +# Gajim is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# Gajim is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Gajim. If not, see . + +# XEP-0163: Personal Eventing Protocol + +import logging + +import nbxmpp + +from gajim.common import app +from gajim.common.nec import NetworkIncomingEvent +from gajim.common.const import PEPHandlerType, PEPEventType + +log = logging.getLogger('gajim.c.m.pep') + + +class PEP: + def __init__(self, con): + self._con = con + self._account = con.name + + self.handlers = [ + ('message', self._pep_event_received, + 'headline', nbxmpp.NS_PUBSUB_EVENT) + ] + + self._pep_handlers = {} + self._store_publish_modules = [] + + def register_pep_handler(self, namespace, notify_handler, retract_handler): + if namespace in self._pep_handlers: + self._pep_handlers[namespace].append( + (notify_handler, retract_handler)) + else: + self._pep_handlers[namespace] = [(notify_handler, retract_handler)] + if notify_handler: + module_instance = notify_handler.__self__ + if hasattr(module_instance, 'send_stored_publish'): + if module_instance not in self._store_publish_modules: + self._store_publish_modules.append(module_instance) + + def _pep_event_received(self, conn, stanza): + jid = stanza.getFrom() + event = stanza.getTag('event', namespace=nbxmpp.NS_PUBSUB_EVENT) + items = event.getTag('items') + if items is None: + log.warning('Malformed PEP event (no items node): %s', stanza) + raise nbxmpp.NodeProcessed + + namespace = items.getAttr('node') + if namespace is None: + log.warning('Malformed PEP event (no node attr): %s', stanza) + raise nbxmpp.NodeProcessed + + log.info('PEP notification received: %s %s', jid, namespace) + + handlers = self._pep_handlers.get(namespace, None) + if handlers is None: + # Old Fallback + from gajim.common.connection_handlers_events import PEPReceivedEvent as OldPEPReceivedEvent + app.nec.push_incoming_event( + OldPEPReceivedEvent(None, conn=self._con, stanza=stanza)) + raise nbxmpp.NodeProcessed + else: + # Check if this is a retraction + retract = items.getTag('retract') + if retract is not None: + for handler in handlers: + handler[PEPHandlerType.RETRACT](jid, retract.getID()) + raise nbxmpp.NodeProcessed + + # Check if we have items + items_ = items.getTags('item') + if items_ is None: + log.warning('Malformed PEP event received: %s', stanza) + raise nbxmpp.NodeProcessed + for handler in handlers: + handler[PEPHandlerType.NOTIFY](jid, items_[0]) + raise nbxmpp.NodeProcessed + + def send_stored_publish(self): + for module in self._store_publish_modules: + module.send_stored_publish() + + def reset_stored_publish(self): + for module in self._store_publish_modules: + module.reset_stored_publish() + + +class PEPEvent: + + name = '' + + def __init__(self, con, account): + self.__account = account + self.__con = con + + def _update_contacts(self, jid, user_pep): + for contact in app.contacts.get_contacts(self.__account, str(jid)): + if user_pep: + contact.pep[self.name] = user_pep + else: + contact.pep.pop(self.name, None) + + if jid == self.__con.get_own_jid().getStripped(): + if user_pep: + self.__con.pep[self.name] = user_pep + else: + self.__con.pep.pop(self.name, None) + + +class AbstractPEP: + + type_ = PEPEventType + + def __eq__(self, other): + return other == self.type_ + + def __bool__(self): + return self._pep_specific_data is not None + + def __str__(self): + return str(self._pep_specific_data) + + +class PEPReceivedEvent(NetworkIncomingEvent): + name = 'pep-received' + base_network_events = [] diff --git a/gajim/common/modules/user_activity.py b/gajim/common/modules/user_activity.py new file mode 100644 index 000000000..20dae13a0 --- /dev/null +++ b/gajim/common/modules/user_activity.py @@ -0,0 +1,161 @@ +# This file is part of Gajim. +# +# Gajim is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# Gajim is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Gajim. If not, see . + +# XEP-0108: User Activity + +import logging + +import nbxmpp +from gi.repository import GLib + +from gajim.common import app +from gajim.common.const import PEPEventType, ACTIVITIES +from gajim.common.exceptions import StanzaMalformed +from gajim.common.modules.pep import PEPReceivedEvent, PEPEvent, AbstractPEP + +log = logging.getLogger('gajim.c.m.user_activity') + + +class UserActivity(PEPEvent): + + name = 'activity' + + def __init__(self, con): + PEPEvent.__init__(self, con, con.name) + self._con = con + self._account = con.name + + self.handlers = [] + + self._stored_publish = None + + self._con.get_module('PEP').register_pep_handler( + nbxmpp.NS_ACTIVITY, + self._pep_notify_received, + self._pep_retract_received) + + def _pep_notify_received(self, jid, item): + try: + activity = self._extract_info(item) + except StanzaMalformed as error: + log.warning('%s, %s: %s', jid, error, item) + return + + log.info('Received: %s %s', jid, activity) + self._push_event(jid, UserActivityPEP(activity)) + + def _pep_retract_received(self, jid, id_): + log.info('Retract: %s %s', jid, id_) + self._push_event(jid, UserActivityPEP(None)) + + def _push_event(self, jid, user_pep): + self._update_contacts(jid, user_pep) + app.nec.push_incoming_event( + PEPReceivedEvent(None, conn=self._con, + jid=str(jid), + pep_type=self.name)) + + def _extract_info(self, item): + activity_dict = {} + activity_tag = item.getTag('activity', namespace=nbxmpp.NS_ACTIVITY) + if activity_tag is None: + raise StanzaMalformed('No activity node') + + for child in activity_tag.getChildren(): + name = child.getName().strip() + data = child.getData().strip() + if name == 'text': + activity_dict['text'] = data + else: + activity_dict['activity'] = name + for subactivity in child.getChildren(): + subactivity_name = subactivity.getName().strip() + activity_dict['subactivity'] = subactivity_name + + return activity_dict or None + + def send_stored_publish(self): + if self._stored_publish is not None: + log.info('Send stored publish') + self.send_activity(*self._stored_publish) + self._stored_publish = None + + def reset_stored_publish(self): + log.info('Reset stored publish') + self._stored_publish = None + + def send_activity(self, activity=None, subactivity=None, message=None): + if not self._con.pep_supported: + return + + if self._con.connected == 1: + # We are connecting, save activity and send it later + self._stored_publish = (activity, subactivity, message) + return + + if activity: + log.info('Send activity: %s %s %s', activity, subactivity, message) + else: + log.info('Remove activity') + + item = self._build_activity_node(activity, subactivity, message) + + self._con.get_module('PubSub').send_pb_publish( + '', nbxmpp.NS_ACTIVITY, item, 'current') + + def _build_activity_node(self, activity, subactivity=None, message=None): + item = nbxmpp.Node('activity', {'xmlns': nbxmpp.NS_ACTIVITY}) + if activity: + i = item.addChild(activity) + if subactivity: + i.addChild(subactivity) + if message: + i = item.addChild('text') + i.addData(message) + return item + + def retract_activity(self): + if not self._con.pep_supported: + return + self.send_activity() + self._con.get_module('PubSub').send_pb_retract( + '', nbxmpp.NS_ACTIVITY, 'current') + + +class UserActivityPEP(AbstractPEP): + + type_ = PEPEventType.ACTIVITY + + def __init__(self, activity): + self._pep_specific_data = activity + + def asMarkupText(self): + pep = self._pep_specific_data + activity = pep['activity'] + subactivity = pep['subactivity'] if 'subactivity' in pep else None + text = pep['text'] if 'text' in pep else None + + if activity in ACTIVITIES: + # Translate standard activities + if subactivity in ACTIVITIES[activity]: + subactivity = ACTIVITIES[activity][subactivity] + activity = ACTIVITIES[activity]['category'] + + markuptext = '' + GLib.markup_escape_text(activity) + if subactivity: + markuptext += ': ' + GLib.markup_escape_text(subactivity) + markuptext += '' + if text: + markuptext += ' (%s)' % GLib.markup_escape_text(text) + return markuptext diff --git a/gajim/common/pep.py b/gajim/common/pep.py index 83b7ebb88..5283717f4 100644 --- a/gajim/common/pep.py +++ b/gajim/common/pep.py @@ -109,86 +109,6 @@ MOODS = { 'weak': _('Weak'), 'worried': _('Worried')} -ACTIVITIES = { - 'doing_chores': {'category': _('Doing Chores'), - 'buying_groceries': _('Buying Groceries'), - 'cleaning': _('Cleaning'), - 'cooking': _('Cooking'), - 'doing_maintenance': _('Doing Maintenance'), - 'doing_the_dishes': _('Doing the Dishes'), - 'doing_the_laundry': _('Doing the Laundry'), - 'gardening': _('Gardening'), - 'running_an_errand': _('Running an Errand'), - 'walking_the_dog': _('Walking the Dog')}, - 'drinking': {'category': _('Drinking'), - 'having_a_beer': _('Having a Beer'), - 'having_coffee': _('Having Coffee'), - 'having_tea': _('Having Tea')}, - 'eating': {'category': _('Eating'), - 'having_a_snack': _('Having a Snack'), - 'having_breakfast': _('Having Breakfast'), - 'having_dinner': _('Having Dinner'), - 'having_lunch': _('Having Lunch')}, - 'exercising': {'category': _('Exercising'), - 'cycling': _('Cycling'), - 'dancing': _('Dancing'), - 'hiking': _('Hiking'), - 'jogging': _('Jogging'), - 'playing_sports': _('Playing Sports'), - 'running': _('Running'), - 'skiing': _('Skiing'), - 'swimming': _('Swimming'), - 'working_out': _('Working out')}, - 'grooming': {'category': _('Grooming'), - 'at_the_spa': _('At the Spa'), - 'brushing_teeth': _('Brushing Teeth'), - 'getting_a_haircut': _('Getting a Haircut'), - 'shaving': _('Shaving'), - 'taking_a_bath': _('Taking a Bath'), - 'taking_a_shower': _('Taking a Shower')}, - 'having_appointment': {'category': _('Having an Appointment')}, - 'inactive': {'category': _('Inactive'), - 'day_off': _('Day Off'), - 'hanging_out': _('Hanging out'), - 'hiding': _('Hiding'), - 'on_vacation': _('On Vacation'), - 'praying': _('Praying'), - 'scheduled_holiday': _('Scheduled Holiday'), - 'sleeping': _('Sleeping'), - 'thinking': _('Thinking')}, - 'relaxing': {'category': _('Relaxing'), - 'fishing': _('Fishing'), - 'gaming': _('Gaming'), - 'going_out': _('Going out'), - 'partying': _('Partying'), - 'reading': _('Reading'), - 'rehearsing': _('Rehearsing'), - 'shopping': _('Shopping'), - 'smoking': _('Smoking'), - 'socializing': _('Socializing'), - 'sunbathing': _('Sunbathing'), - 'watching_tv': _('Watching TV'), - 'watching_a_movie': _('Watching a Movie')}, - 'talking': {'category': _('Talking'), - 'in_real_life': _('In Real Life'), - 'on_the_phone': _('On the Phone'), - 'on_video_phone': _('On Video Phone')}, - 'traveling': {'category': _('Traveling'), - 'commuting': _('Commuting'), - 'cycling': _('Cycling'), - 'driving': _('Driving'), - 'in_a_car': _('In a Car'), - 'on_a_bus': _('On a Bus'), - 'on_a_plane': _('On a Plane'), - 'on_a_train': _('On a Train'), - 'on_a_trip': _('On a Trip'), - 'walking': _('Walking')}, - 'working': {'category': _('Working'), - 'coding': _('Coding'), - 'in_a_meeting': _('In a Meeting'), - 'studying': _('Studying'), - 'writing': _('Writing')}} - TUNE_DATA = ['artist', 'title', 'source', 'track', 'length'] LOCATION_DATA = { @@ -355,54 +275,6 @@ class UserTunePEP(AbstractPEP): return tune_string -class UserActivityPEP(AbstractPEP): - '''XEP-0108: User Activity''' - - type_ = 'activity' - namespace = nbxmpp.NS_ACTIVITY - - def _extract_info(self, items): - activity_dict = {} - - for item in items.getTags('item'): - activity_tag = item.getTag('activity') - if activity_tag: - for child in activity_tag.getChildren(): - name = child.getName().strip() - data = child.getData().strip() - if name == 'text': - activity_dict['text'] = data - else: - activity_dict['activity'] = name - for subactivity in child.getChildren(): - subactivity_name = subactivity.getName().strip() - activity_dict['subactivity'] = subactivity_name - - retracted = items.getTag('retract') or not 'activity' in activity_dict - return (activity_dict, retracted) - - def asMarkupText(self): - assert not self._retracted - pep = self._pep_specific_data - activity = pep['activity'] - subactivity = pep['subactivity'] if 'subactivity' in pep else None - text = pep['text'] if 'text' in pep else None - - if activity in ACTIVITIES: - # Translate standard activities - if subactivity in ACTIVITIES[activity]: - subactivity = ACTIVITIES[activity][subactivity] - activity = ACTIVITIES[activity]['category'] - - markuptext = '' + GLib.markup_escape_text(activity) - if subactivity: - markuptext += ': ' + GLib.markup_escape_text(subactivity) - markuptext += '' - if text: - markuptext += ' (%s)' % GLib.markup_escape_text(text) - return markuptext - - class UserNicknamePEP(AbstractPEP): '''XEP-0172: User Nickname''' @@ -518,5 +390,5 @@ class AvatarNotificationPEP(AbstractPEP): SUPPORTED_PERSONAL_USER_EVENTS = [ - UserMoodPEP, UserTunePEP, UserActivityPEP, + UserMoodPEP, UserTunePEP, UserNicknamePEP, UserLocationPEP, AvatarNotificationPEP] diff --git a/gajim/dialogs.py b/gajim/dialogs.py index abbec845b..8085a5dfc 100644 --- a/gajim/dialogs.py +++ b/gajim/dialogs.py @@ -51,7 +51,7 @@ from gajim.common import pep from gajim.common import ged from gajim.common import const from gajim.options_dialog import OptionsDialog -from gajim.common.const import Option, OptionKind, OptionType +from gajim.common.const import Option, OptionKind, OptionType, ACTIVITIES from gajim.common import app from gajim.common import helpers @@ -371,11 +371,11 @@ class ChangeActivityDialog: rbtns = {} group = None - for category in pep.ACTIVITIES: + for category in ACTIVITIES: item = self.xml.get_object(category + '_image') item.set_from_pixbuf( gtkgui_helpers.load_activity_icon(category).get_pixbuf()) - item.set_tooltip_text(pep.ACTIVITIES[category]['category']) + item.set_tooltip_text(ACTIVITIES[category]['category']) vbox = self.xml.get_object(category + '_vbox') vbox.set_border_width(5) @@ -392,7 +392,7 @@ class ChangeActivityDialog: hbox = Gtk.HBox(homogeneous=False, spacing=5) hbox.pack_start(gtkgui_helpers.load_activity_icon(category, activity), False, False, 0) - lbl = Gtk.Label(label='' + pep.ACTIVITIES[category]['category'] \ + lbl = Gtk.Label(label='' + ACTIVITIES[category]['category'] \ + '') lbl.set_use_markup(True) hbox.pack_start(lbl, False, False, 0) @@ -402,7 +402,7 @@ class ChangeActivityDialog: vbox.pack_start(rbtns[act], False, False, 0) activities = [] - for activity in pep.ACTIVITIES[category]: + for activity in ACTIVITIES[category]: activities.append(activity) activities.sort() for activity in activities: @@ -420,7 +420,7 @@ class ChangeActivityDialog: hbox = Gtk.HBox(homogeneous=False, spacing=5) hbox.pack_start(gtkgui_helpers.load_activity_icon(category, activity), False, False, 0) - hbox.pack_start(Gtk.Label(label=pep.ACTIVITIES[category][activity]), + hbox.pack_start(Gtk.Label(label=ACTIVITIES[category][activity]), False, False, 0) rbtns[act].connect('toggled', self.on_rbtn_toggled, [category, activity]) @@ -430,8 +430,8 @@ class ChangeActivityDialog: self.default_radio = rbtns['doing_chores_other'] - if self.activity in pep.ACTIVITIES: - if not self.subactivity in pep.ACTIVITIES[self.activity]: + if self.activity in ACTIVITIES: + if not self.subactivity in ACTIVITIES[self.activity]: self.subactivity = 'other' rbtns[self.activity + '_' + self.subactivity].set_active(True) @@ -682,9 +682,9 @@ class ChangeStatusMessageDialog(TimeoutDialog): img = self.xml.get_object('activity_image') label = self.xml.get_object('activity_button_label') if 'activity' in self.pep_dict and self.pep_dict['activity'] in \ - pep.ACTIVITIES: + ACTIVITIES: if 'subactivity' in self.pep_dict and self.pep_dict['subactivity'] \ - in pep.ACTIVITIES[self.pep_dict['activity']]: + in ACTIVITIES[self.pep_dict['activity']]: img.set_from_pixbuf(gtkgui_helpers.load_activity_icon( self.pep_dict['activity'], self.pep_dict['subactivity']).\ get_pixbuf()) diff --git a/gajim/gtkgui_helpers.py b/gajim/gtkgui_helpers.py index d6b0b240c..3e9c72a47 100644 --- a/gajim/gtkgui_helpers.py +++ b/gajim/gtkgui_helpers.py @@ -52,6 +52,7 @@ from gajim.common import i18n from gajim.common import app from gajim.common import pep from gajim.common import configpaths +from gajim.common.const import PEPEventType, ACTIVITIES from gajim.filechoosers import AvatarSaveDialog gtk_icon_theme = Gtk.IconTheme.get_default() @@ -635,14 +636,13 @@ def get_pep_as_pixbuf(pep_class): 'music.png') return GdkPixbuf.Pixbuf.new_from_file(path) return icon - elif isinstance(pep_class, pep.UserActivityPEP): - assert not pep_class._retracted + elif pep_class == PEPEventType.ACTIVITY: pep_ = pep_class._pep_specific_data activity = pep_['activity'] - has_known_activity = activity in pep.ACTIVITIES + has_known_activity = activity in ACTIVITIES has_known_subactivity = (has_known_activity and ('subactivity' in pep_) - and (pep_['subactivity'] in pep.ACTIVITIES[activity])) + and (pep_['subactivity'] in ACTIVITIES[activity])) if has_known_activity: if has_known_subactivity: diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py index b99389ebb..370480e63 100644 --- a/gajim/gui_interface.py +++ b/gajim/gui_interface.py @@ -99,7 +99,7 @@ from gajim.common.connection import Connection from gajim.common.file_props import FilesProp from gajim.common import pep from gajim import emoticons -from gajim.common.const import AvatarSize, SSLError +from gajim.common.const import AvatarSize, SSLError, PEPEventType, ACTIVITIES from gajim import roster_window from gajim import profile_window @@ -2481,13 +2481,13 @@ class Interface: path = os.path.join( configpaths.get('DATA'), 'emoticons', 'static', 'music.png') return GdkPixbuf.Pixbuf.new_from_file(path) - elif isinstance(pep_obj, pep.UserActivityPEP): + elif pep_obj == PEPEventType.ACTIVITY: pep_ = pep_obj._pep_specific_data activity = pep_['activity'] - has_known_activity = activity in pep.ACTIVITIES + has_known_activity = activity in ACTIVITIES has_known_subactivity = (has_known_activity and ('subactivity' in - pep_) and (pep_['subactivity'] in pep.ACTIVITIES[activity])) + pep_) and (pep_['subactivity'] in ACTIVITIES[activity])) if has_known_activity: if has_known_subactivity: diff --git a/gajim/roster_window.py b/gajim/roster_window.py index 704625fb2..05216fe5a 100644 --- a/gajim/roster_window.py +++ b/gajim/roster_window.py @@ -2099,9 +2099,10 @@ class RosterWindow: activity = pep_dict['activity'] subactivity = pep_dict.get('subactivity', None) activity_text = pep_dict.get('activity_text', None) - connection.send_activity(activity, subactivity, activity_text) + connection.get_module('UserActivity').send_activity( + activity, subactivity, activity_text) else: - connection.retract_activity() + connection.get_module('UserActivity').retract_activity() if 'mood' in pep_dict: mood = pep_dict['mood']