Mercurial > libervia-backend
comparison sat/plugins/plugin_xep_0231.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 | be6d91572633 |
children |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
56 | 56 |
57 class XEP_0231(object): | 57 class XEP_0231(object): |
58 def __init__(self, host): | 58 def __init__(self, host): |
59 log.info(_("plugin Bits of Binary initialization")) | 59 log.info(_("plugin Bits of Binary initialization")) |
60 self.host = host | 60 self.host = host |
61 host.registerNamespace("bob", NS_BOB) | 61 host.register_namespace("bob", NS_BOB) |
62 host.trigger.add("xhtml_post_treat", self.XHTMLTrigger) | 62 host.trigger.add("xhtml_post_treat", self.xhtml_trigger) |
63 host.bridge.addMethod( | 63 host.bridge.add_method( |
64 "bobGetFile", | 64 "bob_get_file", |
65 ".plugin", | 65 ".plugin", |
66 in_sign="sss", | 66 in_sign="sss", |
67 out_sign="s", | 67 out_sign="s", |
68 method=self._getFile, | 68 method=self._get_file, |
69 async_=True, | 69 async_=True, |
70 ) | 70 ) |
71 | 71 |
72 def dumpData(self, cache, data_elt, cid): | 72 def dump_data(self, cache, data_elt, cid): |
73 """save file encoded in data_elt to cache | 73 """save file encoded in data_elt to cache |
74 | 74 |
75 @param cache(memory.cache.Cache): cache to use to store the data | 75 @param cache(memory.cache.Cache): cache to use to store the data |
76 @param data_elt(domish.Element): <data> as in XEP-0231 | 76 @param data_elt(domish.Element): <data> as in XEP-0231 |
77 @param cid(unicode): content-id | 77 @param cid(unicode): content-id |
85 raise ValueError | 85 raise ValueError |
86 except (KeyError, ValueError): | 86 except (KeyError, ValueError): |
87 log.warning("invalid max-age found") | 87 log.warning("invalid max-age found") |
88 max_age = None | 88 max_age = None |
89 | 89 |
90 with cache.cacheData( | 90 with cache.cache_data( |
91 PLUGIN_INFO[C.PI_IMPORT_NAME], cid, data_elt.getAttribute("type"), max_age | 91 PLUGIN_INFO[C.PI_IMPORT_NAME], cid, data_elt.getAttribute("type"), max_age |
92 ) as f: | 92 ) as f: |
93 | 93 |
94 file_path = Path(f.name) | 94 file_path = Path(f.name) |
95 f.write(base64.b64decode(str(data_elt))) | 95 f.write(base64.b64decode(str(data_elt))) |
96 | 96 |
97 return file_path | 97 return file_path |
98 | 98 |
99 def getHandler(self, client): | 99 def get_handler(self, client): |
100 return XEP_0231_handler(self) | 100 return XEP_0231_handler(self) |
101 | 101 |
102 def _requestCb(self, iq_elt, cache, cid): | 102 def _request_cb(self, iq_elt, cache, cid): |
103 for data_elt in iq_elt.elements(NS_BOB, "data"): | 103 for data_elt in iq_elt.elements(NS_BOB, "data"): |
104 if data_elt.getAttribute("cid") == cid: | 104 if data_elt.getAttribute("cid") == cid: |
105 file_path = self.dumpData(cache, data_elt, cid) | 105 file_path = self.dump_data(cache, data_elt, cid) |
106 return file_path | 106 return file_path |
107 | 107 |
108 log.warning( | 108 log.warning( |
109 "invalid data stanza received, requested cid was not found:\n{iq_elt}\nrequested cid: {cid}".format( | 109 "invalid data stanza received, requested cid was not found:\n{iq_elt}\nrequested cid: {cid}".format( |
110 iq_elt=iq_elt, cid=cid | 110 iq_elt=iq_elt, cid=cid |
111 ) | 111 ) |
112 ) | 112 ) |
113 raise failure.Failure(exceptions.DataError("missing data")) | 113 raise failure.Failure(exceptions.DataError("missing data")) |
114 | 114 |
115 def _requestEb(self, failure_): | 115 def _request_eb(self, failure_): |
116 """Log the error and continue errback chain""" | 116 """Log the error and continue errback chain""" |
117 log.warning("Can't get requested data:\n{reason}".format(reason=failure_)) | 117 log.warning("Can't get requested data:\n{reason}".format(reason=failure_)) |
118 return failure_ | 118 return failure_ |
119 | 119 |
120 def requestData(self, client, to_jid, cid, cache=None): | 120 def request_data(self, client, to_jid, cid, cache=None): |
121 """Request data if we don't have it in cache | 121 """Request data if we don't have it in cache |
122 | 122 |
123 @param to_jid(jid.JID): jid to request the data to | 123 @param to_jid(jid.JID): jid to request the data to |
124 @param cid(unicode): content id | 124 @param cid(unicode): content id |
125 @param cache(memory.cache.Cache, None): cache to use | 125 @param cache(memory.cache.Cache, None): cache to use |
131 iq_elt = client.IQ("get") | 131 iq_elt = client.IQ("get") |
132 iq_elt["to"] = to_jid.full() | 132 iq_elt["to"] = to_jid.full() |
133 data_elt = iq_elt.addElement((NS_BOB, "data")) | 133 data_elt = iq_elt.addElement((NS_BOB, "data")) |
134 data_elt["cid"] = cid | 134 data_elt["cid"] = cid |
135 d = iq_elt.send() | 135 d = iq_elt.send() |
136 d.addCallback(self._requestCb, cache, cid) | 136 d.addCallback(self._request_cb, cache, cid) |
137 d.addErrback(self._requestEb) | 137 d.addErrback(self._request_eb) |
138 return d | 138 return d |
139 | 139 |
140 def _setImgEltSrc(self, path, img_elt): | 140 def _set_img_elt_src(self, path, img_elt): |
141 img_elt["src"] = "file://{}".format(path) | 141 img_elt["src"] = "file://{}".format(path) |
142 | 142 |
143 def XHTMLTrigger(self, client, message_elt, body_elt, lang, treat_d): | 143 def xhtml_trigger(self, client, message_elt, body_elt, lang, treat_d): |
144 for img_elt in xml_tools.findAll(body_elt, C.NS_XHTML, "img"): | 144 for img_elt in xml_tools.find_all(body_elt, C.NS_XHTML, "img"): |
145 source = img_elt.getAttribute("src", "") | 145 source = img_elt.getAttribute("src", "") |
146 if source.startswith("cid:"): | 146 if source.startswith("cid:"): |
147 cid = source[4:] | 147 cid = source[4:] |
148 file_path = client.cache.getFilePath(cid) | 148 file_path = client.cache.get_file_path(cid) |
149 if file_path is not None: | 149 if file_path is not None: |
150 # image is in cache, we change the url | 150 # image is in cache, we change the url |
151 img_elt["src"] = "file://{}".format(file_path) | 151 img_elt["src"] = "file://{}".format(file_path) |
152 continue | 152 continue |
153 else: | 153 else: |
154 # image is not in cache, is it given locally? | 154 # image is not in cache, is it given locally? |
155 for data_elt in message_elt.elements(NS_BOB, "data"): | 155 for data_elt in message_elt.elements(NS_BOB, "data"): |
156 if data_elt.getAttribute("cid") == cid: | 156 if data_elt.getAttribute("cid") == cid: |
157 file_path = self.dumpData(client.cache, data_elt, cid) | 157 file_path = self.dump_data(client.cache, data_elt, cid) |
158 img_elt["src"] = "file://{}".format(file_path) | 158 img_elt["src"] = "file://{}".format(file_path) |
159 break | 159 break |
160 else: | 160 else: |
161 # cid not found locally, we need to request it | 161 # cid not found locally, we need to request it |
162 # so we use the deferred | 162 # so we use the deferred |
163 d = self.requestData(client, jid.JID(message_elt["from"]), cid) | 163 d = self.request_data(client, jid.JID(message_elt["from"]), cid) |
164 d.addCallback(partial(self._setImgEltSrc, img_elt=img_elt)) | 164 d.addCallback(partial(self._set_img_elt_src, img_elt=img_elt)) |
165 treat_d.addCallback(lambda __: d) | 165 treat_d.addCallback(lambda __: d) |
166 | 166 |
167 def onComponentRequest(self, iq_elt, client): | 167 def on_component_request(self, iq_elt, client): |
168 """cache data is retrieve from common cache for components""" | 168 """cache data is retrieve from common cache for components""" |
169 # FIXME: this is a security/privacy issue as no access check is done | 169 # FIXME: this is a security/privacy issue as no access check is done |
170 # but this is mitigated by the fact that the cid must be known. | 170 # but this is mitigated by the fact that the cid must be known. |
171 # An access check should be implemented though. | 171 # An access check should be implemented though. |
172 | 172 |
177 except KeyError: | 177 except KeyError: |
178 error_elt = jabber_error.StanzaError("not-acceptable").toResponse(iq_elt) | 178 error_elt = jabber_error.StanzaError("not-acceptable").toResponse(iq_elt) |
179 client.send(error_elt) | 179 client.send(error_elt) |
180 return | 180 return |
181 | 181 |
182 metadata = self.host.common_cache.getMetadata(cid) | 182 metadata = self.host.common_cache.get_metadata(cid) |
183 if metadata is None: | 183 if metadata is None: |
184 error_elt = jabber_error.StanzaError("item-not-found").toResponse(iq_elt) | 184 error_elt = jabber_error.StanzaError("item-not-found").toResponse(iq_elt) |
185 client.send(error_elt) | 185 client.send(error_elt) |
186 return | 186 return |
187 | 187 |
194 data_elt["cid"] = cid | 194 data_elt["cid"] = cid |
195 data_elt["type"] = metadata["mime_type"] | 195 data_elt["type"] = metadata["mime_type"] |
196 data_elt["max-age"] = str(int(max(0, metadata["eol"] - time.time()))) | 196 data_elt["max-age"] = str(int(max(0, metadata["eol"] - time.time()))) |
197 client.send(result_elt) | 197 client.send(result_elt) |
198 | 198 |
199 def _getFile(self, peer_jid_s, cid, profile): | 199 def _get_file(self, peer_jid_s, cid, profile): |
200 peer_jid = jid.JID(peer_jid_s) | 200 peer_jid = jid.JID(peer_jid_s) |
201 assert cid | 201 assert cid |
202 client = self.host.getClient(profile) | 202 client = self.host.get_client(profile) |
203 d = self.getFile(client, peer_jid, cid) | 203 d = self.get_file(client, peer_jid, cid) |
204 d.addCallback(lambda path: str(path)) | 204 d.addCallback(lambda path: str(path)) |
205 return d | 205 return d |
206 | 206 |
207 def getFile(self, client, peer_jid, cid, parent_elt=None): | 207 def get_file(self, client, peer_jid, cid, parent_elt=None): |
208 """Retrieve a file from it's content-id | 208 """Retrieve a file from it's content-id |
209 | 209 |
210 @param peer_jid(jid.JID): jid of the entity offering the data | 210 @param peer_jid(jid.JID): jid of the entity offering the data |
211 @param cid(unicode): content-id of file data | 211 @param cid(unicode): content-id of file data |
212 @param parent_elt(domish.Element, None): if file is not in cache, | 212 @param parent_elt(domish.Element, None): if file is not in cache, |
213 data will be looked after in children of this elements. | 213 data will be looked after in children of this elements. |
214 None to ignore | 214 None to ignore |
215 @return D(Path): path to cached data | 215 @return D(Path): path to cached data |
216 """ | 216 """ |
217 file_path = client.cache.getFilePath(cid) | 217 file_path = client.cache.get_file_path(cid) |
218 if file_path is not None: | 218 if file_path is not None: |
219 # file is in cache | 219 # file is in cache |
220 return defer.succeed(file_path) | 220 return defer.succeed(file_path) |
221 else: | 221 else: |
222 # file not in cache, is it given locally? | 222 # file not in cache, is it given locally? |
223 if parent_elt is not None: | 223 if parent_elt is not None: |
224 for data_elt in parent_elt.elements(NS_BOB, "data"): | 224 for data_elt in parent_elt.elements(NS_BOB, "data"): |
225 if data_elt.getAttribute("cid") == cid: | 225 if data_elt.getAttribute("cid") == cid: |
226 return defer.succeed(self.dumpData(client.cache, data_elt, cid)) | 226 return defer.succeed(self.dump_data(client.cache, data_elt, cid)) |
227 | 227 |
228 # cid not found locally, we need to request it | 228 # cid not found locally, we need to request it |
229 # so we use the deferred | 229 # so we use the deferred |
230 return self.requestData(client, peer_jid, cid) | 230 return self.request_data(client, peer_jid, cid) |
231 | 231 |
232 | 232 |
233 @implementer(iwokkel.IDisco) | 233 @implementer(iwokkel.IDisco) |
234 class XEP_0231_handler(xmlstream.XMPPHandler): | 234 class XEP_0231_handler(xmlstream.XMPPHandler): |
235 | 235 |
238 self.host = plugin_parent.host | 238 self.host = plugin_parent.host |
239 | 239 |
240 def connectionInitialized(self): | 240 def connectionInitialized(self): |
241 if self.parent.is_component: | 241 if self.parent.is_component: |
242 self.xmlstream.addObserver( | 242 self.xmlstream.addObserver( |
243 IQ_BOB_REQUEST, self.plugin_parent.onComponentRequest, client=self.parent | 243 IQ_BOB_REQUEST, self.plugin_parent.on_component_request, client=self.parent |
244 ) | 244 ) |
245 | 245 |
246 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): | 246 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): |
247 return [disco.DiscoFeature(NS_BOB)] | 247 return [disco.DiscoFeature(NS_BOB)] |
248 | 248 |