comparison sat/plugins/plugin_exp_list_of_interest.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 ef554aca3eb1
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 to detect language (experimental) 4 # SAT plugin to detect language (experimental)
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 6
19 19
20 from sat.core.i18n import _ 20 from sat.core.i18n import _
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from sat.core.log import getLogger 22 from sat.core.log import getLogger
23 from wokkel import disco, iwokkel, pubsub 23 from wokkel import disco, iwokkel, pubsub
24 from zope.interface import implements 24 from zope.interface import implementer
25 from twisted.internet import defer 25 from twisted.internet import defer
26 from twisted.words.protocols.jabber import error as jabber_error, jid 26 from twisted.words.protocols.jabber import error as jabber_error, jid
27 from twisted.words.protocols.jabber.xmlstream import XMPPHandler 27 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
28 from twisted.words.xish import domish 28 from twisted.words.xish import domish
29 29
33 PLUGIN_INFO = { 33 PLUGIN_INFO = {
34 C.PI_NAME: "List of Interest", 34 C.PI_NAME: "List of Interest",
35 C.PI_IMPORT_NAME: "LIST_INTEREST", 35 C.PI_IMPORT_NAME: "LIST_INTEREST",
36 C.PI_TYPE: "EXP", 36 C.PI_TYPE: "EXP",
37 C.PI_PROTOCOLS: [], 37 C.PI_PROTOCOLS: [],
38 C.PI_DEPENDENCIES: [u"XEP-0060", u"XEP-0329"], 38 C.PI_DEPENDENCIES: ["XEP-0060", "XEP-0329"],
39 C.PI_RECOMMENDATIONS: [], 39 C.PI_RECOMMENDATIONS: [],
40 C.PI_MAIN: "ListInterest", 40 C.PI_MAIN: "ListInterest",
41 C.PI_HANDLER: "yes", 41 C.PI_HANDLER: "yes",
42 C.PI_DESCRIPTION: _(u"Experimental handling of interesting XMPP locations"), 42 C.PI_DESCRIPTION: _("Experimental handling of interesting XMPP locations"),
43 } 43 }
44 44
45 NS_LIST_INTEREST = "https://salut-a-toi/protocol/list-interest:0" 45 NS_LIST_INTEREST = "https://salut-a-toi/protocol/list-interest:0"
46 46
47 47
48 class ListInterest(object): 48 class ListInterest(object):
49 namespace = NS_LIST_INTEREST 49 namespace = NS_LIST_INTEREST
50 50
51 def __init__(self, host): 51 def __init__(self, host):
52 log.info(_(u"List of Interest plugin initialization")) 52 log.info(_("List of Interest plugin initialization"))
53 self.host = host 53 self.host = host
54 self._p = self.host.plugins["XEP-0060"] 54 self._p = self.host.plugins["XEP-0060"]
55 host.bridge.addMethod( 55 host.bridge.addMethod(
56 "interestsList", 56 "interestsList",
57 ".plugin", 57 ".plugin",
58 in_sign="ssss", 58 in_sign="ssss",
59 out_sign="aa{ss}", 59 out_sign="aa{ss}",
60 method=self._listInterests, 60 method=self._listInterests,
61 async=True, 61 async_=True,
62 ) 62 )
63 63
64 def getHandler(self, client): 64 def getHandler(self, client):
65 return ListInterestHandler(self) 65 return ListInterestHandler(self)
66 66
74 client.jid.userhostJID(), 74 client.jid.userhostJID(),
75 nodeIdentifier=NS_LIST_INTEREST, 75 nodeIdentifier=NS_LIST_INTEREST,
76 options=options, 76 options=options,
77 ) 77 )
78 except jabber_error.StanzaError as e: 78 except jabber_error.StanzaError as e:
79 if e.condition == u"conflict": 79 if e.condition == "conflict":
80 log.debug(_(u"requested node already exists")) 80 log.debug(_("requested node already exists"))
81 81
82 @defer.inlineCallbacks 82 @defer.inlineCallbacks
83 def registerPubsub(self, client, namespace, service, node, item_id=None, 83 def registerPubsub(self, client, namespace, service, node, item_id=None,
84 creator=False, name=None, element=None, extra=None): 84 creator=False, name=None, element=None, extra=None):
85 """Register an interesting element in personal list 85 """Register an interesting element in personal list
99 - thumb_url: http(s) URL of a thumbnail 99 - thumb_url: http(s) URL of a thumbnail
100 """ 100 """
101 if extra is None: 101 if extra is None:
102 extra = {} 102 extra = {}
103 yield self.createNode(client) 103 yield self.createNode(client)
104 interest_elt = domish.Element((NS_LIST_INTEREST, u"interest")) 104 interest_elt = domish.Element((NS_LIST_INTEREST, "interest"))
105 interest_elt[u"namespace"] = namespace 105 interest_elt["namespace"] = namespace
106 if name is not None: 106 if name is not None:
107 interest_elt[u'name'] = name 107 interest_elt['name'] = name
108 thumb_url = extra.get(u'thumb_url') 108 thumb_url = extra.get('thumb_url')
109 if thumb_url: 109 if thumb_url:
110 interest_elt[u'thumb_url'] = thumb_url 110 interest_elt['thumb_url'] = thumb_url
111 pubsub_elt = interest_elt.addElement(u"pubsub") 111 pubsub_elt = interest_elt.addElement("pubsub")
112 pubsub_elt[u"service"] = service.full() 112 pubsub_elt["service"] = service.full()
113 pubsub_elt[u"node"] = node 113 pubsub_elt["node"] = node
114 if item_id is not None: 114 if item_id is not None:
115 pubsub_elt[u"item"] = item_id 115 pubsub_elt["item"] = item_id
116 if creator: 116 if creator:
117 pubsub_elt[u"creator"] = C.BOOL_TRUE 117 pubsub_elt["creator"] = C.BOOL_TRUE
118 if element is not None: 118 if element is not None:
119 pubsub_elt.addChild(element) 119 pubsub_elt.addChild(element)
120 item_elt = pubsub.Item(payload=interest_elt) 120 item_elt = pubsub.Item(payload=interest_elt)
121 yield self._p.publish( 121 yield self._p.publish(
122 client, client.jid.userhostJID(), NS_LIST_INTEREST, items=[item_elt] 122 client, client.jid.userhostJID(), NS_LIST_INTEREST, items=[item_elt]
136 @param extra(dict, None): as ad for [registerPubsub] 136 @param extra(dict, None): as ad for [registerPubsub]
137 """ 137 """
138 if extra is None: 138 if extra is None:
139 extra = {} 139 extra = {}
140 yield self.createNode(client) 140 yield self.createNode(client)
141 interest_elt = domish.Element((NS_LIST_INTEREST, u"interest")) 141 interest_elt = domish.Element((NS_LIST_INTEREST, "interest"))
142 interest_elt[u"namespace"] = self.host.getNamespace(u"fis") 142 interest_elt["namespace"] = self.host.getNamespace("fis")
143 if name is not None: 143 if name is not None:
144 interest_elt[u'name'] = name 144 interest_elt['name'] = name
145 thumb_url = extra.get(u'thumb_url') 145 thumb_url = extra.get('thumb_url')
146 if thumb_url: 146 if thumb_url:
147 interest_elt[u'thumb_url'] = thumb_url 147 interest_elt['thumb_url'] = thumb_url
148 file_sharing_elt = interest_elt.addElement(u"file_sharing") 148 file_sharing_elt = interest_elt.addElement("file_sharing")
149 file_sharing_elt[u"service"] = service.full() 149 file_sharing_elt["service"] = service.full()
150 if repos_type is not None: 150 if repos_type is not None:
151 file_sharing_elt[u"type"] = repos_type 151 file_sharing_elt["type"] = repos_type
152 if namespace is not None: 152 if namespace is not None:
153 file_sharing_elt[u"namespace"] = namespace 153 file_sharing_elt["namespace"] = namespace
154 if path is not None: 154 if path is not None:
155 file_sharing_elt[u"path"] = path 155 file_sharing_elt["path"] = path
156 item_elt = pubsub.Item(payload=interest_elt) 156 item_elt = pubsub.Item(payload=interest_elt)
157 yield self._p.publish( 157 yield self._p.publish(
158 client, client.jid.userhostJID(), NS_LIST_INTEREST, items=[item_elt] 158 client, client.jid.userhostJID(), NS_LIST_INTEREST, items=[item_elt]
159 ) 159 )
160 160
161 def _listInterestsSerialise(self, interests_data): 161 def _listInterestsSerialise(self, interests_data):
162 interests = [] 162 interests = []
163 for item_elt in interests_data[0]: 163 for item_elt in interests_data[0]:
164 interest_data = {} 164 interest_data = {}
165 interest_elt = item_elt.interest 165 interest_elt = item_elt.interest
166 if interest_elt.hasAttribute(u'namespace'): 166 if interest_elt.hasAttribute('namespace'):
167 interest_data[u'namespace'] = interest_elt.getAttribute(u'namespace') 167 interest_data['namespace'] = interest_elt.getAttribute('namespace')
168 if interest_elt.hasAttribute(u'name'): 168 if interest_elt.hasAttribute('name'):
169 interest_data[u'name'] = interest_elt.getAttribute(u'name') 169 interest_data['name'] = interest_elt.getAttribute('name')
170 if interest_elt.hasAttribute(u'thumb_url'): 170 if interest_elt.hasAttribute('thumb_url'):
171 interest_data[u'thumb_url'] = interest_elt.getAttribute(u'thumb_url') 171 interest_data['thumb_url'] = interest_elt.getAttribute('thumb_url')
172 elt = interest_elt.firstChildElement() 172 elt = interest_elt.firstChildElement()
173 if elt.uri != NS_LIST_INTEREST: 173 if elt.uri != NS_LIST_INTEREST:
174 log.warning(u"unexpected child element, ignoring: {xml}".format( 174 log.warning("unexpected child element, ignoring: {xml}".format(
175 xml = elt.toXml())) 175 xml = elt.toXml()))
176 continue 176 continue
177 if elt.name == u'pubsub': 177 if elt.name == 'pubsub':
178 interest_data.update({ 178 interest_data.update({
179 u"type": u"pubsub", 179 "type": "pubsub",
180 u"service": elt[u'service'], 180 "service": elt['service'],
181 u"node": elt[u'node'], 181 "node": elt['node'],
182 }) 182 })
183 for attr in (u'item', u'creator'): 183 for attr in ('item', 'creator'):
184 if elt.hasAttribute(attr): 184 if elt.hasAttribute(attr):
185 interest_data[attr] = elt[attr] 185 interest_data[attr] = elt[attr]
186 elif elt.name == u'file_sharing': 186 elif elt.name == 'file_sharing':
187 interest_data.update({ 187 interest_data.update({
188 u"type": u"file_sharing", 188 "type": "file_sharing",
189 u"service": elt[u'service'], 189 "service": elt['service'],
190 }) 190 })
191 if elt.hasAttribute(u'type'): 191 if elt.hasAttribute('type'):
192 interest_data[u'subtype'] = elt[u'type'] 192 interest_data['subtype'] = elt['type']
193 for attr in (u'namespace', u'path'): 193 for attr in ('namespace', 'path'):
194 if elt.hasAttribute(attr): 194 if elt.hasAttribute(attr):
195 interest_data[attr] = elt[attr] 195 interest_data[attr] = elt[attr]
196 else: 196 else:
197 log.warning(u"unknown element, ignoring: {xml}".format(xml=elt.toXml())) 197 log.warning("unknown element, ignoring: {xml}".format(xml=elt.toXml()))
198 continue 198 continue
199 interests.append(interest_data) 199 interests.append(interest_data)
200 200
201 return interests 201 return interests
202 202
227 items, metadata = yield self._p.getItems(client, service, node) 227 items, metadata = yield self._p.getItems(client, service, node)
228 if namespace is not None: 228 if namespace is not None:
229 filtered_items = [] 229 filtered_items = []
230 for item in items: 230 for item in items:
231 try: 231 try:
232 interest_elt = next(item.elements(NS_LIST_INTEREST, u"interest")) 232 interest_elt = next(item.elements(NS_LIST_INTEREST, "interest"))
233 except StopIteration: 233 except StopIteration:
234 log.warning(_(u"Missing interest element: {xml}").format( 234 log.warning(_("Missing interest element: {xml}").format(
235 xml=interest_elt.toXml())) 235 xml=interest_elt.toXml()))
236 continue 236 continue
237 if interest_elt.getAttribute(u"namespace") == namespace: 237 if interest_elt.getAttribute("namespace") == namespace:
238 filtered_items.append(item) 238 filtered_items.append(item)
239 items = filtered_items 239 items = filtered_items
240 240
241 defer.returnValue((items, metadata)) 241 defer.returnValue((items, metadata))
242 242
243 243
244 @implementer(iwokkel.IDisco)
244 class ListInterestHandler(XMPPHandler): 245 class ListInterestHandler(XMPPHandler):
245 implements(iwokkel.IDisco)
246 246
247 def __init__(self, plugin_parent): 247 def __init__(self, plugin_parent):
248 self.plugin_parent = plugin_parent 248 self.plugin_parent = plugin_parent
249 249
250 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): 250 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):