From bcc04dda3c2978548bcd7769c73e968f976eb852 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Thu, 7 Jul 2022 12:51:51 -0500 Subject: [PATCH] Plugin permission additions --- plugins/README.md | 9 ++-- plugins/template/plugin.py | 13 +++-- plugins/youtube_download/plugin.py | 7 ++- .../SolarFM/solarfm/core/controller.py | 4 ++ .../solarfm/core/mixins/ui/grid_mixin.py | 47 ++++++++++++++++++- .../solarfm/core/mixins/ui/tab_mixin.py | 4 +- .../core/signals/keyboard_signals_mixin.py | 10 +++- .../SolarFM/solarfm/plugins/plugins.py | 11 ++++- .../SolarFM/solarfm/utils/keybindings.py | 11 +++++ 9 files changed, 99 insertions(+), 17 deletions(-) diff --git a/plugins/README.md b/plugins/README.md index 6c3ef9e..9495829 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -3,7 +3,7 @@ Copy the example and rename it to your desired name. Plugins define a ui target Plugins must have a run method defined; though, you do not need to necessarily do anything within it. The run method implies that the passed in event system or other data is ready for the plugin to use. -### Manifest +### Manifest Example (All are required.) ``` class Manifest: path: str = os.path.dirname(os.path.realpath(__file__)) @@ -23,8 +23,11 @@ class Manifest: ``` permissions: {} = { 'ui_target': "plugin_control_list", - 'ui_target_id': "" # Only needed if using "other" in "ui_target". See below for predefined "ui_target" options... - 'pass_fm_events': "true" # If empty or undefined will be ignored. + 'ui_target_id': "" # Only needed if using "other" in "ui_target". See below for predefined "ui_target" options... + 'pass_fm_events': "true" # If empty or not present will be ignored. + 'bind_keys': [f"{name}||send_message:f"], + f"{name}||do_save:s"] # Bind keys with method and key pare using list. Must pass "name" like shown with delimiter to its right. + } ``` diff --git a/plugins/template/plugin.py b/plugins/template/plugin.py index f991579..e514ec5 100644 --- a/plugins/template/plugin.py +++ b/plugins/template/plugin.py @@ -32,8 +32,8 @@ class Manifest: support: str = "" permissions: {} = { 'ui_target': "plugin_control_list", - 'pass_fm_events': "true" - + 'pass_fm_events': "true", + 'bind_keys': [f"{name}||send_message:f"] } @@ -58,6 +58,7 @@ class Plugin(Manifest): def send_message(self, widget=None, eve=None): message = "Hello, World!" + print("here") self._event_system.push_gui_event([self.name, "display_message", ("warning", message, None)]) @@ -68,13 +69,17 @@ class Plugin(Manifest): event = self._event_system.read_module_event() if event: try: - if event[0] is self.name: + if event[0] == self.name: target_id, method_target, data = self._event_system.consume_module_event() if not method_target: self._event_message = data else: method = getattr(self.__class__, f"{method_target}") - data = method(*(self, *parameters)) + if data: + data = method(*(self, *data)) + else: + method(*(self,)) except Exception as e: + print("ewww here") print(repr(e)) diff --git a/plugins/youtube_download/plugin.py b/plugins/youtube_download/plugin.py index 1407471..e183c4f 100644 --- a/plugins/youtube_download/plugin.py +++ b/plugins/youtube_download/plugin.py @@ -63,14 +63,17 @@ class Plugin(Manifest): event = self._fm_event_system.read_module_event() if event: try: - if event[0] is self.name: + if event[0] == self.name: target_id, method_target, data = self._fm_event_system.consume_module_event() if not method_target: self._fm_event_message = data else: method = getattr(self.__class__, f"{method_target}") - data = method(*(self, *parameters)) + if data: + data = method(*(self, *data)) + else: + method(*(self,)) except Exception as e: print(repr(e)) diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/controller.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/controller.py index deb4493..3b7ba50 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/controller.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/controller.py @@ -84,6 +84,10 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi data = method(*(self, *parameters)) event_system.push_module_event([sender, None, data]) + def handle_plugin_key_event(self, sender, method_target, parameters=()): + event_system.push_module_event([sender, method_target, parameters]) + + def save_load_session(self, action="save_session"): wid, tid = self.fm_controller.get_active_wid_and_tid() tab = self.get_fm_window(wid).get_tab_by_id(tid) diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/grid_mixin.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/grid_mixin.py index 8d4d065..01ff051 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/grid_mixin.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/grid_mixin.py @@ -19,6 +19,39 @@ def threaded(fn): +# NOTE: Consider trying to use Gtk.TreeView with css that turns it into a grid... +# Can possibly use this to dynamicly load icons instead... +class Icon(Gtk.HBox): + def __init__(self, tab, dir, file): + super(Icon, self).__init__() + + self.load_icon(tab, dir, file) + + @threaded + def load_icon(self, tab, dir, file): + icon = tab.create_icon(dir, file) + + if not icon: + path = f"{dir}/{file}" + icon = self.get_system_thumbnail(path, tab.sys_icon_wh[0]) + + if not icon: + icon = GdkPixbuf.Pixbuf.new_from_file(tab.DEFAULT_ICON) + + self.add(Gtk.Image.new_from_pixbuf(icon)) + self.show_all() + + def get_system_thumbnail(self, file, size): + try: + gio_file = Gio.File.new_for_path(file) + info = gio_file.query_info('standard::icon' , 0, None) + icon = info.get_icon().get_names()[0] + icon_path = self.icon_theme.lookup_icon(icon , size , 0).get_filename() + return GdkPixbuf.Pixbuf.new_from_file(icon_path) + except Exception as e: + return None + + class GridMixin: """docstring for WidgetMixin""" @@ -86,6 +119,15 @@ class GridMixin: tid.hide() return tab_widget + def create_scroll_and_store(self, tab, wid, use_tree_view=False): + if not use_tree_view: + scroll, store = self.create_icon_grid_widget(tab, wid) + else: + # TODO: Fix global logic to make the below work too + scroll, store = self.create_icon_tree_widget(tab, wid) + + return scroll, store + def create_icon_grid_widget(self, tab, wid): scroll = Gtk.ScrolledWindow() grid = Gtk.IconView() @@ -112,7 +154,6 @@ class GridMixin: grid.connect("drag-data-received", self.grid_on_drag_data_received) grid.connect("drag-motion", self.grid_on_drag_motion) - URI_TARGET_TYPE = 80 uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE) targets = [ uri_target ] @@ -167,12 +208,14 @@ class GridMixin: grid.enable_model_drag_dest(targets, action) grid.enable_model_drag_source(0, targets, action) - grid.show_all() scroll.add(grid) grid.set_name(f"{wid}|{tab.get_id()}") scroll.set_name(f"{wid}|{tab.get_id()}") + self.builder.expose_object(f"{wid}|{tab.get_id()}|icon_grid", grid) + self.builder.expose_object(f"{wid}|{tab.get_id()}", scroll) grid.columns_autosize() + self.builder.expose_object(f"{wid}|{tab.get_id()}", scroll) return scroll, store diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/tab_mixin.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/tab_mixin.py index 24e2b56..539f840 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/tab_mixin.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/tab_mixin.py @@ -33,9 +33,7 @@ class TabMixin(GridMixin): tab.set_path(path) tab_widget = self.create_tab_widget(tab) - scroll, store = self.create_icon_grid_widget(tab, wid) - # TODO: Fix global logic to make the below work too - # scroll, store = self.create_icon_tree_widget(tab, wid) + scroll, store = self.create_scroll_and_store(tab, wid) index = notebook.append_page(scroll, tab_widget) self.fm_controller.set_wid_and_tid(wid, tab.get_id()) diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/signals/keyboard_signals_mixin.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/signals/keyboard_signals_mixin.py index 4cb0108..e5f70e8 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/signals/keyboard_signals_mixin.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/signals/keyboard_signals_mixin.py @@ -46,8 +46,14 @@ class KeyboardSignalsMixin: mapping = self.keybindings.lookup(event) if mapping: - getattr(self, mapping)() - return True + try: + # See if in filemanager scope + getattr(self, mapping)() + return True + except Exception: + # Must be plugins scope or we forgot to add method to file manager scope + sender, method_target = mapping.split("||") + self.handle_plugin_key_event(sender, method_target) else: if debug: print(f"on_global_key_release_controller > key > {keyname}") diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/plugins/plugins.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/plugins/plugins.py index 44c5e63..0a81be1 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/plugins/plugins.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/plugins/plugins.py @@ -15,7 +15,7 @@ class Plugin: name: str = None author: str = None version: str = None - suppoert: str = None + support: str = None permissions:{} = None reference: type = None @@ -28,6 +28,8 @@ class Plugins: self._settings = settings self._builder = self._settings.get_builder() self._plugins_path = self._settings.get_plugins_path() + self._keybindings = self._settings.get_keybindings() + self._plugins_dir_watcher = None self._plugin_collection = [] @@ -114,6 +116,10 @@ class Plugins: if permissions["pass_fm_events"] in ["true"]: loading_data["pass_fm_events"] = True + if "bind_keys" in keys: + if isinstance(permissions["bind_keys"], list): + loading_data["bind_keys"] = permissions["bind_keys"] + return loading_data def execute_plugin(self, module: type, plugin: Plugin, loading_data: []): @@ -127,6 +133,9 @@ class Plugins: if "pass_fm_events" in keys: plugin.reference.set_fm_event_system(event_system) + if "bind_keys" in keys: + self._keybindings.append_bindings(loading_data["bind_keys"]) + plugin.reference.run() self._plugin_collection.append(plugin) diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/utils/keybindings.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/utils/keybindings.py index a7bbbf6..f1bf0bc 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/utils/keybindings.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/utils/keybindings.py @@ -42,6 +42,17 @@ class Keybindings: self.keymap = Gdk.Keymap.get_default() self.configure({}) + def print_keys(self): + print(self.keys) + + def append_bindings(self, combos): + """Accept new binding(s) and reload""" + for item in combos: + method, keys = item.split(":") + self.keys[method] = keys + + self.reload() + def configure(self, bindings): """Accept new bindings and reconfigure with them""" self.keys = bindings