comparison sat/plugins/plugin_xep_0249.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 6acaa8244220
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 managing xep-0249 4 # SAT plugin for managing xep-0249
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
25 log = getLogger(__name__) 25 log = getLogger(__name__)
26 from sat.tools import xml_tools 26 from sat.tools import xml_tools
27 from twisted.words.xish import domish 27 from twisted.words.xish import domish
28 from twisted.words.protocols.jabber import jid 28 from twisted.words.protocols.jabber import jid
29 29
30 from zope.interface import implements 30 from zope.interface import implementer
31 31
32 from wokkel import disco, iwokkel 32 from wokkel import disco, iwokkel
33 33
34 34
35 try: 35 try:
120 """ 120 """
121 message = domish.Element((None, "message")) 121 message = domish.Element((None, "message"))
122 message["to"] = guest.full() 122 message["to"] = guest.full()
123 x_elt = message.addElement((NS_X_CONFERENCE, "x")) 123 x_elt = message.addElement((NS_X_CONFERENCE, "x"))
124 x_elt["jid"] = room.userhost() 124 x_elt["jid"] = room.userhost()
125 for key, value in options.iteritems(): 125 for key, value in options.items():
126 if key not in ("password", "reason", "thread"): 126 if key not in ("password", "reason", "thread"):
127 log.warning(u"Ignoring invalid invite option: {}".format(key)) 127 log.warning("Ignoring invalid invite option: {}".format(key))
128 continue 128 continue
129 x_elt[key] = value 129 x_elt[key] = value
130 #  there is not body in this message, so we can use directly send() 130 #  there is not body in this message, so we can use directly send()
131 client.send(message) 131 client.send(message)
132 132
135 135
136 @param room (jid.JID): JID of the room 136 @param room (jid.JID): JID of the room
137 """ 137 """
138 client = self.host.getClient(profile_key) 138 client = self.host.getClient(profile_key)
139 log.info( 139 log.info(
140 _(u"Invitation accepted for room %(room)s [%(profile)s]") 140 _("Invitation accepted for room %(room)s [%(profile)s]")
141 % {"room": room_jid.userhost(), "profile": client.profile} 141 % {"room": room_jid.userhost(), "profile": client.profile}
142 ) 142 )
143 d = self.host.plugins["XEP-0045"].join(client, room_jid, client.jid.user, {}) 143 d = self.host.plugins["XEP-0045"].join(client, room_jid, client.jid.user, {})
144 return d 144 return d
145 145
148 x_elt = next(message_elt.elements(NS_X_CONFERENCE, 'x'), None) 148 x_elt = next(message_elt.elements(NS_X_CONFERENCE, 'x'), None)
149 if x_elt is None: 149 if x_elt is None:
150 return True 150 return True
151 151
152 try: 152 try:
153 room_jid_s = x_elt[u"jid"] 153 room_jid_s = x_elt["jid"]
154 except KeyError: 154 except KeyError:
155 log.warning(_(u"invalid invitation received: {xml}").format( 155 log.warning(_("invalid invitation received: {xml}").format(
156 xml=message_elt.toXml())) 156 xml=message_elt.toXml()))
157 return False 157 return False
158 log.info( 158 log.info(
159 _(u"Invitation received for room %(room)s [%(profile)s]") 159 _("Invitation received for room %(room)s [%(profile)s]")
160 % {"room": room_jid_s, "profile": client.profile} 160 % {"room": room_jid_s, "profile": client.profile}
161 ) 161 )
162 from_jid_s = message_elt["from"] 162 from_jid_s = message_elt["from"]
163 room_jid = jid.JID(room_jid_s) 163 room_jid = jid.JID(room_jid_s)
164 try: 164 try:
165 self.host.plugins["XEP-0045"].checkRoomJoined(client, room_jid) 165 self.host.plugins["XEP-0045"].checkRoomJoined(client, room_jid)
166 except exceptions.NotFound: 166 except exceptions.NotFound:
167 pass 167 pass
168 else: 168 else:
169 log.info( 169 log.info(
170 _(u"Invitation silently discarded because user is already in the room.") 170 _("Invitation silently discarded because user is already in the room.")
171 ) 171 )
172 return 172 return
173 173
174 autojoin = self.host.memory.getParamA( 174 autojoin = self.host.memory.getParamA(
175 AUTOJOIN_NAME, AUTOJOIN_KEY, profile_key=client.profile 175 AUTOJOIN_NAME, AUTOJOIN_KEY, profile_key=client.profile
177 177
178 if autojoin == "always": 178 if autojoin == "always":
179 self._accept(room_jid, client.profile) 179 self._accept(room_jid, client.profile)
180 elif autojoin == "never": 180 elif autojoin == "never":
181 msg = D_( 181 msg = D_(
182 u"An invitation from %(user)s to join the room %(room)s has been " 182 "An invitation from %(user)s to join the room %(room)s has been "
183 u"declined according to your personal settings." 183 "declined according to your personal settings."
184 ) % {"user": from_jid_s, "room": room_jid_s} 184 ) % {"user": from_jid_s, "room": room_jid_s}
185 title = D_("MUC invitation") 185 title = D_("MUC invitation")
186 xml_tools.quickNote(self.host, client, msg, title, C.XMLUI_DATA_LVL_INFO) 186 xml_tools.quickNote(self.host, client, msg, title, C.XMLUI_DATA_LVL_INFO)
187 else: # leave the default value here 187 else: # leave the default value here
188 confirm_msg = D_( 188 confirm_msg = D_(
189 u"You have been invited by %(user)s to join the room %(room)s. " 189 "You have been invited by %(user)s to join the room %(room)s. "
190 u"Do you accept?" 190 "Do you accept?"
191 ) % {"user": from_jid_s, "room": room_jid_s} 191 ) % {"user": from_jid_s, "room": room_jid_s}
192 confirm_title = D_("MUC invitation") 192 confirm_title = D_("MUC invitation")
193 d = xml_tools.deferConfirm( 193 d = xml_tools.deferConfirm(
194 self.host, confirm_msg, confirm_title, profile=client.profile 194 self.host, confirm_msg, confirm_title, profile=client.profile
195 ) 195 )
211 my_host = client.jid.host 211 my_host = client.jid.host
212 try: 212 try:
213 contact_jid = jid.JID(contact_jid_s) 213 contact_jid = jid.JID(contact_jid_s)
214 except (RuntimeError, jid.InvalidFormat, AttributeError): 214 except (RuntimeError, jid.InvalidFormat, AttributeError):
215 feedback = _( 215 feedback = _(
216 u"You must provide a valid JID to invite, like in '/invite " 216 "You must provide a valid JID to invite, like in '/invite "
217 u"contact@{host}'" 217 "contact@{host}'"
218 ).format(host=my_host) 218 ).format(host=my_host)
219 self.host.plugins[C.TEXT_CMDS].feedBack(client, feedback, mess_data) 219 self.host.plugins[C.TEXT_CMDS].feedBack(client, feedback, mess_data)
220 return False 220 return False
221 if not contact_jid.user: 221 if not contact_jid.user:
222 contact_jid.user, contact_jid.host = contact_jid.host, my_host 222 contact_jid.user, contact_jid.host = contact_jid.host, my_host
223 self.invite(client, contact_jid, mess_data["to"]) 223 self.invite(client, contact_jid, mess_data["to"])
224 return False 224 return False
225 225
226 226
227 @implementer(iwokkel.IDisco)
227 class XEP_0249_handler(XMPPHandler): 228 class XEP_0249_handler(XMPPHandler):
228 implements(iwokkel.IDisco)
229 229
230 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): 230 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
231 return [disco.DiscoFeature(NS_X_CONFERENCE)] 231 return [disco.DiscoFeature(NS_X_CONFERENCE)]
232 232
233 def getDiscoItems(self, requestor, target, nodeIdentifier=""): 233 def getDiscoItems(self, requestor, target, nodeIdentifier=""):