comparison sat/plugins/plugin_xep_0353.py @ 4037:524856bd7b19

massive refactoring to switch from camelCase to snake_case: historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a pre-PEP8 code, to use the same coding style as in Twisted. However, snake_case is more readable and it's better to follow PEP8 best practices, so it has been decided to move on full snake_case. Because Libervia has a huge codebase, this ended with a ugly mix of camelCase and snake_case. To fix that, this patch does a big refactoring by renaming every function and method (including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case. This is a massive change, and may result in some bugs.
author Goffi <goffi@goffi.org>
date Sat, 08 Apr 2023 13:54:42 +0200
parents 6e34307319c0
children 877145b4ba01
comparison
equal deleted inserted replaced
4036:c4464d7ae97b 4037:524856bd7b19
50 class XEP_0353: 50 class XEP_0353:
51 51
52 def __init__(self, host): 52 def __init__(self, host):
53 log.info(_("plugin {name} initialization").format(name=PLUGIN_INFO[C.PI_NAME])) 53 log.info(_("plugin {name} initialization").format(name=PLUGIN_INFO[C.PI_NAME]))
54 self.host = host 54 self.host = host
55 host.registerNamespace("jingle-message", NS_JINGLE_MESSAGE) 55 host.register_namespace("jingle-message", NS_JINGLE_MESSAGE)
56 self._j = host.plugins["XEP-0166"] 56 self._j = host.plugins["XEP-0166"]
57 host.trigger.add("XEP-0166_initiate", self._onInitiateTrigger) 57 host.trigger.add("XEP-0166_initiate", self._on_initiate_trigger)
58 host.trigger.add("messageReceived", self._onMessageReceived) 58 host.trigger.add("messageReceived", self._on_message_received)
59 59
60 def getHandler(self, client): 60 def get_handler(self, client):
61 return Handler() 61 return Handler()
62 62
63 def profileConnecting(self, client): 63 def profile_connecting(self, client):
64 # mapping from session id to deferred used to wait for destinee answer 64 # mapping from session id to deferred used to wait for destinee answer
65 client._xep_0353_pending_sessions = {} 65 client._xep_0353_pending_sessions = {}
66 66
67 def buildMessageData(self, client, peer_jid, verb, session_id): 67 def build_message_data(self, client, peer_jid, verb, session_id):
68 mess_data = { 68 mess_data = {
69 'from': client.jid, 69 'from': client.jid,
70 'to': peer_jid, 70 'to': peer_jid,
71 'uid': '', 71 'uid': '',
72 'message': {}, 72 'message': {},
73 'type': C.MESS_TYPE_CHAT, 73 'type': C.MESS_TYPE_CHAT,
74 'subject': {}, 74 'subject': {},
75 'extra': {} 75 'extra': {}
76 } 76 }
77 client.generateMessageXML(mess_data) 77 client.generate_message_xml(mess_data)
78 verb_elt = mess_data["xml"].addElement((NS_JINGLE_MESSAGE, verb)) 78 verb_elt = mess_data["xml"].addElement((NS_JINGLE_MESSAGE, verb))
79 verb_elt["id"] = session_id 79 verb_elt["id"] = session_id
80 return mess_data 80 return mess_data
81 81
82 async def _onInitiateTrigger(self, client, session, contents): 82 async def _on_initiate_trigger(self, client, session, contents):
83 # FIXME: check that at least one resource of the peer_jid can handle the feature 83 # FIXME: check that at least one resource of the peer_jid can handle the feature
84 peer_jid = session['peer_jid'] 84 peer_jid = session['peer_jid']
85 if peer_jid.resource: 85 if peer_jid.resource:
86 return True 86 return True
87 87
88 try: 88 try:
89 infos = await self.host.memory.disco.getInfos(client, peer_jid) 89 infos = await self.host.memory.disco.get_infos(client, peer_jid)
90 except error.StanzaError as e: 90 except error.StanzaError as e:
91 if e.condition == "service-unavailable": 91 if e.condition == "service-unavailable":
92 categories = {} 92 categories = {}
93 else: 93 else:
94 raise e 94 raise e
101 if peer_jid.userhostJID() not in client.roster: 101 if peer_jid.userhostJID() not in client.roster:
102 # if the contact is not in our roster, we need to send a directed presence 102 # if the contact is not in our roster, we need to send a directed presence
103 # according to XEP-0353 §3.1 103 # according to XEP-0353 §3.1
104 await client.presence.available(peer_jid) 104 await client.presence.available(peer_jid)
105 105
106 mess_data = self.buildMessageData(client, peer_jid, "propose", session['id']) 106 mess_data = self.build_message_data(client, peer_jid, "propose", session['id'])
107 for content in contents: 107 for content in contents:
108 application, app_args, app_kwargs, content_name = self._j.getContentData( 108 application, app_args, app_kwargs, content_name = self._j.get_content_data(
109 content) 109 content)
110 try: 110 try:
111 jingleDescriptionElt = application.handler.jingleDescriptionElt 111 jingle_description_elt = application.handler.jingle_description_elt
112 except AttributeError: 112 except AttributeError:
113 log.debug(f"no jingleDescriptionElt set for {application.handler}") 113 log.debug(f"no jingle_description_elt set for {application.handler}")
114 description_elt = domish.Element((content["app_ns"], "description")) 114 description_elt = domish.Element((content["app_ns"], "description"))
115 else: 115 else:
116 description_elt = await utils.asDeferred( 116 description_elt = await utils.as_deferred(
117 jingleDescriptionElt, 117 jingle_description_elt,
118 client, session, content_name, *app_args, **app_kwargs 118 client, session, content_name, *app_args, **app_kwargs
119 ) 119 )
120 mess_data["xml"].propose.addChild(description_elt) 120 mess_data["xml"].propose.addChild(description_elt)
121 response_d = defer.Deferred() 121 response_d = defer.Deferred()
122 # we wait for 2 min before cancelling the session init 122 # we wait for 2 min before cancelling the session init
123 response_d.addTimeout(2*60, reactor) 123 response_d.addTimeout(2*60, reactor)
124 client._xep_0353_pending_sessions[session['id']] = response_d 124 client._xep_0353_pending_sessions[session['id']] = response_d
125 await client.sendMessageData(mess_data) 125 await client.send_message_data(mess_data)
126 try: 126 try:
127 accepting_jid = await response_d 127 accepting_jid = await response_d
128 except defer.TimeoutError: 128 except defer.TimeoutError:
129 log.warning(_( 129 log.warning(_(
130 "Message initiation with {peer_jid} timed out" 130 "Message initiation with {peer_jid} timed out"
132 else: 132 else:
133 session["peer_jid"] = accepting_jid 133 session["peer_jid"] = accepting_jid
134 del client._xep_0353_pending_sessions[session['id']] 134 del client._xep_0353_pending_sessions[session['id']]
135 return True 135 return True
136 136
137 async def _onMessageReceived(self, client, message_elt, post_treat): 137 async def _on_message_received(self, client, message_elt, post_treat):
138 for elt in message_elt.elements(): 138 for elt in message_elt.elements():
139 if elt.uri == NS_JINGLE_MESSAGE: 139 if elt.uri == NS_JINGLE_MESSAGE:
140 if elt.name == "propose": 140 if elt.name == "propose":
141 return await self._handlePropose(client, message_elt, elt) 141 return await self._handle_propose(client, message_elt, elt)
142 elif elt.name == "retract": 142 elif elt.name == "retract":
143 return self._handleRetract(client, message_elt, elt) 143 return self._handle_retract(client, message_elt, elt)
144 elif elt.name == "proceed": 144 elif elt.name == "proceed":
145 return self._handleProceed(client, message_elt, elt) 145 return self._handle_proceed(client, message_elt, elt)
146 elif elt.name == "accept": 146 elif elt.name == "accept":
147 return self._handleAccept(client, message_elt, elt) 147 return self._handle_accept(client, message_elt, elt)
148 elif elt.name == "reject": 148 elif elt.name == "reject":
149 return self._handleAccept(client, message_elt, elt) 149 return self._handle_accept(client, message_elt, elt)
150 else: 150 else:
151 log.warning(f"invalid element: {elt.toXml}") 151 log.warning(f"invalid element: {elt.toXml}")
152 return True 152 return True
153 return True 153 return True
154 154
155 async def _handlePropose(self, client, message_elt, elt): 155 async def _handle_propose(self, client, message_elt, elt):
156 peer_jid = jid.JID(message_elt["from"]) 156 peer_jid = jid.JID(message_elt["from"])
157 session_id = elt["id"] 157 session_id = elt["id"]
158 if peer_jid.userhostJID() not in client.roster: 158 if peer_jid.userhostJID() not in client.roster:
159 app_ns = elt.description.uri 159 app_ns = elt.description.uri
160 try: 160 try:
174 "Somebody not in your contact list ({peer_jid}) wants to do a " 174 "Somebody not in your contact list ({peer_jid}) wants to do a "
175 '"{human_name}" session with you, this would leak your presence and ' 175 '"{human_name}" session with you, this would leak your presence and '
176 "possibly you IP (internet localisation), do you accept?" 176 "possibly you IP (internet localisation), do you accept?"
177 ).format(peer_jid=peer_jid, human_name=human_name) 177 ).format(peer_jid=peer_jid, human_name=human_name)
178 confirm_title = D_("Invitation from an unknown contact") 178 confirm_title = D_("Invitation from an unknown contact")
179 accept = await xml_tools.deferConfirm( 179 accept = await xml_tools.defer_confirm(
180 self.host, confirm_msg, confirm_title, profile=client.profile, 180 self.host, confirm_msg, confirm_title, profile=client.profile,
181 action_extra={ 181 action_extra={
182 "meta_type": C.META_TYPE_NOT_IN_ROSTER_LEAK, 182 "meta_type": C.META_TYPE_NOT_IN_ROSTER_LEAK,
183 "meta_session_id": session_id, 183 "meta_session_id": session_id,
184 "meta_from_jid": peer_jid.full(), 184 "meta_from_jid": peer_jid.full(),
185 } 185 }
186 ) 186 )
187 if not accept: 187 if not accept:
188 mess_data = self.buildMessageData( 188 mess_data = self.build_message_data(
189 client, client.jid.userhostJID(), "reject", session_id) 189 client, client.jid.userhostJID(), "reject", session_id)
190 await client.sendMessageData(mess_data) 190 await client.send_message_data(mess_data)
191 # we don't sent anything to sender, to avoid leaking presence 191 # we don't sent anything to sender, to avoid leaking presence
192 return False 192 return False
193 else: 193 else:
194 await client.presence.available(peer_jid) 194 await client.presence.available(peer_jid)
195 session_id = elt["id"] 195 session_id = elt["id"]
196 mess_data = self.buildMessageData( 196 mess_data = self.build_message_data(
197 client, client.jid.userhostJID(), "accept", session_id) 197 client, client.jid.userhostJID(), "accept", session_id)
198 await client.sendMessageData(mess_data) 198 await client.send_message_data(mess_data)
199 mess_data = self.buildMessageData( 199 mess_data = self.build_message_data(
200 client, peer_jid, "proceed", session_id) 200 client, peer_jid, "proceed", session_id)
201 await client.sendMessageData(mess_data) 201 await client.send_message_data(mess_data)
202 return False 202 return False
203 203
204 def _handleRetract(self, client, message_elt, proceed_elt): 204 def _handle_retract(self, client, message_elt, proceed_elt):
205 log.warning("retract is not implemented yet") 205 log.warning("retract is not implemented yet")
206 return False 206 return False
207 207
208 def _handleProceed(self, client, message_elt, proceed_elt): 208 def _handle_proceed(self, client, message_elt, proceed_elt):
209 try: 209 try:
210 session_id = proceed_elt["id"] 210 session_id = proceed_elt["id"]
211 except KeyError: 211 except KeyError:
212 log.warning(f"invalid proceed element in message_elt: {message_elt}") 212 log.warning(f"invalid proceed element in message_elt: {message_elt}")
213 return True 213 return True
221 return True 221 return True
222 222
223 response_d.callback(jid.JID(message_elt["from"])) 223 response_d.callback(jid.JID(message_elt["from"]))
224 return False 224 return False
225 225
226 def _handleAccept(self, client, message_elt, accept_elt): 226 def _handle_accept(self, client, message_elt, accept_elt):
227 pass 227 pass
228 228
229 def _handleReject(self, client, message_elt, accept_elt): 229 def _handle_reject(self, client, message_elt, accept_elt):
230 pass 230 pass
231 231
232 232
233 @implementer(iwokkel.IDisco) 233 @implementer(iwokkel.IDisco)
234 class Handler(xmlstream.XMPPHandler): 234 class Handler(xmlstream.XMPPHandler):