comparison sat/plugins/plugin_xep_0334.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 003b8b4b56a7
children 9d0df638c8b4
comparison
equal deleted inserted replaced
3027:ff5bcb12ae60 3028:ab2696e34d29
1 #!/usr/bin/env python2 1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 3
4 # SAT plugin for Delayed Delivery (XEP-0334) 4 # SAT plugin for Delayed Delivery (XEP-0334)
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) 5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org)
6 # Copyright (C) 2013-2016 Adrien Cossa (souliane@mailoo.org) 6 # Copyright (C) 2013-2016 Adrien Cossa (souliane@mailoo.org)
27 from sat.tools.common import data_format 27 from sat.tools.common import data_format
28 28
29 from wokkel import disco, iwokkel 29 from wokkel import disco, iwokkel
30 30
31 from twisted.words.protocols.jabber import xmlstream 31 from twisted.words.protocols.jabber import xmlstream
32 from zope.interface import implements 32 from zope.interface import implementer
33 from textwrap import dedent 33 from textwrap import dedent
34 34
35 35
36 PLUGIN_INFO = { 36 PLUGIN_INFO = {
37 C.PI_NAME: u"Message Processing Hints", 37 C.PI_NAME: "Message Processing Hints",
38 C.PI_IMPORT_NAME: u"XEP-0334", 38 C.PI_IMPORT_NAME: "XEP-0334",
39 C.PI_TYPE: u"XEP", 39 C.PI_TYPE: "XEP",
40 C.PI_PROTOCOLS: [u"XEP-0334"], 40 C.PI_PROTOCOLS: ["XEP-0334"],
41 C.PI_MAIN: "XEP_0334", 41 C.PI_MAIN: "XEP_0334",
42 C.PI_HANDLER: u"yes", 42 C.PI_HANDLER: "yes",
43 C.PI_DESCRIPTION: D_(u"""Implementation of Message Processing Hints"""), 43 C.PI_DESCRIPTION: D_("""Implementation of Message Processing Hints"""),
44 C.PI_USAGE: dedent( 44 C.PI_USAGE: dedent(
45 D_( 45 D_(
46 u"""\ 46 """\
47 Frontends can use HINT_* constants in mess_data['extra'] in a serialized 'hints' dict. 47 Frontends can use HINT_* constants in mess_data['extra'] in a serialized 'hints' dict.
48 Internal plugins can use directly addHint([HINT_* constant]). 48 Internal plugins can use directly addHint([HINT_* constant]).
49 Will set mess_data['extra']['history'] to 'skipped' when no store is requested and message is not saved in history.""" 49 Will set mess_data['extra']['history'] to 'skipped' when no store is requested and message is not saved in history."""
50 ) 50 )
51 ), 51 ),
52 } 52 }
53 53
54 NS_HINTS = u"urn:xmpp:hints" 54 NS_HINTS = "urn:xmpp:hints"
55 55
56 56
57 class XEP_0334(object): 57 class XEP_0334(object):
58 HINT_NO_PERMANENT_STORE = u"no-permanent-store" 58 HINT_NO_PERMANENT_STORE = "no-permanent-store"
59 HINT_NO_STORE = u"no-store" 59 HINT_NO_STORE = "no-store"
60 HINT_NO_COPY = u"no-copy" 60 HINT_NO_COPY = "no-copy"
61 HINT_STORE = u"store" 61 HINT_STORE = "store"
62 HINTS = (HINT_NO_PERMANENT_STORE, HINT_NO_STORE, HINT_NO_COPY, HINT_STORE) 62 HINTS = (HINT_NO_PERMANENT_STORE, HINT_NO_STORE, HINT_NO_COPY, HINT_STORE)
63 63
64 def __init__(self, host): 64 def __init__(self, host):
65 log.info(_("Message Processing Hints plugin initialization")) 65 log.info(_("Message Processing Hints plugin initialization"))
66 self.host = host 66 self.host = host
71 return XEP_0334_handler() 71 return XEP_0334_handler()
72 72
73 def addHint(self, mess_data, hint): 73 def addHint(self, mess_data, hint):
74 if hint == self.HINT_NO_COPY and not mess_data["to"].resource: 74 if hint == self.HINT_NO_COPY and not mess_data["to"].resource:
75 log.error( 75 log.error(
76 u"{hint} can only be used with full jids! Ignoring it.".format(hint=hint) 76 "{hint} can only be used with full jids! Ignoring it.".format(hint=hint)
77 ) 77 )
78 return 78 return
79 hints = mess_data.setdefault("hints", set()) 79 hints = mess_data.setdefault("hints", set())
80 if hint in self.HINTS: 80 if hint in self.HINTS:
81 hints.add(hint) 81 hints.add(hint)
82 else: 82 else:
83 log.error(u"Unknown hint: {}".format(hint)) 83 log.error("Unknown hint: {}".format(hint))
84 84
85 def addHintElements(self, message_elt, hints): 85 def addHintElements(self, message_elt, hints):
86 """Add hints elements to message stanza 86 """Add hints elements to message stanza
87 87
88 @param message_elt(domish.Element): stanza where hints must be added 88 @param message_elt(domish.Element): stanza where hints must be added
91 for hint in hints: 91 for hint in hints:
92 message_elt.addElement((NS_HINTS, hint)) 92 message_elt.addElement((NS_HINTS, hint))
93 93
94 def _sendPostXmlTreatment(self, mess_data): 94 def _sendPostXmlTreatment(self, mess_data):
95 if "hints" in mess_data: 95 if "hints" in mess_data:
96 self.addHintElements(mess_data[u"xml"], mess_data[u"hints"]) 96 self.addHintElements(mess_data["xml"], mess_data["hints"])
97 return mess_data 97 return mess_data
98 98
99 def sendMessageTrigger( 99 def sendMessageTrigger(
100 self, client, mess_data, pre_xml_treatments, post_xml_treatments 100 self, client, mess_data, pre_xml_treatments, post_xml_treatments
101 ): 101 ):
102 """Add the hints element to the message to be sent""" 102 """Add the hints element to the message to be sent"""
103 if u"hints" in mess_data[u"extra"]: 103 if "hints" in mess_data["extra"]:
104 for hint in data_format.dict2iter(u"hints", mess_data[u"extra"], pop=True): 104 for hint in data_format.dict2iter("hints", mess_data["extra"], pop=True):
105 self.addHint(hint) 105 self.addHint(hint)
106 106
107 post_xml_treatments.addCallback(self._sendPostXmlTreatment) 107 post_xml_treatments.addCallback(self._sendPostXmlTreatment)
108 return True 108 return True
109 109
110 def _receivedSkipHistory(self, mess_data): 110 def _receivedSkipHistory(self, mess_data):
111 mess_data[u"history"] = C.HISTORY_SKIP 111 mess_data["history"] = C.HISTORY_SKIP
112 return mess_data 112 return mess_data
113 113
114 def messageReceivedTrigger(self, client, message_elt, post_treat): 114 def messageReceivedTrigger(self, client, message_elt, post_treat):
115 """Check for hints in the received message""" 115 """Check for hints in the received message"""
116 for elt in message_elt.elements(): 116 for elt in message_elt.elements():
117 if elt.uri == NS_HINTS and elt.name in ( 117 if elt.uri == NS_HINTS and elt.name in (
118 self.HINT_NO_PERMANENT_STORE, 118 self.HINT_NO_PERMANENT_STORE,
119 self.HINT_NO_STORE, 119 self.HINT_NO_STORE,
120 ): 120 ):
121 log.debug(u"history will be skipped for this message, as requested") 121 log.debug("history will be skipped for this message, as requested")
122 post_treat.addCallback(self._receivedSkipHistory) 122 post_treat.addCallback(self._receivedSkipHistory)
123 break 123 break
124 return True 124 return True
125 125
126 126
127 @implementer(iwokkel.IDisco)
127 class XEP_0334_handler(xmlstream.XMPPHandler): 128 class XEP_0334_handler(xmlstream.XMPPHandler):
128 implements(iwokkel.IDisco)
129 129
130 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): 130 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
131 return [disco.DiscoFeature(NS_HINTS)] 131 return [disco.DiscoFeature(NS_HINTS)]
132 132
133 def getDiscoItems(self, requestor, target, nodeIdentifier=""): 133 def getDiscoItems(self, requestor, target, nodeIdentifier=""):