comparison sat/plugins/plugin_xep_0334.py @ 2562:26edcf3a30eb

core, setup: huge cleaning: - moved directories from src and frontends/src to sat and sat_frontends, which is the recommanded naming convention - move twisted directory to root - removed all hacks from setup.py, and added missing dependencies, it is now clean - use https URL for website in setup.py - removed "Environment :: X11 Applications :: GTK", as wix is deprecated and removed - renamed sat.sh to sat and fixed its installation - added python_requires to specify Python version needed - replaced glib2reactor which use deprecated code by gtk3reactor sat can now be installed directly from virtualenv without using --system-site-packages anymore \o/
author Goffi <goffi@goffi.org>
date Mon, 02 Apr 2018 19:44:50 +0200
parents src/plugins/plugin_xep_0334.py@0046283a285d
children 56f94936df1e
comparison
equal deleted inserted replaced
2561:bd30dc3ffe5a 2562:26edcf3a30eb
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3
4 # SAT plugin for Delayed Delivery (XEP-0334)
5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org)
6 # Copyright (C) 2013-2016 Adrien Cossa (souliane@mailoo.org)
7
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Affero General Public License for more details.
17
18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21 from sat.core.i18n import _, D_
22 from sat.core.log import getLogger
23 log = getLogger(__name__)
24 from sat.core.constants import Const as C
25
26 from sat.tools.common import data_format
27
28 from wokkel import disco, iwokkel
29 try:
30 from twisted.words.protocols.xmlstream import XMPPHandler
31 except ImportError:
32 from wokkel.subprotocols import XMPPHandler
33 from zope.interface import implements
34 from textwrap import dedent
35
36
37 PLUGIN_INFO = {
38 C.PI_NAME: u"Message Processing Hints",
39 C.PI_IMPORT_NAME: u"XEP-0334",
40 C.PI_TYPE: u"XEP",
41 C.PI_PROTOCOLS: [u"XEP-0334"],
42 C.PI_MAIN: "XEP_0334",
43 C.PI_HANDLER: u"yes",
44 C.PI_DESCRIPTION: D_(u"""Implementation of Message Processing Hints"""),
45 C.PI_USAGE: dedent(D_(u"""\
46 Frontends can use HINT_* constants in mess_data['extra'] in a serialized 'hints' dict.
47 Internal plugins can use directly addHint([HINT_* constant]).
48 Will set mess_data['extra']['history'] to 'skipped' when no store is requested and message is not saved in history."""))
49
50 }
51
52 NS_HINTS = u'urn:xmpp:hints'
53
54
55 class XEP_0334(object):
56 HINT_NO_PERMANENT_STORE = u'no-permanent-store'
57 HINT_NO_STORE = u'no-store'
58 HINT_NO_COPY = u'no-copy'
59 HINT_STORE = u'store'
60 HINTS = (HINT_NO_PERMANENT_STORE, HINT_NO_STORE, HINT_NO_COPY, HINT_STORE)
61
62 def __init__(self, host):
63 log.info(_("Message Processing Hints plugin initialization"))
64 self.host = host
65 host.trigger.add("sendMessage", self.sendMessageTrigger)
66 host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=-1000)
67
68 def getHandler(self, client):
69 return XEP_0334_handler()
70
71 def addHint(self, mess_data, hint):
72 if hint == self.HINT_NO_COPY and not mess_data['to'].resource:
73 log.error(u"{hint} can only be used with full jids! Ignoring it.".format(hint=hint))
74 return
75 hints = mess_data.setdefault('hints', set())
76 if hint in self.HINTS:
77 hints.add(hint)
78 else:
79 log.error(u"Unknown hint: {}".format(hint))
80
81 def _sendPostXmlTreatment(self, mess_data):
82 if 'hints' in mess_data:
83 for hint in mess_data['hints']:
84 mess_data[u'xml'].addElement((NS_HINTS, hint))
85 return mess_data
86
87 def sendMessageTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments):
88 """Add the hints element to the message to be sent"""
89 if u'hints' in mess_data[u'extra']:
90 for hint in data_format.dict2iter(u'hints', mess_data[u'extra'], pop=True):
91 self.addHint(hint)
92
93 post_xml_treatments.addCallback(self._sendPostXmlTreatment)
94 return True
95
96 def _receivedSkipHistory(self, mess_data):
97 mess_data[u'history'] = C.HISTORY_SKIP
98 return mess_data
99
100 def messageReceivedTrigger(self, client, message_elt, post_treat):
101 """Check for hints in the received message"""
102 for elt in message_elt.elements():
103 if elt.uri == NS_HINTS and elt.name in (self.HINT_NO_PERMANENT_STORE, self.HINT_NO_STORE):
104 log.debug(u"history will be skipped for this message, as requested")
105 post_treat.addCallback(self._receivedSkipHistory)
106 break
107 return True
108
109
110 class XEP_0334_handler(XMPPHandler):
111 implements(iwokkel.IDisco)
112
113 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
114 return [disco.DiscoFeature(NS_HINTS)]
115
116 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
117 return []