Mercurial > libervia-desktop-kivy
comparison cagou/core/cagou_main.py @ 491:203755bbe0fe
massive refactoring from camelCase -> snake_case. See backend commit log for more details
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 08 Apr 2023 13:44:32 +0200 |
parents | 38ca44d96752 |
children |
comparison
equal
deleted
inserted
replaced
490:962d17c4078c | 491:203755bbe0fe |
---|---|
40 from sat.tools.common import dynamic_import | 40 from sat.tools.common import dynamic_import |
41 from sat.tools.common import files_utils | 41 from sat.tools.common import files_utils |
42 import kivy | 42 import kivy |
43 kivy.require('1.11.0') | 43 kivy.require('1.11.0') |
44 import kivy.support | 44 import kivy.support |
45 main_config = config.parseMainConf(log_filenames=True) | 45 main_config = config.parse_main_conf(log_filenames=True) |
46 bridge_name = config.getConfig(main_config, '', 'bridge', 'dbus') | 46 bridge_name = config.config_get(main_config, '', 'bridge', 'dbus') |
47 # FIXME: event loop is choosen according to bridge_name, a better way should be used | 47 # FIXME: event loop is choosen according to bridge_name, a better way should be used |
48 if 'dbus' in bridge_name: | 48 if 'dbus' in bridge_name: |
49 kivy.support.install_gobject_iteration() | 49 kivy.support.install_gobject_iteration() |
50 elif bridge_name in ('pb', 'embedded'): | 50 elif bridge_name in ('pb', 'embedded'): |
51 kivy.support.install_twisted_reactor() | 51 kivy.support.install_twisted_reactor() |
105 | 105 |
106 def on_release(self): | 106 def on_release(self): |
107 callback, args, kwargs = self.notifs.pop(0) | 107 callback, args, kwargs = self.notifs.pop(0) |
108 callback(*args, **kwargs) | 108 callback(*args, **kwargs) |
109 | 109 |
110 def addNotif(self, callback, *args, **kwargs): | 110 def add_notif(self, callback, *args, **kwargs): |
111 self.notifs.append((callback, args, kwargs)) | 111 self.notifs.append((callback, args, kwargs)) |
112 | 112 |
113 | 113 |
114 class Note(Label): | 114 class Note(Label): |
115 title = properties.StringProperty() | 115 title = properties.StringProperty() |
157 self.add_widget(self.clear_btn) | 157 self.add_widget(self.clear_btn) |
158 super(NotesDrop, self).open(widget) | 158 super(NotesDrop, self).open(widget) |
159 | 159 |
160 def on_select(self, action_kwargs): | 160 def on_select(self, action_kwargs): |
161 app = App.get_running_app() | 161 app = App.get_running_app() |
162 app.host.doAction(**action_kwargs) | 162 app.host.do_action(**action_kwargs) |
163 | 163 |
164 | 164 |
165 class RootHeadWidget(BoxLayout): | 165 class RootHeadWidget(BoxLayout): |
166 """Notifications widget""" | 166 """Notifications widget""" |
167 manager = properties.ObjectProperty() | 167 manager = properties.ObjectProperty() |
173 super(RootHeadWidget, self).__init__() | 173 super(RootHeadWidget, self).__init__() |
174 self.notes_last = None | 174 self.notes_last = None |
175 self.notes_event = None | 175 self.notes_event = None |
176 self.notes_drop = NotesDrop(self.notes) | 176 self.notes_drop = NotesDrop(self.notes) |
177 | 177 |
178 def addNotif(self, callback, *args, **kwargs): | 178 def add_notif(self, callback, *args, **kwargs): |
179 """add a notification with a callback attached | 179 """add a notification with a callback attached |
180 | 180 |
181 when notification is pressed, callback is called | 181 when notification is pressed, callback is called |
182 @param *args, **kwargs: arguments of callback | 182 @param *args, **kwargs: arguments of callback |
183 """ | 183 """ |
184 self.notifs_icon.addNotif(callback, *args, **kwargs) | 184 self.notifs_icon.add_notif(callback, *args, **kwargs) |
185 | 185 |
186 def addNote(self, title, message, level, symbol, action): | 186 def add_note(self, title, message, level, symbol, action): |
187 kwargs = { | 187 kwargs = { |
188 'title': title, | 188 'title': title, |
189 'message': message, | 189 'message': message, |
190 'level': level | 190 'level': level |
191 } | 191 } |
194 if action is not None: | 194 if action is not None: |
195 kwargs['action'] = action | 195 kwargs['action'] = action |
196 note = Note(**kwargs) | 196 note = Note(**kwargs) |
197 self.notes.append(note) | 197 self.notes.append(note) |
198 if self.notes_event is None: | 198 if self.notes_event is None: |
199 self.notes_event = Clock.schedule_interval(self._displayNextNote, 5) | 199 self.notes_event = Clock.schedule_interval(self._display_next_note, 5) |
200 self._displayNextNote() | 200 self._display_next_note() |
201 | 201 |
202 def addNotifUI(self, ui): | 202 def add_notif_ui(self, ui): |
203 self.notifs_icon.addNotif(ui.show, force=True) | 203 self.notifs_icon.add_notif(ui.show, force=True) |
204 | 204 |
205 def addNotifWidget(self, widget): | 205 def add_notif_widget(self, widget): |
206 app = App.get_running_app() | 206 app = App.get_running_app() |
207 self.notifs_icon.addNotif(app.host.showExtraUI, widget=widget) | 207 self.notifs_icon.add_notif(app.host.show_extra_ui, widget=widget) |
208 | 208 |
209 def _displayNextNote(self, __=None): | 209 def _display_next_note(self, __=None): |
210 screen = Screen() | 210 screen = Screen() |
211 try: | 211 try: |
212 idx = self.notes.index(self.notes_last) + 1 | 212 idx = self.notes.index(self.notes_last) + 1 |
213 except ValueError: | 213 except ValueError: |
214 idx = 0 | 214 idx = 0 |
246 # extra (file chooser, audio record, etc) | 246 # extra (file chooser, audio record, etc) |
247 extra_screen = Screen(name='extra') | 247 extra_screen = Screen(name='extra') |
248 self._manager.add_widget(extra_screen) | 248 self._manager.add_widget(extra_screen) |
249 self.root_body.add_widget(self._manager) | 249 self.root_body.add_widget(self._manager) |
250 | 250 |
251 def changeWidget(self, widget, screen_name="main"): | 251 def change_widget(self, widget, screen_name="main"): |
252 """change main widget""" | 252 """change main widget""" |
253 if self._manager.transition.is_active: | 253 if self._manager.transition.is_active: |
254 # FIXME: workaround for what seems a Kivy bug | 254 # FIXME: workaround for what seems a Kivy bug |
255 # TODO: report this upstream | 255 # TODO: report this upstream |
256 self._manager.transition.stop() | 256 self._manager.transition.stop() |
269 self._manager.transition = FallOutTransition() | 269 self._manager.transition = FallOutTransition() |
270 else: | 270 else: |
271 self._manager.transition = RiseInTransition() | 271 self._manager.transition = RiseInTransition() |
272 self._manager.current = screen | 272 self._manager.current = screen |
273 | 273 |
274 def newAction(self, handler, action_data, id_, security_limit, profile): | 274 def new_action(self, handler, action_data, id_, security_limit, profile): |
275 """Add a notification for an action""" | 275 """Add a notification for an action""" |
276 self.head_widget.addNotif(handler, action_data, id_, security_limit, profile) | 276 self.head_widget.add_notif(handler, action_data, id_, security_limit, profile) |
277 | 277 |
278 def addNote(self, title, message, level, symbol, action): | 278 def add_note(self, title, message, level, symbol, action): |
279 self.head_widget.addNote(title, message, level, symbol, action) | 279 self.head_widget.add_note(title, message, level, symbol, action) |
280 | 280 |
281 def addNotifUI(self, ui): | 281 def add_notif_ui(self, ui): |
282 self.head_widget.addNotifUI(ui) | 282 self.head_widget.add_notif_ui(ui) |
283 | 283 |
284 def addNotifWidget(self, widget): | 284 def add_notif_widget(self, widget): |
285 self.head_widget.addNotifWidget(widget) | 285 self.head_widget.add_notif_widget(widget) |
286 | 286 |
287 | 287 |
288 class CagouApp(App): | 288 class CagouApp(App): |
289 """Kivy App for Cagou""" | 289 """Kivy App for Cagou""" |
290 c_prim = properties.ListProperty(C.COLOR_PRIM) | 290 c_prim = properties.ListProperty(C.COLOR_PRIM) |
309 Window.bind(on_dropfile=self.on_dropfile) | 309 Window.bind(on_dropfile=self.on_dropfile) |
310 wid = CagouRootWidget(Label(text=_("Loading please wait"))) | 310 wid = CagouRootWidget(Label(text=_("Loading please wait"))) |
311 local_platform.on_app_build(wid) | 311 local_platform.on_app_build(wid) |
312 return wid | 312 return wid |
313 | 313 |
314 def showProfileManager(self): | 314 def show_profile_manager(self): |
315 self._profile_manager = ProfileManager() | 315 self._profile_manager = ProfileManager() |
316 self.root.changeWidget(self._profile_manager) | 316 self.root.change_widget(self._profile_manager) |
317 | 317 |
318 def expand(self, path, *args, **kwargs): | 318 def expand(self, path, *args, **kwargs): |
319 """expand path and replace known values | 319 """expand path and replace known values |
320 | 320 |
321 useful in kv. Values which can be used: | 321 useful in kv. Values which can be used: |
324 @param *args: additional arguments used in format | 324 @param *args: additional arguments used in format |
325 @param **kwargs: additional keyword arguments used in format | 325 @param **kwargs: additional keyword arguments used in format |
326 """ | 326 """ |
327 return os.path.expanduser(path).format(*args, media=self.host.media_dir, **kwargs) | 327 return os.path.expanduser(path).format(*args, media=self.host.media_dir, **kwargs) |
328 | 328 |
329 def initFrontendState(self): | 329 def init_frontend_state(self): |
330 """Init state to handle paused/stopped/running on mobile OSes""" | 330 """Init state to handle paused/stopped/running on mobile OSes""" |
331 local_platform.on_initFrontendState() | 331 local_platform.on_init_frontend_state() |
332 | 332 |
333 def on_pause(self): | 333 def on_pause(self): |
334 return local_platform.on_pause() | 334 return local_platform.on_pause() |
335 | 335 |
336 def on_resume(self): | 336 def on_resume(self): |
337 return local_platform.on_resume() | 337 return local_platform.on_resume() |
338 | 338 |
339 def on_stop(self): | 339 def on_stop(self): |
340 return local_platform.on_stop() | 340 return local_platform.on_stop() |
341 | 341 |
342 def showHeadWidget(self, show=None, animation=True): | 342 def show_head_widget(self, show=None, animation=True): |
343 """Show/Hide the head widget | 343 """Show/Hide the head widget |
344 | 344 |
345 @param show(bool, None): True to show, False to hide, None to switch | 345 @param show(bool, None): True to show, False to hide, None to switch |
346 @param animation(bool): animate the show/hide if True | 346 @param animation(bool): animate the show/hide if True |
347 """ | 347 """ |
384 else: | 384 else: |
385 Window.fullscreen = False | 385 Window.fullscreen = False |
386 return True | 386 return True |
387 elif key == 110 and 'alt' in modifier: | 387 elif key == 110 and 'alt' in modifier: |
388 # M-n we hide/show notifications | 388 # M-n we hide/show notifications |
389 self.showHeadWidget() | 389 self.show_head_widget() |
390 return True | 390 return True |
391 else: | 391 else: |
392 return False | 392 return False |
393 | 393 |
394 def on_dropfile(self, __, file_path): | 394 def on_dropfile(self, __, file_path): |
416 if bridge_module is None: | 416 if bridge_module is None: |
417 log.error(f"Can't import {bridge_name} bridge") | 417 log.error(f"Can't import {bridge_name} bridge") |
418 sys.exit(3) | 418 sys.exit(3) |
419 else: | 419 else: |
420 log.debug(f"Loading {bridge_name} bridge") | 420 log.debug(f"Loading {bridge_name} bridge") |
421 super(Cagou, self).__init__(bridge_factory=bridge_module.Bridge, | 421 super(Cagou, self).__init__(bridge_factory=bridge_module.bridge, |
422 xmlui=xmlui, | 422 xmlui=xmlui, |
423 check_options=quick_utils.check_options, | 423 check_options=quick_utils.check_options, |
424 connect_bridge=False) | 424 connect_bridge=False) |
425 self._import_kv() | 425 self._import_kv() |
426 self.app = CagouApp() | 426 self.app = CagouApp() |
427 self.app.host = self | 427 self.app.host = self |
428 self.media_dir = self.app.media_dir = config.getConfig(main_config, '', | 428 self.media_dir = self.app.media_dir = config.config_get(main_config, '', |
429 'media_dir') | 429 'media_dir') |
430 self.downloads_dir = self.app.downloads_dir = config.getConfig(main_config, '', | 430 self.downloads_dir = self.app.downloads_dir = config.config_get(main_config, '', |
431 'downloads_dir') | 431 'downloads_dir') |
432 if not os.path.exists(self.downloads_dir): | 432 if not os.path.exists(self.downloads_dir): |
433 try: | 433 try: |
434 os.makedirs(self.downloads_dir) | 434 os.makedirs(self.downloads_dir) |
435 except OSError as e: | 435 except OSError as e: |
447 # visible widgets by classes | 447 # visible widgets by classes |
448 self._visible_widgets = {} | 448 self._visible_widgets = {} |
449 # used to keep track of last selected widget in "main" screen when changing | 449 # used to keep track of last selected widget in "main" screen when changing |
450 # root screen | 450 # root screen |
451 self._selected_widget_main = None | 451 self._selected_widget_main = None |
452 self.backend_version = sat.__version__ # will be replaced by getVersion() | 452 self.backend_version = sat.__version__ # will be replaced by version_get() |
453 if C.APP_VERSION.endswith('D'): | 453 if C.APP_VERSION.endswith('D'): |
454 self.version = "{} {}".format( | 454 self.version = "{} {}".format( |
455 C.APP_VERSION, | 455 C.APP_VERSION, |
456 sat_utils.getRepositoryData(cagou) | 456 sat_utils.get_repository_data(cagou) |
457 ) | 457 ) |
458 else: | 458 else: |
459 self.version = C.APP_VERSION | 459 self.version = C.APP_VERSION |
460 | 460 |
461 self.tls_validation = not C.bool(config.getConfig(main_config, | 461 self.tls_validation = not C.bool(config.config_get(main_config, |
462 C.CONFIG_SECTION, | 462 C.CONFIG_SECTION, |
463 'no_certificate_validation', | 463 'no_certificate_validation', |
464 C.BOOL_FALSE)) | 464 C.BOOL_FALSE)) |
465 if not self.tls_validation: | 465 if not self.tls_validation: |
466 from cagou.core import patches | 466 from cagou.core import patches |
482 return self.default_wid['main'] | 482 return self.default_wid['main'] |
483 | 483 |
484 @QuickApp.sync.setter | 484 @QuickApp.sync.setter |
485 def sync(self, state): | 485 def sync(self, state): |
486 QuickApp.sync.fset(self, state) | 486 QuickApp.sync.fset(self, state) |
487 # widget are resynchronised in onVisible event, | 487 # widget are resynchronised in on_visible event, |
488 # so we must call resync for widgets which are already visible | 488 # so we must call resync for widgets which are already visible |
489 if state: | 489 if state: |
490 for w in self.visible_widgets: | 490 for w in self.visible_widgets: |
491 try: | 491 try: |
492 resync = w.resync | 492 resync = w.resync |
494 pass | 494 pass |
495 else: | 495 else: |
496 resync() | 496 resync() |
497 self.contact_lists.fill() | 497 self.contact_lists.fill() |
498 | 498 |
499 def getConfig(self, section, name, default=None): | 499 def config_get(self, section, name, default=None): |
500 return config.getConfig(main_config, section, name, default) | 500 return config.config_get(main_config, section, name, default) |
501 | 501 |
502 def onBridgeConnected(self): | 502 def on_bridge_connected(self): |
503 super(Cagou, self).onBridgeConnected() | 503 super(Cagou, self).on_bridge_connected() |
504 self.registerSignal("otrState", iface="plugin") | 504 self.register_signal("otr_state", iface="plugin") |
505 | 505 |
506 def _bridgeEb(self, failure): | 506 def _bridge_eb(self, failure): |
507 if bridge_name == "pb" and sys.platform == "android": | 507 if bridge_name == "pb" and sys.platform == "android": |
508 try: | 508 try: |
509 self.retried += 1 | 509 self.retried += 1 |
510 except AttributeError: | 510 except AttributeError: |
511 self.retried = 1 | 511 self.retried = 1 |
512 if ((isinstance(failure, exceptions.BridgeExceptionNoService) | 512 if ((isinstance(failure, exceptions.BridgeExceptionNoService) |
513 and self.retried < 100)): | 513 and self.retried < 100)): |
514 if self.retried % 20 == 0: | 514 if self.retried % 20 == 0: |
515 log.debug("backend not ready, retrying ({})".format(self.retried)) | 515 log.debug("backend not ready, retrying ({})".format(self.retried)) |
516 Clock.schedule_once(lambda __: self.connectBridge(), 0.05) | 516 Clock.schedule_once(lambda __: self.connect_bridge(), 0.05) |
517 return | 517 return |
518 super(Cagou, self)._bridgeEb(failure) | 518 super(Cagou, self)._bridge_eb(failure) |
519 | 519 |
520 def run(self): | 520 def run(self): |
521 self.connectBridge() | 521 self.connect_bridge() |
522 self.app.bind(on_stop=self.onStop) | 522 self.app.bind(on_stop=self.onStop) |
523 self.app.run() | 523 self.app.run() |
524 | 524 |
525 def onStop(self, obj): | 525 def onStop(self, obj): |
526 try: | 526 try: |
528 except AttributeError: | 528 except AttributeError: |
529 pass | 529 pass |
530 else: | 530 else: |
531 sat_instance.stopService() | 531 sat_instance.stopService() |
532 | 532 |
533 def _getVersionCb(self, version): | 533 def _get_version_cb(self, version): |
534 self.backend_version = version | 534 self.backend_version = version |
535 | 535 |
536 def onBackendReady(self): | 536 def on_backend_ready(self): |
537 super().onBackendReady() | 537 super().on_backend_ready() |
538 self.app.showProfileManager() | 538 self.app.show_profile_manager() |
539 self.bridge.getVersion(callback=self._getVersionCb) | 539 self.bridge.version_get(callback=self._get_version_cb) |
540 self.app.initFrontendState() | 540 self.app.init_frontend_state() |
541 if local_platform.do_postInit(): | 541 if local_platform.do_post_init(): |
542 self.postInit() | 542 self.post_init() |
543 | 543 |
544 def postInit(self, __=None): | 544 def post_init(self, __=None): |
545 # FIXME: resize doesn't work with SDL2 on android, so we use below_target for now | 545 # FIXME: resize doesn't work with SDL2 on android, so we use below_target for now |
546 self.app.root_window.softinput_mode = "below_target" | 546 self.app.root_window.softinput_mode = "below_target" |
547 profile_manager = self.app._profile_manager | 547 profile_manager = self.app._profile_manager |
548 del self.app._profile_manager | 548 del self.app._profile_manager |
549 super(Cagou, self).postInit(profile_manager) | 549 super(Cagou, self).post_init(profile_manager) |
550 | 550 |
551 def profilePlugged(self, profile): | 551 def profile_plugged(self, profile): |
552 super().profilePlugged(profile) | 552 super().profile_plugged(profile) |
553 # FIXME: this won't work with multiple profiles | 553 # FIXME: this won't work with multiple profiles |
554 self.app.connected = self.profiles[profile].connected | 554 self.app.connected = self.profiles[profile].connected |
555 | 555 |
556 def _bookmarksListCb(self, bookmarks_dict, profile): | 556 def _bookmarks_list_cb(self, bookmarks_dict, profile): |
557 bookmarks = set() | 557 bookmarks = set() |
558 for data in bookmarks_dict.values(): | 558 for data in bookmarks_dict.values(): |
559 bookmarks.update({jid.JID(k) for k in data.keys()}) | 559 bookmarks.update({jid.JID(k) for k in data.keys()}) |
560 self.profiles[profile]._bookmarks = sorted(bookmarks) | 560 self.profiles[profile]._bookmarks = sorted(bookmarks) |
561 | 561 |
562 def profileConnected(self, profile): | 562 def profile_connected(self, profile): |
563 self.bridge.bookmarksList( | 563 self.bridge.bookmarks_list( |
564 "muc", "all", profile, | 564 "muc", "all", profile, |
565 callback=partial(self._bookmarksListCb, profile=profile), | 565 callback=partial(self._bookmarks_list_cb, profile=profile), |
566 errback=partial(self.errback, title=_("Bookmark error"))) | 566 errback=partial(self.errback, title=_("Bookmark error"))) |
567 | 567 |
568 def _defaultFactoryMain(self, plugin_info, target, profiles): | 568 def _default_factory_main(self, plugin_info, target, profiles): |
569 """default factory used to create main widgets instances | 569 """default factory used to create main widgets instances |
570 | 570 |
571 used when PLUGIN_INFO["factory"] is not set | 571 used when PLUGIN_INFO["factory"] is not set |
572 @param plugin_info(dict): plugin datas | 572 @param plugin_info(dict): plugin datas |
573 @param target: QuickWidget target | 573 @param target: QuickWidget target |
574 @param profiles(iterable): list of profiles | 574 @param profiles(iterable): list of profiles |
575 """ | 575 """ |
576 main_cls = plugin_info['main'] | 576 main_cls = plugin_info['main'] |
577 return self.widgets.getOrCreateWidget(main_cls, | 577 return self.widgets.get_or_create_widget(main_cls, |
578 target, | 578 target, |
579 on_new_widget=None, | 579 on_new_widget=None, |
580 profiles=iter(self.profiles)) | 580 profiles=iter(self.profiles)) |
581 | 581 |
582 def _defaultFactoryTransfer(self, plugin_info, callback, cancel_cb, profiles): | 582 def _default_factory_transfer(self, plugin_info, callback, cancel_cb, profiles): |
583 """default factory used to create transfer widgets instances | 583 """default factory used to create transfer widgets instances |
584 | 584 |
585 @param plugin_info(dict): plugin datas | 585 @param plugin_info(dict): plugin datas |
586 @param callback(callable): method to call with path to file to transfer | 586 @param callback(callable): method to call with path to file to transfer |
587 @param cancel_cb(callable): call when transfer is cancelled | 587 @param cancel_cb(callable): call when transfer is cancelled |
635 plugin_type = suff[:suff.find('_')] | 635 plugin_type = suff[:suff.find('_')] |
636 | 636 |
637 # and select the variable to use according to type | 637 # and select the variable to use according to type |
638 if plugin_type == C.PLUG_TYPE_WID: | 638 if plugin_type == C.PLUG_TYPE_WID: |
639 imported_names = imported_names_main | 639 imported_names = imported_names_main |
640 default_factory = self._defaultFactoryMain | 640 default_factory = self._default_factory_main |
641 elif plugin_type == C.PLUG_TYPE_TRANSFER: | 641 elif plugin_type == C.PLUG_TYPE_TRANSFER: |
642 imported_names = imported_names_transfer | 642 imported_names = imported_names_transfer |
643 default_factory = self._defaultFactoryTransfer | 643 default_factory = self._default_factory_transfer |
644 else: | 644 else: |
645 log.error("unknown plugin type {type_} for plugin {file_}, skipping" | 645 log.error("unknown plugin type {type_} for plugin {file_}, skipping" |
646 .format( | 646 .format( |
647 type_ = plugin_type, | 647 type_ = plugin_type, |
648 file_ = plug | 648 file_ = plug |
649 )) | 649 )) |
650 continue | 650 continue |
651 plugins_set = self._getPluginsSet(plugin_type) | 651 plugins_set = self._get_plugins_set(plugin_type) |
652 | 652 |
653 mod = import_module(plugin_path) | 653 mod = import_module(plugin_path) |
654 try: | 654 try: |
655 plugin_info = mod.PLUGIN_INFO | 655 plugin_info = mod.PLUGIN_INFO |
656 except AttributeError: | 656 except AttributeError: |
699 # what is the main class ? | 699 # what is the main class ? |
700 main_cls = getattr(mod, plugin_info['main']) | 700 main_cls = getattr(mod, plugin_info['main']) |
701 plugin_info['main'] = main_cls | 701 plugin_info['main'] = main_cls |
702 | 702 |
703 # factory is used to create the instance | 703 # factory is used to create the instance |
704 # if not found, we use a defaut one with getOrCreateWidget | 704 # if not found, we use a defaut one with get_or_create_widget |
705 if 'factory' not in plugin_info: | 705 if 'factory' not in plugin_info: |
706 plugin_info['factory'] = default_factory | 706 plugin_info['factory'] = default_factory |
707 | 707 |
708 # icons | 708 # icons |
709 for size in ('small', 'medium'): | 709 for size in ('small', 'medium'): |
729 | 729 |
730 if self.default_wid is None: | 730 if self.default_wid is None: |
731 # we have no selector widget, we use the first widget as default | 731 # we have no selector widget, we use the first widget as default |
732 self.default_wid = self._plg_wids[0] | 732 self.default_wid = self._plg_wids[0] |
733 | 733 |
734 def _getPluginsSet(self, type_): | 734 def _get_plugins_set(self, type_): |
735 if type_ == C.PLUG_TYPE_WID: | 735 if type_ == C.PLUG_TYPE_WID: |
736 return self._plg_wids | 736 return self._plg_wids |
737 elif type_ == C.PLUG_TYPE_TRANSFER: | 737 elif type_ == C.PLUG_TYPE_TRANSFER: |
738 return self._plg_wids_transfer | 738 return self._plg_wids_transfer |
739 else: | 739 else: |
740 raise KeyError("{} plugin type is unknown".format(type_)) | 740 raise KeyError("{} plugin type is unknown".format(type_)) |
741 | 741 |
742 def getPluggedWidgets(self, type_=C.PLUG_TYPE_WID, except_cls=None): | 742 def get_plugged_widgets(self, type_=C.PLUG_TYPE_WID, except_cls=None): |
743 """get available widgets plugin infos | 743 """get available widgets plugin infos |
744 | 744 |
745 @param type_(unicode): type of widgets to get | 745 @param type_(unicode): type of widgets to get |
746 one of C.PLUG_TYPE_* constant | 746 one of C.PLUG_TYPE_* constant |
747 @param except_cls(None, class): if not None, | 747 @param except_cls(None, class): if not None, |
748 widgets from this class will be excluded | 748 widgets from this class will be excluded |
749 @return (iter[dict]): available widgets plugin infos | 749 @return (iter[dict]): available widgets plugin infos |
750 """ | 750 """ |
751 plugins_set = self._getPluginsSet(type_) | 751 plugins_set = self._get_plugins_set(type_) |
752 for plugin_data in plugins_set: | 752 for plugin_data in plugins_set: |
753 if plugin_data['main'] == except_cls: | 753 if plugin_data['main'] == except_cls: |
754 continue | 754 continue |
755 yield plugin_data | 755 yield plugin_data |
756 | 756 |
757 def getPluginInfo(self, type_=C.PLUG_TYPE_WID, **kwargs): | 757 def get_plugin_info(self, type_=C.PLUG_TYPE_WID, **kwargs): |
758 """get first plugin info corresponding to filters | 758 """get first plugin info corresponding to filters |
759 | 759 |
760 @param type_(unicode): type of widgets to get | 760 @param type_(unicode): type of widgets to get |
761 one of C.PLUG_TYPE_* constant | 761 one of C.PLUG_TYPE_* constant |
762 @param **kwargs: filter(s) to use, each key present here must also | 762 @param **kwargs: filter(s) to use, each key present here must also |
763 exist and be of the same value in requested plugin info | 763 exist and be of the same value in requested plugin info |
764 @return (dict, None): found plugin info or None | 764 @return (dict, None): found plugin info or None |
765 """ | 765 """ |
766 plugins_set = self._getPluginsSet(type_) | 766 plugins_set = self._get_plugins_set(type_) |
767 for plugin_info in plugins_set: | 767 for plugin_info in plugins_set: |
768 for k, w in kwargs.items(): | 768 for k, w in kwargs.items(): |
769 try: | 769 try: |
770 if plugin_info[k] != w: | 770 if plugin_info[k] != w: |
771 continue | 771 continue |
773 continue | 773 continue |
774 return plugin_info | 774 return plugin_info |
775 | 775 |
776 ## widgets handling | 776 ## widgets handling |
777 | 777 |
778 def newWidget(self, widget): | 778 def new_widget(self, widget): |
779 log.debug("new widget created: {}".format(widget)) | 779 log.debug("new widget created: {}".format(widget)) |
780 if isinstance(widget, quick_chat.QuickChat) and widget.type == C.CHAT_GROUP: | 780 if isinstance(widget, quick_chat.QuickChat) and widget.type == C.CHAT_GROUP: |
781 self.addNote("", _("room {} has been joined").format(widget.target)) | 781 self.add_note("", _("room {} has been joined").format(widget.target)) |
782 | 782 |
783 def switchWidget(self, old, new=None): | 783 def switch_widget(self, old, new=None): |
784 """Replace old widget by new one | 784 """Replace old widget by new one |
785 | 785 |
786 @param old(CagouWidget, None): CagouWidget instance or a child | 786 @param old(CagouWidget, None): CagouWidget instance or a child |
787 None to select automatically widget to switch | 787 None to select automatically widget to switch |
788 @param new(CagouWidget): new widget instance | 788 @param new(CagouWidget): new widget instance |
789 None to use default widget | 789 None to use default widget |
790 @return (CagouWidget): new widget | 790 @return (CagouWidget): new widget |
791 """ | 791 """ |
792 if old is None: | 792 if old is None: |
793 old = self.getWidgetToSwitch() | 793 old = self.get_widget_to_switch() |
794 if new is None: | 794 if new is None: |
795 factory = self.default_wid['factory'] | 795 factory = self.default_wid['factory'] |
796 try: | 796 try: |
797 profiles = old.profiles | 797 profiles = old.profiles |
798 except AttributeError: | 798 except AttributeError: |
809 | 809 |
810 if to_change is None: | 810 if to_change is None: |
811 raise exceptions.InternalError("no CagouWidget found when " | 811 raise exceptions.InternalError("no CagouWidget found when " |
812 "trying to switch widget") | 812 "trying to switch widget") |
813 | 813 |
814 # selected_widget can be modified in changeWidget, so we need to set it before | 814 # selected_widget can be modified in change_widget, so we need to set it before |
815 self.selected_widget = new | 815 self.selected_widget = new |
816 if to_change == new: | 816 if to_change == new: |
817 log.debug("switchWidget called with old==new, nothing to do") | 817 log.debug("switch_widget called with old==new, nothing to do") |
818 return new | 818 return new |
819 to_change.whwrapper.changeWidget(new) | 819 to_change.whwrapper.change_widget(new) |
820 return new | 820 return new |
821 | 821 |
822 def _addVisibleWidget(self, widget): | 822 def _add_visible_widget(self, widget): |
823 """declare a widget visible | 823 """declare a widget visible |
824 | 824 |
825 for internal use only! | 825 for internal use only! |
826 """ | 826 """ |
827 assert isinstance(widget, CagouWidget) | 827 assert isinstance(widget, CagouWidget) |
828 log.debug(f"Visible widget: {widget}") | 828 log.debug(f"Visible widget: {widget}") |
829 self._visible_widgets.setdefault(widget.__class__, set()).add(widget) | 829 self._visible_widgets.setdefault(widget.__class__, set()).add(widget) |
830 log.debug(f"visible widgets list: {self.getVisibleList(None)}") | 830 log.debug(f"visible widgets list: {self.get_visible_list(None)}") |
831 widget.onVisible() | 831 widget.on_visible() |
832 | 832 |
833 def _removeVisibleWidget(self, widget, ignore_missing=False): | 833 def _remove_visible_widget(self, widget, ignore_missing=False): |
834 """declare a widget not visible anymore | 834 """declare a widget not visible anymore |
835 | 835 |
836 for internal use only! | 836 for internal use only! |
837 """ | 837 """ |
838 log.debug(f"Widget not visible anymore: {widget}") | 838 log.debug(f"Widget not visible anymore: {widget}") |
840 self._visible_widgets[widget.__class__].remove(widget) | 840 self._visible_widgets[widget.__class__].remove(widget) |
841 except KeyError as e: | 841 except KeyError as e: |
842 if not ignore_missing: | 842 if not ignore_missing: |
843 log.error(f"trying to remove a not visible widget ({widget}): {e}") | 843 log.error(f"trying to remove a not visible widget ({widget}): {e}") |
844 return | 844 return |
845 log.debug(f"visible widgets list: {self.getVisibleList(None)}") | 845 log.debug(f"visible widgets list: {self.get_visible_list(None)}") |
846 if isinstance(widget, CagouWidget): | 846 if isinstance(widget, CagouWidget): |
847 widget.onNotVisible() | 847 widget.on_not_visible() |
848 if isinstance(widget, quick_widgets.QuickWidget): | 848 if isinstance(widget, quick_widgets.QuickWidget): |
849 self.widgets.deleteWidget(widget) | 849 self.widgets.delete_widget(widget) |
850 | 850 |
851 def getVisibleList(self, cls): | 851 def get_visible_list(self, cls): |
852 """get list of visible widgets for a given class | 852 """get list of visible widgets for a given class |
853 | 853 |
854 @param cls(type): type of widgets to get | 854 @param cls(type): type of widgets to get |
855 None to get all visible widgets | 855 None to get all visible widgets |
856 @return (set[type]): visible widgets of this class | 856 @return (set[type]): visible widgets of this class |
864 try: | 864 try: |
865 return self._visible_widgets[cls] | 865 return self._visible_widgets[cls] |
866 except KeyError: | 866 except KeyError: |
867 return set() | 867 return set() |
868 | 868 |
869 def deleteUnusedWidgetInstances(self, widget): | 869 def delete_unused_widget_instances(self, widget): |
870 """Delete instance of this widget which are not attached to a WHWrapper | 870 """Delete instance of this widget which are not attached to a WHWrapper |
871 | 871 |
872 @param widget(quick_widgets.QuickWidget): reference widget | 872 @param widget(quick_widgets.QuickWidget): reference widget |
873 other instance of this widget will be deleted if they have no parent | 873 other instance of this widget will be deleted if they have no parent |
874 """ | 874 """ |
875 to_delete = [] | 875 to_delete = [] |
876 if isinstance(widget, quick_widgets.QuickWidget): | 876 if isinstance(widget, quick_widgets.QuickWidget): |
877 for w in self.widgets.getWidgetInstances(widget): | 877 for w in self.widgets.get_widget_instances(widget): |
878 if w.whwrapper is None and w != widget: | 878 if w.whwrapper is None and w != widget: |
879 to_delete.append(w) | 879 to_delete.append(w) |
880 for w in to_delete: | 880 for w in to_delete: |
881 log.debug("cleaning widget: {wid}".format(wid=w)) | 881 log.debug("cleaning widget: {wid}".format(wid=w)) |
882 self.widgets.deleteWidget(w) | 882 self.widgets.delete_widget(w) |
883 | 883 |
884 def getOrClone(self, widget, **kwargs): | 884 def get_or_clone(self, widget, **kwargs): |
885 """Get a QuickWidget if it is not in a WHWrapper, else clone it | 885 """Get a QuickWidget if it is not in a WHWrapper, else clone it |
886 | 886 |
887 if an other instance of this widget exist without being in a WHWrapper | 887 if an other instance of this widget exist without being in a WHWrapper |
888 (i.e. if it is not already in use) it will be used. | 888 (i.e. if it is not already in use) it will be used. |
889 """ | 889 """ |
890 if widget.whwrapper is None: | 890 if widget.whwrapper is None: |
891 if widget.parent is not None: | 891 if widget.parent is not None: |
892 widget.parent.remove_widget(widget) | 892 widget.parent.remove_widget(widget) |
893 self.deleteUnusedWidgetInstances(widget) | 893 self.delete_unused_widget_instances(widget) |
894 return widget | 894 return widget |
895 for w in self.widgets.getWidgetInstances(widget): | 895 for w in self.widgets.get_widget_instances(widget): |
896 if w.whwrapper is None: | 896 if w.whwrapper is None: |
897 if w.parent is not None: | 897 if w.parent is not None: |
898 w.parent.remove_widget(w) | 898 w.parent.remove_widget(w) |
899 self.deleteUnusedWidgetInstances(w) | 899 self.delete_unused_widget_instances(w) |
900 return w | 900 return w |
901 targets = list(widget.targets) | 901 targets = list(widget.targets) |
902 w = self.widgets.getOrCreateWidget(widget.__class__, | 902 w = self.widgets.get_or_create_widget(widget.__class__, |
903 targets[0], | 903 targets[0], |
904 on_new_widget=None, | 904 on_new_widget=None, |
905 on_existing_widget=C.WIDGET_RECREATE, | 905 on_existing_widget=C.WIDGET_RECREATE, |
906 profiles=widget.profiles, | 906 profiles=widget.profiles, |
907 **kwargs) | 907 **kwargs) |
908 for t in targets[1:]: | 908 for t in targets[1:]: |
909 w.addTarget(t) | 909 w.add_target(t) |
910 return w | 910 return w |
911 | 911 |
912 def getWidgetToSwitch(self): | 912 def get_widget_to_switch(self): |
913 """Choose best candidate when we need to switch widget and old is not specified | 913 """Choose best candidate when we need to switch widget and old is not specified |
914 | 914 |
915 @return (CagouWidget): widget to switch | 915 @return (CagouWidget): widget to switch |
916 """ | 916 """ |
917 if (self._selected_widget_main is not None | 917 if (self._selected_widget_main is not None |
929 return w | 929 return w |
930 | 930 |
931 # no default widget found, we return the first widget | 931 # no default widget found, we return the first widget |
932 return next(iter(self.visible_widgets)) | 932 return next(iter(self.visible_widgets)) |
933 | 933 |
934 def doAction(self, action, target, profiles): | 934 def do_action(self, action, target, profiles): |
935 """Launch an action handler by a plugin | 935 """Launch an action handler by a plugin |
936 | 936 |
937 @param action(unicode): action to do, can be: | 937 @param action(unicode): action to do, can be: |
938 - chat: open a chat widget | 938 - chat: open a chat widget |
939 @param target(unicode): target of the action | 939 @param target(unicode): target of the action |
941 @return (CagouWidget, None): new widget | 941 @return (CagouWidget, None): new widget |
942 """ | 942 """ |
943 try: | 943 try: |
944 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method | 944 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method |
945 # in host | 945 # in host |
946 plg_infos = [p for p in self.getPluggedWidgets() | 946 plg_infos = [p for p in self.get_plugged_widgets() |
947 if action in p['import_name']][0] | 947 if action in p['import_name']][0] |
948 except IndexError: | 948 except IndexError: |
949 log.warning("No plugin widget found to do {action}".format(action=action)) | 949 log.warning("No plugin widget found to do {action}".format(action=action)) |
950 else: | 950 else: |
951 try: | 951 try: |
952 # does the widget already exist? | 952 # does the widget already exist? |
953 wid = next(self.widgets.getWidgets( | 953 wid = next(self.widgets.get_widgets( |
954 plg_infos['main'], | 954 plg_infos['main'], |
955 target=target, | 955 target=target, |
956 profiles=profiles)) | 956 profiles=profiles)) |
957 except StopIteration: | 957 except StopIteration: |
958 # no, let's create a new one | 958 # no, let's create a new one |
959 factory = plg_infos['factory'] | 959 factory = plg_infos['factory'] |
960 wid = factory(plg_infos, target=target, profiles=profiles) | 960 wid = factory(plg_infos, target=target, profiles=profiles) |
961 | 961 |
962 return self.switchWidget(None, wid) | 962 return self.switch_widget(None, wid) |
963 | 963 |
964 ## bridge handlers ## | 964 ## bridge handlers ## |
965 | 965 |
966 def otrStateHandler(self, state, dest_jid, profile): | 966 def otr_state_handler(self, state, dest_jid, profile): |
967 """OTR state has changed for on destinee""" | 967 """OTR state has changed for on destinee""" |
968 # XXX: this method could be in QuickApp but it's here as | 968 # XXX: this method could be in QuickApp but it's here as |
969 # it's only used by Cagou so far | 969 # it's only used by Cagou so far |
970 dest_jid = jid.JID(dest_jid) | 970 dest_jid = jid.JID(dest_jid) |
971 bare_jid = dest_jid.bare | 971 bare_jid = dest_jid.bare |
972 for widget in self.widgets.getWidgets(quick_chat.QuickChat, profiles=(profile,)): | 972 for widget in self.widgets.get_widgets(quick_chat.QuickChat, profiles=(profile,)): |
973 if widget.type == C.CHAT_ONE2ONE and widget.target == bare_jid: | 973 if widget.type == C.CHAT_ONE2ONE and widget.target == bare_jid: |
974 widget.onOTRState(state, dest_jid, profile) | 974 widget.on_otr_state(state, dest_jid, profile) |
975 | 975 |
976 def _debugHandler(self, action, parameters, profile): | 976 def _debug_handler(self, action, parameters, profile): |
977 if action == "visible_widgets_dump": | 977 if action == "visible_widgets_dump": |
978 from pprint import pformat | 978 from pprint import pformat |
979 log.info("Visible widgets dump:\n{data}".format( | 979 log.info("Visible widgets dump:\n{data}".format( |
980 data=pformat(self._visible_widgets))) | 980 data=pformat(self._visible_widgets))) |
981 else: | 981 else: |
982 return super(Cagou, self)._debugHandler(action, parameters, profile) | 982 return super(Cagou, self)._debug_handler(action, parameters, profile) |
983 | 983 |
984 def connectedHandler(self, jid_s, profile): | 984 def connected_handler(self, jid_s, profile): |
985 # FIXME: this won't work with multiple profiles | 985 # FIXME: this won't work with multiple profiles |
986 super().connectedHandler(jid_s, profile) | 986 super().connected_handler(jid_s, profile) |
987 self.app.connected = True | 987 self.app.connected = True |
988 | 988 |
989 def disconnectedHandler(self, profile): | 989 def disconnected_handler(self, profile): |
990 # FIXME: this won't work with multiple profiles | 990 # FIXME: this won't work with multiple profiles |
991 super().disconnectedHandler(profile) | 991 super().disconnected_handler(profile) |
992 self.app.connected = False | 992 self.app.connected = False |
993 | 993 |
994 ## misc ## | 994 ## misc ## |
995 | 995 |
996 def plugging_profiles(self): | 996 def plugging_profiles(self): |
997 self.widgets_handler = widgets_handler.WidgetsHandler() | 997 self.widgets_handler = widgets_handler.WidgetsHandler() |
998 self.app.root.changeWidget(self.widgets_handler) | 998 self.app.root.change_widget(self.widgets_handler) |
999 | 999 |
1000 def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): | 1000 def set_presence_status(self, show='', status=None, profile=C.PROF_KEY_NONE): |
1001 log.info("Profile presence status set to {show}/{status}".format(show=show, | 1001 log.info("Profile presence status set to {show}/{status}".format(show=show, |
1002 status=status)) | 1002 status=status)) |
1003 | 1003 |
1004 def errback(self, failure_, title=_('error'), | 1004 def errback(self, failure_, title=_('error'), |
1005 message=_('error while processing: {msg}')): | 1005 message=_('error while processing: {msg}')): |
1006 self.addNote(title, message.format(msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) | 1006 self.add_note(title, message.format(msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) |
1007 | 1007 |
1008 def addNote(self, title, message, level=C.XMLUI_DATA_LVL_INFO, symbol=None, | 1008 def add_note(self, title, message, level=C.XMLUI_DATA_LVL_INFO, symbol=None, |
1009 action=None): | 1009 action=None): |
1010 """add a note (message which disappear) to root widget's header""" | 1010 """add a note (message which disappear) to root widget's header""" |
1011 self.app.root.addNote(title, message, level, symbol, action) | 1011 self.app.root.add_note(title, message, level, symbol, action) |
1012 | 1012 |
1013 def addNotifUI(self, ui): | 1013 def add_notif_ui(self, ui): |
1014 """add a notification with a XMLUI attached | 1014 """add a notification with a XMLUI attached |
1015 | 1015 |
1016 @param ui(xmlui.XMLUIPanel): XMLUI instance to show when notification is selected | 1016 @param ui(xmlui.XMLUIPanel): XMLUI instance to show when notification is selected |
1017 """ | 1017 """ |
1018 self.app.root.addNotifUI(ui) | 1018 self.app.root.add_notif_ui(ui) |
1019 | 1019 |
1020 def addNotifWidget(self, widget): | 1020 def add_notif_widget(self, widget): |
1021 """add a notification with a Kivy widget attached | 1021 """add a notification with a Kivy widget attached |
1022 | 1022 |
1023 @param widget(kivy.uix.Widget): widget to attach to notification | 1023 @param widget(kivy.uix.Widget): widget to attach to notification |
1024 """ | 1024 """ |
1025 self.app.root.addNotifWidget(widget) | 1025 self.app.root.add_notif_widget(widget) |
1026 | 1026 |
1027 def showUI(self, ui): | 1027 def show_ui(self, ui): |
1028 """show a XMLUI""" | 1028 """show a XMLUI""" |
1029 self.app.root.changeWidget(ui, "xmlui") | 1029 self.app.root.change_widget(ui, "xmlui") |
1030 self.app.root.show("xmlui") | 1030 self.app.root.show("xmlui") |
1031 self._selected_widget_main = self.selected_widget | 1031 self._selected_widget_main = self.selected_widget |
1032 self.selected_widget = ui | 1032 self.selected_widget = ui |
1033 | 1033 |
1034 def showExtraUI(self, widget): | 1034 def show_extra_ui(self, widget): |
1035 """show any extra widget""" | 1035 """show any extra widget""" |
1036 self.app.root.changeWidget(widget, "extra") | 1036 self.app.root.change_widget(widget, "extra") |
1037 self.app.root.show("extra") | 1037 self.app.root.show("extra") |
1038 self._selected_widget_main = self.selected_widget | 1038 self._selected_widget_main = self.selected_widget |
1039 self.selected_widget = widget | 1039 self.selected_widget = widget |
1040 | 1040 |
1041 def closeUI(self): | 1041 def close_ui(self): |
1042 self.app.root.show() | 1042 self.app.root.show() |
1043 self.selected_widget = self._selected_widget_main | 1043 self.selected_widget = self._selected_widget_main |
1044 self._selected_widget_main = None | 1044 self._selected_widget_main = None |
1045 screen = self.app.root._manager.get_screen("extra") | 1045 screen = self.app.root._manager.get_screen("extra") |
1046 screen.clear_widgets() | 1046 screen.clear_widgets() |
1047 | 1047 |
1048 def getDefaultAvatar(self, entity=None): | 1048 def get_default_avatar(self, entity=None): |
1049 return self.app.default_avatar | 1049 return self.app.default_avatar |
1050 | 1050 |
1051 def _dialog_cb(self, cb, *args, **kwargs): | 1051 def _dialog_cb(self, cb, *args, **kwargs): |
1052 """generic dialog callback | 1052 """generic dialog callback |
1053 | 1053 |
1054 close dialog then call the callback with given arguments | 1054 close dialog then call the callback with given arguments |
1055 """ | 1055 """ |
1056 def callback(): | 1056 def callback(): |
1057 self.closeUI() | 1057 self.close_ui() |
1058 cb(*args, **kwargs) | 1058 cb(*args, **kwargs) |
1059 return callback | 1059 return callback |
1060 | 1060 |
1061 def showDialog(self, message, title, type="info", answer_cb=None, answer_data=None): | 1061 def show_dialog(self, message, title, type="info", answer_cb=None, answer_data=None): |
1062 if type in ('info', 'warning', 'error'): | 1062 if type in ('info', 'warning', 'error'): |
1063 self.addNote(title, message, type) | 1063 self.add_note(title, message, type) |
1064 elif type == "yes/no": | 1064 elif type == "yes/no": |
1065 wid = dialog.ConfirmDialog(title=title, message=message, | 1065 wid = dialog.ConfirmDialog(title=title, message=message, |
1066 yes_cb=self._dialog_cb(answer_cb, | 1066 yes_cb=self._dialog_cb(answer_cb, |
1067 True, | 1067 True, |
1068 answer_data), | 1068 answer_data), |
1069 no_cb=self._dialog_cb(answer_cb, | 1069 no_cb=self._dialog_cb(answer_cb, |
1070 False, | 1070 False, |
1071 answer_data) | 1071 answer_data) |
1072 ) | 1072 ) |
1073 self.addNotifWidget(wid) | 1073 self.add_notif_widget(wid) |
1074 else: | 1074 else: |
1075 log.warning(_("unknown dialog type: {dialog_type}").format(dialog_type=type)) | 1075 log.warning(_("unknown dialog type: {dialog_type}").format(dialog_type=type)) |
1076 | 1076 |
1077 def share(self, media_type, data): | 1077 def share(self, media_type, data): |
1078 share_wid = ShareWidget(media_type=media_type, data=data) | 1078 share_wid = ShareWidget(media_type=media_type, data=data) |
1079 try: | 1079 try: |
1080 self.showExtraUI(share_wid) | 1080 self.show_extra_ui(share_wid) |
1081 except Exception as e: | 1081 except Exception as e: |
1082 log.error(e) | 1082 log.error(e) |
1083 self.closeUI() | 1083 self.close_ui() |
1084 | 1084 |
1085 def downloadURL( | 1085 def download_url( |
1086 self, url, callback, errback=None, options=None, dest=C.FILE_DEST_DOWNLOAD, | 1086 self, url, callback, errback=None, options=None, dest=C.FILE_DEST_DOWNLOAD, |
1087 profile=C.PROF_KEY_NONE): | 1087 profile=C.PROF_KEY_NONE): |
1088 """Download an URL (decrypt it if necessary) | 1088 """Download an URL (decrypt it if necessary) |
1089 | 1089 |
1090 @param url(str, parse.SplitResult): url to download | 1090 @param url(str, parse.SplitResult): url to download |
1092 @param errback(callable, None): method to call in case of error | 1092 @param errback(callable, None): method to call in case of error |
1093 if None, default errback will be called | 1093 if None, default errback will be called |
1094 @param dest(str): where the file should be downloaded: | 1094 @param dest(str): where the file should be downloaded: |
1095 - C.FILE_DEST_DOWNLOAD: in platform download directory | 1095 - C.FILE_DEST_DOWNLOAD: in platform download directory |
1096 - C.FILE_DEST_CACHE: in SàT cache | 1096 - C.FILE_DEST_CACHE: in SàT cache |
1097 @param options(dict, None): options to pass to bridge.fileDownloadComplete | 1097 @param options(dict, None): options to pass to bridge.file_download_complete |
1098 """ | 1098 """ |
1099 if not isinstance(url, urlparse.ParseResult): | 1099 if not isinstance(url, urlparse.ParseResult): |
1100 url = urlparse.urlparse(url) | 1100 url = urlparse.urlparse(url) |
1101 if errback is None: | 1101 if errback is None: |
1102 errback = partial( | 1102 errback = partial( |
1109 dest_path = files_utils.get_unique_name(Path(self.downloads_dir)/name) | 1109 dest_path = files_utils.get_unique_name(Path(self.downloads_dir)/name) |
1110 elif dest == C.FILE_DEST_CACHE: | 1110 elif dest == C.FILE_DEST_CACHE: |
1111 dest_path = '' | 1111 dest_path = '' |
1112 else: | 1112 else: |
1113 raise exceptions.InternalError(f"Invalid dest_path: {dest_path!r}") | 1113 raise exceptions.InternalError(f"Invalid dest_path: {dest_path!r}") |
1114 self.bridge.fileDownloadComplete( | 1114 self.bridge.file_download_complete( |
1115 data_format.serialise({"uri": url.geturl()}), | 1115 data_format.serialise({"uri": url.geturl()}), |
1116 str(dest_path), | 1116 str(dest_path), |
1117 '' if not options else data_format.serialise(options), | 1117 '' if not options else data_format.serialise(options), |
1118 profile, | 1118 profile, |
1119 callback=callback, | 1119 callback=callback, |
1144 except Exception as e: | 1144 except Exception as e: |
1145 log.warning(_("Can't use notifications, disabling: {msg}").format( | 1145 log.warning(_("Can't use notifications, disabling: {msg}").format( |
1146 msg = e)) | 1146 msg = e)) |
1147 notification = None | 1147 notification = None |
1148 | 1148 |
1149 def getParentWHWrapper(self, wid): | 1149 def get_parent_wh_wrapper(self, wid): |
1150 """Retrieve parent WHWrapper instance managing a widget | 1150 """Retrieve parent WHWrapper instance managing a widget |
1151 | 1151 |
1152 @param wid(Widget): widget to check | 1152 @param wid(Widget): widget to check |
1153 @return (WHWrapper, None): found instance if any, else None | 1153 @return (WHWrapper, None): found instance if any, else None |
1154 """ | 1154 """ |
1155 wh = self.getAncestorWidget(wid, widgets_handler.WHWrapper) | 1155 wh = self.get_ancestor_widget(wid, widgets_handler.WHWrapper) |
1156 if wh is None: | 1156 if wh is None: |
1157 # we may have a screen | 1157 # we may have a screen |
1158 try: | 1158 try: |
1159 sm = wid.screen_manager | 1159 sm = wid.screen_manager |
1160 except (exceptions.InternalError, exceptions.NotFound): | 1160 except (exceptions.InternalError, exceptions.NotFound): |
1161 return None | 1161 return None |
1162 else: | 1162 else: |
1163 wh = self.getAncestorWidget(sm, widgets_handler.WHWrapper) | 1163 wh = self.get_ancestor_widget(sm, widgets_handler.WHWrapper) |
1164 return wh | 1164 return wh |
1165 | 1165 |
1166 def getAncestorWidget(self, wid, cls): | 1166 def get_ancestor_widget(self, wid, cls): |
1167 """Retrieve an ancestor of given class | 1167 """Retrieve an ancestor of given class |
1168 | 1168 |
1169 @param wid(Widget): current widget | 1169 @param wid(Widget): current widget |
1170 @param cls(type): class of the ancestor to retrieve | 1170 @param cls(type): class of the ancestor to retrieve |
1171 @return (Widget, None): found instance or None | 1171 @return (Widget, None): found instance or None |