Make new pep module more abstract

This commit is contained in:
Philipp Hörist 2018-07-04 22:55:16 +02:00
parent b7775afd0c
commit 568c2d93a0
3 changed files with 133 additions and 124 deletions

View File

@ -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:
name = ''
class AbstractPEPModule:
def __init__(self, con, account):
self.__account = account
self.__con = con
self._account = account
self._con = con
self._stored_publish = None
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

View File

@ -19,121 +19,14 @@ 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):
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):
class UserActivityData(AbstractPEPData):
type_ = PEPEventType.ACTIVITY
@ -159,3 +52,48 @@ class UserActivityPEP(AbstractPEP):
if text:
markuptext += ' (%s)' % GLib.markup_escape_text(text)
return markuptext
class UserActivity(AbstractPEPModule):
name = 'activity'
namespace = nbxmpp.NS_ACTIVITY
pep_class = UserActivityData
store_publish = True
_log = log
def __init__(self, con):
AbstractPEPModule.__init__(self, con, con.name)
self.handlers = []
def _extract_info(self, item):
activity_dict = {}
activity_tag = item.getTag('activity', namespace=self.namespace)
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 _build_node(self, data):
activity, subactivity, message = data
item = nbxmpp.Node('activity', {'xmlns': self.namespace})
if activity:
i = item.addChild(activity)
if subactivity:
i.addChild(subactivity)
if message:
i = item.addChild('text')
i.addData(message)
return item

View File

@ -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']