[Git][gajim/gajim][master] 3 commits: Make new pep module more abstract
Philipp Hörist
gitlab at dev.gajim.org
Thu Jul 5 00:18:41 CEST 2018
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
568c2d93 by Philipp Hörist at 2018-07-05T00:16:32+02:00
Make new pep module more abstract
- - - - -
a4350a81 by Philipp Hörist at 2018-07-05T00:16:42+02:00
Refactor UserTune into own module
- - - - -
42ccbe74 by Philipp Hörist at 2018-07-05T00:16:42+02:00
Dont fail if modules are not registered
This is for Zeroconf so we dont have to test in GUI always for
account != local
Fixes #9229
- - - - -
11 changed files:
- gajim/common/connection.py
- gajim/common/connection_handlers.py
- gajim/common/const.py
- gajim/common/helpers.py
- gajim/common/modules/pep.py
- gajim/common/modules/user_activity.py
- + gajim/common/modules/user_tune.py
- gajim/common/pep.py
- gajim/gtkgui_helpers.py
- gajim/gui_interface.py
- gajim/roster_window.py
Changes:
=====================================
gajim/common/connection.py
=====================================
--- a/gajim/common/connection.py
+++ b/gajim/common/connection.py
@@ -63,6 +63,7 @@ from gajim.common import gpg
from gajim.common import passwords
from gajim.common import i18n
from gajim.common import idle
+from gajim.common.helpers import ModuleMock
from gajim.common.modules.entity_time import EntityTime
from gajim.common.modules.software_version import SoftwareVersion
from gajim.common.modules.ping import Ping
@@ -78,6 +79,7 @@ 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.modules.user_tune import UserTune
from gajim.common.connection_handlers import *
from gajim.common.contacts import GC_Contact
from gajim.gtkgui_helpers import get_action
@@ -178,7 +180,10 @@ class CommonConnection:
app.ged.raise_event(event, self.name, data)
def get_module(self, name):
- return self._modules[name]
+ try:
+ return self._modules[name]
+ except KeyError:
+ return ModuleMock()
def get_module_handlers(self):
handlers = []
@@ -670,6 +675,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.register_module('Bookmarks', Bookmarks, self)
self.register_module('UserAvatar', UserAvatar, self)
self.register_module('UserActivity', UserActivity, self)
+ self.register_module('UserTune', UserTune, self)
app.ged.register_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received)
=====================================
gajim/common/connection_handlers.py
=====================================
--- a/gajim/common/connection_handlers.py
+++ b/gajim/common/connection_handlers.py
@@ -296,7 +296,6 @@ class ConnectionPEP(object):
def reset_awaiting_pep(self):
self.to_be_sent_mood = None
- self.to_be_sent_tune = None
self.to_be_sent_nick = None
self.to_be_sent_location = None
@@ -306,8 +305,6 @@ class ConnectionPEP(object):
"""
if self.to_be_sent_mood:
self.send_mood(*self.to_be_sent_mood)
- if self.to_be_sent_tune:
- self.send_tune(*self.to_be_sent_tune)
if self.to_be_sent_nick:
self.send_nick(self.to_be_sent_nick)
if self.to_be_sent_location:
@@ -337,42 +334,6 @@ class ConnectionPEP(object):
# not all client support new XEP, so we still retract
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_MOOD, '0')
- def send_tune(self, artist='', title='', source='', track=0, length=0,
- items=None):
- if self.connected == 1:
- # We are connecting, keep tune in mem and send it when we'll be
- # connected
- self.to_be_sent_tune = (artist, title, source, track, length, items)
- return
- if not self.pep_supported:
- return
- item = nbxmpp.Node('tune', {'xmlns': nbxmpp.NS_TUNE})
- if artist:
- i = item.addChild('artist')
- i.addData(artist)
- if title:
- i = item.addChild('title')
- i.addData(title)
- if source:
- i = item.addChild('source')
- i.addData(source)
- if track:
- i = item.addChild('track')
- i.addData(track)
- if length:
- i = item.addChild('length')
- i.addData(length)
- if items:
- item.addChild(payload=items)
- self.get_module('PubSub').send_pb_publish('', nbxmpp.NS_TUNE, item, '0')
-
- def retract_tune(self):
- if not self.pep_supported:
- return
- self.send_tune(None)
- # not all client support new XEP, so we still retract
- self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_TUNE, '0')
-
def send_nickname(self, nick):
if self.connected == 1:
# We are connecting, keep nick in mem and send it when we'll be
=====================================
gajim/common/const.py
=====================================
--- a/gajim/common/const.py
+++ b/gajim/common/const.py
@@ -132,6 +132,7 @@ class PEPHandlerType(IntEnum):
@unique
class PEPEventType(IntEnum):
ACTIVITY = 0
+ TUNE = 1
ACTIVITIES = {
=====================================
gajim/common/helpers.py
=====================================
--- a/gajim/common/helpers.py
+++ b/gajim/common/helpers.py
@@ -164,6 +164,14 @@ class LocalTimezone(tzinfo):
class InvalidFormat(Exception):
pass
+
+class ModuleMock:
+ def __getattr__(self, key):
+ def _mock(self, *args, **kwargs):
+ return
+ return _mock
+
+
def decompose_jid(jidstring):
user = None
server = None
=====================================
gajim/common/modules/pep.py
=====================================
--- a/gajim/common/modules/pep.py
+++ b/gajim/common/modules/pep.py
@@ -19,6 +19,7 @@ import logging
import nbxmpp
from gajim.common import app
+from gajim.common.exceptions import StanzaMalformed
from gajim.common.nec import NetworkIncomingEvent
from gajim.common.const import PEPHandlerType, PEPEventType
@@ -46,7 +47,7 @@ class PEP:
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.store_publish:
if module_instance not in self._store_publish_modules:
self._store_publish_modules.append(module_instance)
@@ -98,29 +99,99 @@ class PEP:
module.reset_stored_publish()
-class PEPEvent:
+class AbstractPEPModule:
+ def __init__(self, con, account):
+ self._account = account
+ self._con = con
- name = ''
+ self._stored_publish = None
- def __init__(self, con, account):
- self.__account = account
- self.__con = con
+ self._con.get_module('PEP').register_pep_handler(
+ self.namespace,
+ self._pep_notify_received,
+ self._pep_retract_received)
+
+ def _pep_notify_received(self, jid, item):
+ try:
+ data = self._extract_info(item)
+ except StanzaMalformed as error:
+ log.warning('%s, %s: %s', jid, error, item)
+ return
+
+ self._log.info('Received: %s %s', jid, data)
+ self._push_event(jid, self.pep_class(data))
+
+ def _pep_retract_received(self, jid, id_):
+ self._log.info('Retract: %s %s', jid, id_)
+ self._push_event(jid, self.pep_class(None))
+
+ def _extract_info(self, item):
+ '''To be implemented by subclasses'''
+ raise NotImplementedError
+
+ def _build_node(self, data):
+ '''To be implemented by subclasses'''
+ raise NotImplementedError
+
+ 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,
+ user_pep=user_pep))
def _update_contacts(self, jid, user_pep):
- for contact in app.contacts.get_contacts(self.__account, str(jid)):
+ 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 jid == self._con.get_own_jid().getStripped():
if user_pep:
- self.__con.pep[self.name] = user_pep
+ self._con.pep[self.name] = user_pep
else:
- self.__con.pep.pop(self.name, None)
+ self._con.pep.pop(self.name, None)
+
+ def send_stored_publish(self):
+ if self._stored_publish is not None:
+ self._log.info('Send stored publish')
+ self.send(*self._stored_publish)
+ self._stored_publish = None
+
+ def reset_stored_publish(self):
+ self._log.info('Reset stored publish')
+ self._stored_publish = None
+
+ def send(self, data):
+ if not self._con.pep_supported:
+ return
+
+ if self._con.connected == 1:
+ # We are connecting, save activity and send it later
+ self._stored_publish = data
+ return
+
+ if data:
+ self._log.info('Send: %s', data)
+ else:
+ self._log.info('Remove')
+
+ item = self._build_node(data)
+
+ self._con.get_module('PubSub').send_pb_publish(
+ '', self.namespace, item, 'current')
+
+ def retract(self):
+ if not self._con.pep_supported:
+ return
+ self.send(None)
+ self._con.get_module('PubSub').send_pb_retract(
+ '', self.namespace, 'current')
-class AbstractPEP:
+class AbstractPEPData:
type_ = PEPEventType
=====================================
gajim/common/modules/user_activity.py
=====================================
--- a/gajim/common/modules/user_activity.py
+++ b/gajim/common/modules/user_activity.py
@@ -19,56 +19,57 @@ 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
+from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData
log = logging.getLogger('gajim.c.m.user_activity')
-class UserActivity(PEPEvent):
+class UserActivityData(AbstractPEPData):
- name = 'activity'
+ type_ = PEPEventType.ACTIVITY
- def __init__(self, con):
- PEPEvent.__init__(self, con, con.name)
- self._con = con
- self._account = con.name
+ def __init__(self, activity):
+ self._pep_specific_data = activity
- self.handlers = []
+ 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']
- self._stored_publish = None
+ markuptext = '<b>' + GLib.markup_escape_text(activity)
+ if subactivity:
+ markuptext += ': ' + GLib.markup_escape_text(subactivity)
+ markuptext += '</b>'
+ if text:
+ markuptext += ' (%s)' % GLib.markup_escape_text(text)
+ return markuptext
- 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
+class UserActivity(AbstractPEPModule):
- log.info('Received: %s %s', jid, activity)
- self._push_event(jid, UserActivityPEP(activity))
+ name = 'activity'
+ namespace = nbxmpp.NS_ACTIVITY
+ pep_class = UserActivityData
+ store_publish = True
+ _log = log
- def _pep_retract_received(self, jid, id_):
- log.info('Retract: %s %s', jid, id_)
- self._push_event(jid, UserActivityPEP(None))
+ def __init__(self, con):
+ AbstractPEPModule.__init__(self, con, con.name)
- 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))
+ self.handlers = []
def _extract_info(self, item):
activity_dict = {}
- activity_tag = item.getTag('activity', namespace=nbxmpp.NS_ACTIVITY)
+ activity_tag = item.getTag('activity', namespace=self.namespace)
if activity_tag is None:
raise StanzaMalformed('No activity node')
@@ -85,37 +86,9 @@ class UserActivity(PEPEvent):
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})
+ def _build_node(self, data):
+ activity, subactivity, message = data
+ item = nbxmpp.Node('activity', {'xmlns': self.namespace})
if activity:
i = item.addChild(activity)
if subactivity:
@@ -124,38 +97,3 @@ class UserActivity(PEPEvent):
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 = '<b>' + GLib.markup_escape_text(activity)
- if subactivity:
- markuptext += ': ' + GLib.markup_escape_text(subactivity)
- markuptext += '</b>'
- if text:
- markuptext += ' (%s)' % GLib.markup_escape_text(text)
- return markuptext
=====================================
gajim/common/modules/user_tune.py
=====================================
--- /dev/null
+++ b/gajim/common/modules/user_tune.py
@@ -0,0 +1,96 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# XEP-0118: User Tune
+
+import logging
+
+import nbxmpp
+from gi.repository import GLib
+
+from gajim.common.const import PEPEventType
+from gajim.common.exceptions import StanzaMalformed
+from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData
+
+log = logging.getLogger('gajim.c.m.user_tune')
+
+
+class UserTuneData(AbstractPEPData):
+
+ type_ = PEPEventType.TUNE
+
+ def __init__(self, tune):
+ self._pep_specific_data = tune
+
+ def asMarkupText(self):
+ tune = self._pep_specific_data
+
+ artist = tune.get('artist', _('Unknown Artist'))
+ artist = GLib.markup_escape_text(artist)
+
+ title = tune.get('title', _('Unknown Title'))
+ title = GLib.markup_escape_text(title)
+
+ source = tune.get('source', _('Unknown Source'))
+ source = GLib.markup_escape_text(source)
+
+ tune_string = _('<b>"%(title)s"</b> by <i>%(artist)s</i>\n'
+ 'from <i>%(source)s</i>') % {'title': title,
+ 'artist': artist,
+ 'source': source}
+ return tune_string
+
+
+class UserTune(AbstractPEPModule):
+
+ name = 'tune'
+ namespace = nbxmpp.NS_TUNE
+ pep_class = UserTuneData
+ store_publish = True
+ _log = log
+
+ def __init__(self, con):
+ AbstractPEPModule.__init__(self, con, con.name)
+
+ self.handlers = []
+
+ def _extract_info(self, item):
+ tune_dict = {}
+ tune_tag = item.getTag('tune', namespace=self.namespace)
+ if tune_tag is None:
+ raise StanzaMalformed('No activity node')
+
+ for child in tune_tag.getChildren():
+ name = child.getName().strip()
+ data = child.getData().strip()
+ if child.getName() in ['artist', 'title', 'source',
+ 'track', 'length']:
+ tune_dict[name] = data
+
+ return tune_dict or None
+
+ def _build_node(self, data):
+ artist, title, source, track, length = data
+ item = nbxmpp.Node('tune', {'xmlns': nbxmpp.NS_TUNE})
+ if artist:
+ item.addChild('artist', payload=artist)
+ if title:
+ item.addChild('title', payload=title)
+ if source:
+ item.addChild('source', payload=source)
+ if track:
+ item.addChild('track', payload=track)
+ if length:
+ item.addChild('length', payload=length)
+ return item
=====================================
gajim/common/pep.py
=====================================
--- a/gajim/common/pep.py
+++ b/gajim/common/pep.py
@@ -109,8 +109,6 @@ MOODS = {
'weak': _('Weak'),
'worried': _('Worried')}
-TUNE_DATA = ['artist', 'title', 'source', 'track', 'length']
-
LOCATION_DATA = {
'accuracy': _('accuracy'),
'alt': _('alt'),
@@ -234,47 +232,6 @@ class UserMoodPEP(AbstractPEP):
return mood
-class UserTunePEP(AbstractPEP):
- '''XEP-0118: User Tune'''
-
- type_ = 'tune'
- namespace = nbxmpp.NS_TUNE
-
- def _extract_info(self, items):
- tune_dict = {}
-
- for item in items.getTags('item'):
- tune_tag = item.getTag('tune')
- if tune_tag:
- for child in tune_tag.getChildren():
- name = child.getName().strip()
- data = child.getData().strip()
- if child.getName() in TUNE_DATA:
- tune_dict[name] = data
-
- retracted = items.getTag('retract') or not ('artist' in tune_dict or
- 'title' in tune_dict)
- return (tune_dict, retracted)
-
- def asMarkupText(self):
- assert not self._retracted
- tune = self._pep_specific_data
-
- artist = tune.get('artist', _('Unknown Artist'))
- artist = GLib.markup_escape_text(artist)
-
- title = tune.get('title', _('Unknown Title'))
- title = GLib.markup_escape_text(title)
-
- source = tune.get('source', _('Unknown Source'))
- source = GLib.markup_escape_text(source)
-
- tune_string = _('<b>"%(title)s"</b> by <i>%(artist)s</i>\n'
- 'from <i>%(source)s</i>') % {'title': title,
- 'artist': artist, 'source': source}
- return tune_string
-
-
class UserNicknamePEP(AbstractPEP):
'''XEP-0172: User Nickname'''
@@ -390,5 +347,5 @@ class AvatarNotificationPEP(AbstractPEP):
SUPPORTED_PERSONAL_USER_EVENTS = [
- UserMoodPEP, UserTunePEP,
+ UserMoodPEP,
UserNicknamePEP, UserLocationPEP, AvatarNotificationPEP]
=====================================
gajim/gtkgui_helpers.py
=====================================
--- a/gajim/gtkgui_helpers.py
+++ b/gajim/gtkgui_helpers.py
@@ -629,7 +629,7 @@ def get_pep_as_pixbuf(pep_class):
mood = received_mood if received_mood in pep.MOODS else 'unknown'
pixbuf = load_mood_icon(mood).get_pixbuf()
return pixbuf
- elif isinstance(pep_class, pep.UserTunePEP):
+ elif pep_class == PEPEventType.TUNE:
icon = get_icon_pixmap('audio-x-generic', quiet=True)
if not icon:
path = os.path.join(configpaths.get('DATA'), 'emoticons', 'static',
=====================================
gajim/gui_interface.py
=====================================
--- a/gajim/gui_interface.py
+++ b/gajim/gui_interface.py
@@ -2169,7 +2169,8 @@ class Interface:
continue
if app.connections[acct].music_track_info == music_track_info:
continue
- app.connections[acct].send_tune(artist, title, source)
+ app.connections[acct].get_module('UserTune').send(
+ (artist, title, source, None, None))
app.connections[acct].music_track_info = music_track_info
def read_sleepy(self):
@@ -2477,7 +2478,7 @@ class Interface:
received_mood = pep_obj._pep_specific_data['mood']
mood = received_mood if received_mood in pep.MOODS else 'unknown'
return gtkgui_helpers.load_mood_icon(mood).get_pixbuf()
- elif isinstance(pep_obj, pep.UserTunePEP):
+ elif pep_obj == PEPEventType.TUNE:
path = os.path.join(
configpaths.get('DATA'), 'emoticons', 'static', 'music.png')
return GdkPixbuf.Pixbuf.new_from_file(path)
=====================================
gajim/roster_window.py
=====================================
--- a/gajim/roster_window.py
+++ b/gajim/roster_window.py
@@ -2099,10 +2099,10 @@ class RosterWindow:
activity = pep_dict['activity']
subactivity = pep_dict.get('subactivity', None)
activity_text = pep_dict.get('activity_text', None)
- connection.get_module('UserActivity').send_activity(
- activity, subactivity, activity_text)
+ connection.get_module('UserActivity').send(
+ (activity, subactivity, activity_text))
else:
- connection.get_module('UserActivity').retract_activity()
+ connection.get_module('UserActivity').retract()
if 'mood' in pep_dict:
mood = pep_dict['mood']
@@ -3594,7 +3594,7 @@ class RosterWindow:
if active:
app.interface.enable_music_listener()
else:
- app.connections[account].retract_tune()
+ app.connections[account].get_module('UserTune').retract()
# disable music listener only if no other account uses it
for acc in app.connections:
if app.config.get_per('accounts', acc, 'publish_tune'):
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/b7775afd0c31912f7dc9541770523d08cd80e77f...42ccbe7499b415be63be2c591afdad4587af68a1
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/b7775afd0c31912f7dc9541770523d08cd80e77f...42ccbe7499b415be63be2c591afdad4587af68a1
You're receiving this email because of your account on dev.gajim.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gajim.org/pipermail/commits/attachments/20180705/a13a1da5/attachment-0001.html>
More information about the Commits
mailing list