diff --git a/src/core/xmpp.py b/src/core/xmpp.py index 01f66353..c8631d78 100644 --- a/src/core/xmpp.py +++ b/src/core/xmpp.py @@ -350,6 +350,9 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol): if None in statuses: # we only want string keys statuses[C.PRESENCE_STATUSES_DEFAULT] = statuses.pop(None) + if not self.host.trigger.point("presenceReceived", entity, show, priority, statuses, self.parent.profile): + return + self.host.memory.setPresenceStatus(entity, show or "", int(priority), statuses, self.parent.profile) @@ -367,11 +370,12 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol): if None in statuses: # we only want string keys statuses[C.PRESENCE_STATUSES_DEFAULT] = statuses.pop(None) - self.host.memory.setPresenceStatus(entity, "unavailable", 0, statuses, self.parent.profile) if not self.host.trigger.point("presenceReceived", entity, "unavailable", 0, statuses, self.parent.profile): return + self.host.memory.setPresenceStatus(entity, C.PRESENCE_UNAVAILABLE, 0, statuses, self.parent.profile) + # now it's time to notify frontends self.host.bridge.presenceUpdate(entity.full(), "unavailable", 0, statuses, self.parent.profile) diff --git a/src/memory/params.py b/src/memory/params.py index fd847fc3..97272636 100644 --- a/src/memory/params.py +++ b/src/memory/params.py @@ -39,7 +39,6 @@ class Params(object): """This class manage parameters with xml""" ### TODO: add desciption in params - #TODO: move Watched in a plugin #TODO: when priority is changed, a new presence stanza must be emitted #TODO: int type (Priority should be int instead of string) default_xml = u""" @@ -63,9 +62,6 @@ class Params(object): - - - """ % { diff --git a/src/plugins/plugin_misc_watched.py b/src/plugins/plugin_misc_watched.py new file mode 100755 index 00000000..00d76dc1 --- /dev/null +++ b/src/plugins/plugin_misc_watched.py @@ -0,0 +1,81 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# SàT plugin to be notified on some entities presence +# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Jérôme Poisson (goffi@goffi.org) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program 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 Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from sat.core.i18n import _, D_ +from sat.core.constants import Const as C +from sat.core.log import getLogger +log = getLogger(__name__) +from sat.core import exceptions +from sat.tools import xml_tools + + +PLUGIN_INFO = { + "name": "Watched", + "import_name": "WATCHED", + "type": "Misc", + "protocols": [], + "dependencies": [], + "main": "Watched", + "handler": "no", + "description": _("""Watch for entities presence, and send notification accordingly""") +} + + +CATEGORY = D_("Misc") +NAME = "Watched" +NOTIF = D_("Watched entity {entity} is connected") + + +class Watched(object): + params = """ + + + + + + + + """.format(category_name=CATEGORY, + category_label=_(CATEGORY), + name=NAME, + label=_(NAME), + ) + + def __init__(self, host): + log.info(_("Watched initialisation")) + self.host = host + host.memory.updateParams(self.params) + host.trigger.add("presenceReceived", self._presenceReceivedTrigger) + + def _presenceReceivedTrigger(self, entity, show, priority, statuses, profile): + if show == C.PRESENCE_UNAVAILABLE: + return True + + # we check that the previous presence was unavailable (no notification else) + try: + old_show = self.host.memory.getEntityDatum(entity, "presence", profile).show + except (KeyError, exceptions.UnknownEntityError): + old_show = C.PRESENCE_UNAVAILABLE + + if old_show == C.PRESENCE_UNAVAILABLE: + watched = self.host.memory.getParamA(NAME, CATEGORY, profile_key=profile) + if entity in watched or entity.userhostJID() in watched: + self.host.actionNew({'xmlui': xml_tools.note(_(NOTIF).format(entity=entity.full())).toXml()}, profile) + + return True diff --git a/src/plugins/plugin_sec_otr.py b/src/plugins/plugin_sec_otr.py index c05d5291..19d64f03 100644 --- a/src/plugins/plugin_sec_otr.py +++ b/src/plugins/plugin_sec_otr.py @@ -208,7 +208,7 @@ class OTR(object): host.importMenu((MAIN_MENU, D_("End session")), self._endSession, security_limit=0, help_string=D_("Finish an OTR session"), type_=C.MENU_SINGLE) host.importMenu((MAIN_MENU, D_("Authenticate")), self._authenticate, security_limit=0, help_string=D_("Authenticate user/see your fingerprint"), type_=C.MENU_SINGLE) host.importMenu((MAIN_MENU, D_("Drop private key")), self._dropPrivKey, security_limit=0, type_=C.MENU_SINGLE) - host.trigger.add("presenceReceived", self.presenceReceivedTrigger) + host.trigger.add("presenceReceived", self._presenceReceivedTrigger) def _fixPotr(self): # FIXME: potr fix for bad unicode handling @@ -472,8 +472,8 @@ class OTR(object): log.debug(u"sending message unencrypted") return True - def presenceReceivedTrigger(self, entity, show, priority, statuses, profile): - if show != "unavailable": + def _presenceReceivedTrigger(self, entity, show, priority, statuses, profile): + if show != C.PRESENCE_UNAVAILABLE: return True if not entity.resource: entity.resource = self.host.memory.getMainResource(entity, profile) # FIXME: temporary and unsecure, must be changed when frontends are refactored