Mercurial > libervia-backend
comparison sat/plugins/plugin_misc_file.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 | 4c3361e2bf55 |
children | 877145b4ba01 |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
67 File = stream.SatFile | 67 File = stream.SatFile |
68 | 68 |
69 def __init__(self, host): | 69 def __init__(self, host): |
70 log.info(_("plugin File initialization")) | 70 log.info(_("plugin File initialization")) |
71 self.host = host | 71 self.host = host |
72 host.bridge.addMethod( | 72 host.bridge.add_method( |
73 "fileSend", | 73 "file_send", |
74 ".plugin", | 74 ".plugin", |
75 in_sign="ssssss", | 75 in_sign="ssssss", |
76 out_sign="a{ss}", | 76 out_sign="a{ss}", |
77 method=self._fileSend, | 77 method=self._file_send, |
78 async_=True, | 78 async_=True, |
79 ) | 79 ) |
80 self._file_managers = [] | 80 self._file_managers = [] |
81 host.importMenu( | 81 host.import_menu( |
82 (D_("Action"), D_("send file")), | 82 (D_("Action"), D_("send file")), |
83 self._fileSendMenu, | 83 self._file_send_menu, |
84 security_limit=10, | 84 security_limit=10, |
85 help_string=D_("Send a file"), | 85 help_string=D_("Send a file"), |
86 type_=C.MENU_SINGLE, | 86 type_=C.MENU_SINGLE, |
87 ) | 87 ) |
88 | 88 |
89 def _fileSend( | 89 def _file_send( |
90 self, | 90 self, |
91 peer_jid_s: str, | 91 peer_jid_s: str, |
92 filepath: str, | 92 filepath: str, |
93 name: str, | 93 name: str, |
94 file_desc: str, | 94 file_desc: str, |
95 extra_s: str, | 95 extra_s: str, |
96 profile: str = C.PROF_KEY_NONE | 96 profile: str = C.PROF_KEY_NONE |
97 ) -> defer.Deferred: | 97 ) -> defer.Deferred: |
98 client = self.host.getClient(profile) | 98 client = self.host.get_client(profile) |
99 return defer.ensureDeferred(self.fileSend( | 99 return defer.ensureDeferred(self.file_send( |
100 client, jid.JID(peer_jid_s), filepath, name or None, file_desc or None, | 100 client, jid.JID(peer_jid_s), filepath, name or None, file_desc or None, |
101 data_format.deserialise(extra_s) | 101 data_format.deserialise(extra_s) |
102 )) | 102 )) |
103 | 103 |
104 async def fileSend( | 104 async def file_send( |
105 self, client, peer_jid, filepath, filename=None, file_desc=None, extra=None | 105 self, client, peer_jid, filepath, filename=None, file_desc=None, extra=None |
106 ): | 106 ): |
107 """Send a file using best available method | 107 """Send a file using best available method |
108 | 108 |
109 @param peer_jid(jid.JID): jid of the destinee | 109 @param peer_jid(jid.JID): jid of the destinee |
117 if not os.path.isfile(filepath): | 117 if not os.path.isfile(filepath): |
118 raise exceptions.DataError("The given path doesn't link to a file") | 118 raise exceptions.DataError("The given path doesn't link to a file") |
119 if not filename: | 119 if not filename: |
120 filename = os.path.basename(filepath) or "_" | 120 filename = os.path.basename(filepath) or "_" |
121 for manager, priority in self._file_managers: | 121 for manager, priority in self._file_managers: |
122 if await utils.asDeferred(manager.canHandleFileSend, | 122 if await utils.as_deferred(manager.can_handle_file_send, |
123 client, peer_jid, filepath): | 123 client, peer_jid, filepath): |
124 try: | 124 try: |
125 method_name = manager.name | 125 method_name = manager.name |
126 except AttributeError: | 126 except AttributeError: |
127 method_name = manager.__class__.__name__ | 127 method_name = manager.__class__.__name__ |
129 _("{name} method will be used to send the file").format( | 129 _("{name} method will be used to send the file").format( |
130 name=method_name | 130 name=method_name |
131 ) | 131 ) |
132 ) | 132 ) |
133 try: | 133 try: |
134 progress_id = await utils.asDeferred( | 134 progress_id = await utils.as_deferred( |
135 manager.fileSend, client, peer_jid, filepath, filename, file_desc, | 135 manager.file_send, client, peer_jid, filepath, filename, file_desc, |
136 extra | 136 extra |
137 ) | 137 ) |
138 except Exception as e: | 138 except Exception as e: |
139 log.warning( | 139 log.warning( |
140 _("Can't send {filepath} to {peer_jid} with {method_name}: " | 140 _("Can't send {filepath} to {peer_jid} with {method_name}: " |
153 "xmlui": xml_tools.note( | 153 "xmlui": xml_tools.note( |
154 "Can't transfer file", msg, C.XMLUI_DATA_LVL_WARNING | 154 "Can't transfer file", msg, C.XMLUI_DATA_LVL_WARNING |
155 ).toXml() | 155 ).toXml() |
156 } | 156 } |
157 | 157 |
158 def _onFileChoosed(self, peer_jid, data, profile): | 158 def _on_file_choosed(self, peer_jid, data, profile): |
159 client = self.host.getClient(profile) | 159 client = self.host.get_client(profile) |
160 cancelled = C.bool(data.get("cancelled", C.BOOL_FALSE)) | 160 cancelled = C.bool(data.get("cancelled", C.BOOL_FALSE)) |
161 if cancelled: | 161 if cancelled: |
162 return | 162 return |
163 path = data["path"] | 163 path = data["path"] |
164 return self.fileSend(client, peer_jid, path) | 164 return self.file_send(client, peer_jid, path) |
165 | 165 |
166 def _fileSendMenu(self, data, profile): | 166 def _file_send_menu(self, data, profile): |
167 """ XMLUI activated by menu: return file sending UI | 167 """ XMLUI activated by menu: return file sending UI |
168 | 168 |
169 @param profile: %(doc_profile)s | 169 @param profile: %(doc_profile)s |
170 """ | 170 """ |
171 try: | 171 try: |
172 jid_ = jid.JID(data["jid"]) | 172 jid_ = jid.JID(data["jid"]) |
173 except RuntimeError: | 173 except RuntimeError: |
174 raise exceptions.DataError(_("Invalid JID")) | 174 raise exceptions.DataError(_("Invalid JID")) |
175 | 175 |
176 file_choosed_id = self.host.registerCallback( | 176 file_choosed_id = self.host.register_callback( |
177 partial(self._onFileChoosed, jid_), | 177 partial(self._on_file_choosed, jid_), |
178 with_data=True, | 178 with_data=True, |
179 one_shot=True, | 179 one_shot=True, |
180 ) | 180 ) |
181 xml_ui = xml_tools.XMLUI( | 181 xml_ui = xml_tools.XMLUI( |
182 C.XMLUI_DIALOG, | 182 C.XMLUI_DIALOG, |
191 return {"xmlui": xml_ui.toXml()} | 191 return {"xmlui": xml_ui.toXml()} |
192 | 192 |
193 def register(self, manager, priority: int = 0) -> None: | 193 def register(self, manager, priority: int = 0) -> None: |
194 """Register a fileSending manager | 194 """Register a fileSending manager |
195 | 195 |
196 @param manager: object implementing canHandleFileSend, and fileSend methods | 196 @param manager: object implementing can_handle_file_send, and file_send methods |
197 @param priority: pririoty of this manager, the higher available will be used | 197 @param priority: pririoty of this manager, the higher available will be used |
198 """ | 198 """ |
199 m_data = (manager, priority) | 199 m_data = (manager, priority) |
200 if m_data in self._file_managers: | 200 if m_data in self._file_managers: |
201 raise exceptions.ConflictError( | 201 raise exceptions.ConflictError( |
202 f"Manager {manager} is already registered" | 202 f"Manager {manager} is already registered" |
203 ) | 203 ) |
204 if not hasattr(manager, "canHandleFileSend") or not hasattr(manager, "fileSend"): | 204 if not hasattr(manager, "can_handle_file_send") or not hasattr(manager, "file_send"): |
205 raise ValueError( | 205 raise ValueError( |
206 f'{manager} must have both "canHandleFileSend" and "fileSend" methods to ' | 206 f'{manager} must have both "can_handle_file_send" and "file_send" methods to ' |
207 'be registered') | 207 'be registered') |
208 self._file_managers.append(m_data) | 208 self._file_managers.append(m_data) |
209 self._file_managers.sort(key=lambda m: m[1], reverse=True) | 209 self._file_managers.sort(key=lambda m: m[1], reverse=True) |
210 | 210 |
211 def unregister(self, manager): | 211 def unregister(self, manager): |
217 del self._file_managers[idx] | 217 del self._file_managers[idx] |
218 | 218 |
219 # Dialogs with user | 219 # Dialogs with user |
220 # the overwrite check is done here | 220 # the overwrite check is done here |
221 | 221 |
222 def openFileWrite(self, client, file_path, transfer_data, file_data, stream_object): | 222 def open_file_write(self, client, file_path, transfer_data, file_data, stream_object): |
223 """create SatFile or FileStremaObject for the requested file and fill suitable data | 223 """create SatFile or FileStremaObject for the requested file and fill suitable data |
224 """ | 224 """ |
225 if stream_object: | 225 if stream_object: |
226 assert "stream_object" not in transfer_data | 226 assert "stream_object" not in transfer_data |
227 transfer_data["stream_object"] = stream.FileStreamObject( | 227 transfer_data["stream_object"] = stream.FileStreamObject( |
243 uid=file_data[PROGRESS_ID_KEY], | 243 uid=file_data[PROGRESS_ID_KEY], |
244 size=file_data["size"], | 244 size=file_data["size"], |
245 data_cb=file_data.get("data_cb"), | 245 data_cb=file_data.get("data_cb"), |
246 ) | 246 ) |
247 | 247 |
248 async def _gotConfirmation( | 248 async def _got_confirmation( |
249 self, client, data, peer_jid, transfer_data, file_data, stream_object | 249 self, client, data, peer_jid, transfer_data, file_data, stream_object |
250 ): | 250 ): |
251 """Called when the permission and dest path have been received | 251 """Called when the permission and dest path have been received |
252 | 252 |
253 @param peer_jid(jid.JID): jid of the file sender | 253 @param peer_jid(jid.JID): jid of the file sender |
254 @param transfer_data(dict): same as for [self.getDestDir] | 254 @param transfer_data(dict): same as for [self.get_dest_dir] |
255 @param file_data(dict): same as for [self.getDestDir] | 255 @param file_data(dict): same as for [self.get_dest_dir] |
256 @param stream_object(bool): same as for [self.getDestDir] | 256 @param stream_object(bool): same as for [self.get_dest_dir] |
257 return (bool): True if copy is wanted and OK | 257 return (bool): True if copy is wanted and OK |
258 False if user wants to cancel | 258 False if user wants to cancel |
259 if file exists ask confirmation and call again self._getDestDir if needed | 259 if file exists ask confirmation and call again self._getDestDir if needed |
260 """ | 260 """ |
261 if data.get("cancelled", False): | 261 if data.get("cancelled", False): |
264 file_data["file_path"] = file_path = os.path.join(path, file_data["name"]) | 264 file_data["file_path"] = file_path = os.path.join(path, file_data["name"]) |
265 log.debug("destination file path set to {}".format(file_path)) | 265 log.debug("destination file path set to {}".format(file_path)) |
266 | 266 |
267 # we manage case where file already exists | 267 # we manage case where file already exists |
268 if os.path.exists(file_path): | 268 if os.path.exists(file_path): |
269 overwrite = await xml_tools.deferConfirm( | 269 overwrite = await xml_tools.defer_confirm( |
270 self.host, | 270 self.host, |
271 _(CONFIRM_OVERWRITE).format(file_path), | 271 _(CONFIRM_OVERWRITE).format(file_path), |
272 _(CONFIRM_OVERWRITE_TITLE), | 272 _(CONFIRM_OVERWRITE_TITLE), |
273 action_extra={ | 273 action_extra={ |
274 "meta_from_jid": peer_jid.full(), | 274 "meta_from_jid": peer_jid.full(), |
278 security_limit=SECURITY_LIMIT, | 278 security_limit=SECURITY_LIMIT, |
279 profile=client.profile, | 279 profile=client.profile, |
280 ) | 280 ) |
281 | 281 |
282 if not overwrite: | 282 if not overwrite: |
283 return await self.getDestDir(client, peer_jid, transfer_data, file_data) | 283 return await self.get_dest_dir(client, peer_jid, transfer_data, file_data) |
284 | 284 |
285 self.openFileWrite(client, file_path, transfer_data, file_data, stream_object) | 285 self.open_file_write(client, file_path, transfer_data, file_data, stream_object) |
286 return True | 286 return True |
287 | 287 |
288 async def getDestDir( | 288 async def get_dest_dir( |
289 self, client, peer_jid, transfer_data, file_data, stream_object=False | 289 self, client, peer_jid, transfer_data, file_data, stream_object=False |
290 ): | 290 ): |
291 """Request confirmation and destination dir to user | 291 """Request confirmation and destination dir to user |
292 | 292 |
293 Overwrite confirmation is managed. | 293 Overwrite confirmation is managed. |
294 if transfer is confirmed, 'file_obj' is added to transfer_data | 294 if transfer is confirmed, 'file_obj' is added to transfer_data |
295 @param peer_jid(jid.JID): jid of the file sender | 295 @param peer_jid(jid.JID): jid of the file sender |
296 @param filename(unicode): name of the file | 296 @param filename(unicode): name of the file |
297 @param transfer_data(dict): data of the transfer session, | 297 @param transfer_data(dict): data of the transfer session, |
298 it will be only used to store the file_obj. | 298 it will be only used to store the file_obj. |
299 "file_obj" (or "stream_object") key *MUST NOT* exist before using getDestDir | 299 "file_obj" (or "stream_object") key *MUST NOT* exist before using get_dest_dir |
300 @param file_data(dict): information about the file to be transfered | 300 @param file_data(dict): information about the file to be transfered |
301 It MUST contain the following keys: | 301 It MUST contain the following keys: |
302 - peer_jid (jid.JID): other peer jid | 302 - peer_jid (jid.JID): other peer jid |
303 - name (unicode): name of the file to trasnsfer | 303 - name (unicode): name of the file to trasnsfer |
304 the name must not be empty or contain a "/" character | 304 the name must not be empty or contain a "/" character |
312 "size_human" will also be added with human readable file size | 312 "size_human" will also be added with human readable file size |
313 @param stream_object(bool): if True, a stream_object will be used instead of file_obj | 313 @param stream_object(bool): if True, a stream_object will be used instead of file_obj |
314 a stream.FileStreamObject will be used | 314 a stream.FileStreamObject will be used |
315 return: True if transfer is accepted | 315 return: True if transfer is accepted |
316 """ | 316 """ |
317 cont, ret_value = await self.host.trigger.asyncReturnPoint( | 317 cont, ret_value = await self.host.trigger.async_return_point( |
318 "FILE_getDestDir", client, peer_jid, transfer_data, file_data, stream_object | 318 "FILE_getDestDir", client, peer_jid, transfer_data, file_data, stream_object |
319 ) | 319 ) |
320 if not cont: | 320 if not cont: |
321 return ret_value | 321 return ret_value |
322 filename = file_data["name"] | 322 filename = file_data["name"] |
323 assert filename and not "/" in filename | 323 assert filename and not "/" in filename |
324 assert PROGRESS_ID_KEY in file_data | 324 assert PROGRESS_ID_KEY in file_data |
325 # human readable size | 325 # human readable size |
326 file_data["size_human"] = common_utils.getHumanSize(file_data["size"]) | 326 file_data["size_human"] = common_utils.get_human_size(file_data["size"]) |
327 resp_data = await xml_tools.deferDialog( | 327 resp_data = await xml_tools.defer_dialog( |
328 self.host, | 328 self.host, |
329 _(CONFIRM).format(peer=peer_jid.full(), **file_data), | 329 _(CONFIRM).format(peer=peer_jid.full(), **file_data), |
330 _(CONFIRM_TITLE), | 330 _(CONFIRM_TITLE), |
331 type_=C.XMLUI_DIALOG_FILE, | 331 type_=C.XMLUI_DIALOG_FILE, |
332 options={C.XMLUI_DATA_FILETYPE: C.XMLUI_DATA_FILETYPE_DIR}, | 332 options={C.XMLUI_DATA_FILETYPE: C.XMLUI_DATA_FILETYPE_DIR}, |
337 }, | 337 }, |
338 security_limit=SECURITY_LIMIT, | 338 security_limit=SECURITY_LIMIT, |
339 profile=client.profile, | 339 profile=client.profile, |
340 ) | 340 ) |
341 | 341 |
342 accepted = await self._gotConfirmation( | 342 accepted = await self._got_confirmation( |
343 client, | 343 client, |
344 resp_data, | 344 resp_data, |
345 peer_jid, | 345 peer_jid, |
346 transfer_data, | 346 transfer_data, |
347 file_data, | 347 file_data, |