Compare commits
	
		
			2 Commits
		
	
	
		
			bebe0c7cba
			...
			41f39ba8cc
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 41f39ba8cc | |||
| 51a565a79d | 
| @@ -7,6 +7,7 @@ gi.require_version('Gtk', '3.0') | |||||||
| from gi.repository import Gtk | from gi.repository import Gtk | ||||||
|  |  | ||||||
| # Application imports | # Application imports | ||||||
|  | from plugins.plugin_base import PluginBase | ||||||
|  |  | ||||||
|  |  | ||||||
| # NOTE: Threads WILL NOT die with parent's destruction. | # NOTE: Threads WILL NOT die with parent's destruction. | ||||||
| @@ -24,22 +25,18 @@ def daemon_threaded(fn): | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugin: | class Plugin(PluginBase): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|  |         super().__init__() | ||||||
|  |  | ||||||
|         self.name               = "Favorites"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus |         self.name               = "Favorites"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus | ||||||
|                                                       #       where self.name should not be needed for message comms |                                                       #       where self.name should not be needed for message comms | ||||||
|         self.path               = os.path.dirname(os.path.realpath(__file__)) |         self.path               = os.path.dirname(os.path.realpath(__file__)) | ||||||
|         self._GLADE_FILE        = f"{self.path}/favorites.glade" |         self._GLADE_FILE        = f"{self.path}/favorites.glade" | ||||||
|         self._FAVORITES_FILE    = f"{self.path}/favorites.json" |         self._FAVORITES_FILE    = f"{self.path}/favorites.json" | ||||||
|  |  | ||||||
|         self._builder           = None |  | ||||||
|         self._event_system      = None |  | ||||||
|         self._event_sleep_time  = .5 |  | ||||||
|         self._event_message     = None |  | ||||||
|  |  | ||||||
|         self._favorites_dialog  = None |         self._favorites_dialog  = None | ||||||
|         self._favorites_store   = None |         self._favorites_store   = None | ||||||
|         self._ui_objects        = None |  | ||||||
|         self._favorites         = None |         self._favorites         = None | ||||||
|         self._state             = None |         self._state             = None | ||||||
|         self._selected          = None |         self._selected          = None | ||||||
| @@ -50,12 +47,6 @@ class Plugin: | |||||||
|         button.connect("button-release-event", self._show_favorites_menu) |         button.connect("button-release-event", self._show_favorites_menu) | ||||||
|         return button |         return button | ||||||
|  |  | ||||||
|     def set_fm_event_system(self, fm_event_system): |  | ||||||
|         self._event_system = fm_event_system |  | ||||||
|  |  | ||||||
|     def set_ui_object_collection(self, ui_objects): |  | ||||||
|         self._ui_objects = ui_objects |  | ||||||
|  |  | ||||||
|     def run(self): |     def run(self): | ||||||
|         self._module_event_observer() |         self._module_event_observer() | ||||||
|  |  | ||||||
| @@ -137,31 +128,6 @@ class Plugin: | |||||||
|         if selected: |         if selected: | ||||||
|             self._selected = selected |             self._selected = selected | ||||||
|  |  | ||||||
|     def wait_for_fm_message(self): |  | ||||||
|         while not self._event_message: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     def wait_for_state(self): |     def wait_for_state(self): | ||||||
|         while not self._state: |         while not self._state: | ||||||
|             pass |             pass | ||||||
|  |  | ||||||
|     @daemon_threaded |  | ||||||
|     def _module_event_observer(self): |  | ||||||
|         while True: |  | ||||||
|             time.sleep(self._event_sleep_time) |  | ||||||
|             event = self._event_system.read_module_event() |  | ||||||
|             if event: |  | ||||||
|                 try: |  | ||||||
|                     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}") |  | ||||||
|                             if data: |  | ||||||
|                                 data = method(*(self, *data)) |  | ||||||
|                             else: |  | ||||||
|                                 method(*(self,)) |  | ||||||
|                 except Exception as e: |  | ||||||
|                     print(repr(e)) |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ gi.require_version('Gtk', '3.0') | |||||||
| from gi.repository import Gtk, GLib, Gio | from gi.repository import Gtk, GLib, Gio | ||||||
|  |  | ||||||
| # Application imports | # Application imports | ||||||
|  | from plugins.plugin_base import PluginBase | ||||||
|  |  | ||||||
|  |  | ||||||
| # NOTE: Threads WILL NOT die with parent's destruction. | # NOTE: Threads WILL NOT die with parent's destruction. | ||||||
| @@ -39,19 +40,16 @@ class Properties: | |||||||
|     chmod_stat: str    = None |     chmod_stat: str    = None | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugin: | class Plugin(PluginBase): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|  |         super().__init__() | ||||||
|  |  | ||||||
|         self.path               = os.path.dirname(os.path.realpath(__file__)) |         self.path               = os.path.dirname(os.path.realpath(__file__)) | ||||||
|  |         self._GLADE_FILE        = f"{self.path}/file_properties.glade" | ||||||
|         self.name               = "Properties"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus |         self.name               = "Properties"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus | ||||||
|                                                 #       where self.name should not be needed for message comms |                                                 #       where self.name should not be needed for message comms | ||||||
|         self._GLADE_FILE        = f"{self.path}/file_properties.glade" |  | ||||||
|         self._builder           = None |  | ||||||
|         self._properties_dialog = None |         self._properties_dialog = None | ||||||
|  |  | ||||||
|         self._event_system      = None |  | ||||||
|         self._event_sleep_time  = .5 |  | ||||||
|         self._event_message     = None |  | ||||||
|  |  | ||||||
|         self._file_name         = None |         self._file_name         = None | ||||||
|         self._file_location     = None |         self._file_location     = None | ||||||
|         self._file_target       = None |         self._file_target       = None | ||||||
| @@ -86,6 +84,13 @@ class Plugin: | |||||||
|  |  | ||||||
|  |  | ||||||
|     def get_ui_element(self): |     def get_ui_element(self): | ||||||
|  |         button = Gtk.Button(label=self.name) | ||||||
|  |         button.connect("button-release-event", self._show_properties_page) | ||||||
|  |         return button | ||||||
|  |  | ||||||
|  |     def run(self): | ||||||
|  |         self._module_event_observer() | ||||||
|  |  | ||||||
|         self._builder           = Gtk.Builder() |         self._builder           = Gtk.Builder() | ||||||
|         self._builder.add_from_file(self._GLADE_FILE) |         self._builder.add_from_file(self._GLADE_FILE) | ||||||
|  |  | ||||||
| @@ -100,17 +105,6 @@ class Plugin: | |||||||
|         self._file_owner    = self._builder.get_object("file_owner") |         self._file_owner    = self._builder.get_object("file_owner") | ||||||
|         self._file_group    = self._builder.get_object("file_group") |         self._file_group    = self._builder.get_object("file_group") | ||||||
|  |  | ||||||
|         button = Gtk.Button(label=self.name) |  | ||||||
|         button.connect("button-release-event", self._show_properties_page) |  | ||||||
|         return button |  | ||||||
|  |  | ||||||
|     def set_fm_event_system(self, fm_event_system): |  | ||||||
|         self._event_system = fm_event_system |  | ||||||
|  |  | ||||||
|     def run(self): |  | ||||||
|         self._module_event_observer() |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     @threaded |     @threaded | ||||||
| @@ -248,28 +242,3 @@ class Plugin: | |||||||
|                 return f"{num:3.1f} {unit}{suffix}" |                 return f"{num:3.1f} {unit}{suffix}" | ||||||
|             num /= 1024.0 |             num /= 1024.0 | ||||||
|         return f"{num:.1f} Yi{suffix}" |         return f"{num:.1f} Yi{suffix}" | ||||||
|  |  | ||||||
|     def wait_for_fm_message(self): |  | ||||||
|         while not self._event_message: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     @daemon_threaded |  | ||||||
|     def _module_event_observer(self): |  | ||||||
|         while True: |  | ||||||
|             time.sleep(self._event_sleep_time) |  | ||||||
|             event = self._event_system.read_module_event() |  | ||||||
|             if event: |  | ||||||
|                 try: |  | ||||||
|                     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}") |  | ||||||
|                             if data: |  | ||||||
|                                 data = method(*(self, *data)) |  | ||||||
|                             else: |  | ||||||
|                                 method(*(self,)) |  | ||||||
|                 except Exception as e: |  | ||||||
|                     print(repr(e)) |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| # Python imports | # Python imports | ||||||
| import os, threading, subprocess, time, inspect, requests, shutil | import os, threading, subprocess, inspect, requests, shutil | ||||||
|  |  | ||||||
| # Lib imports | # Lib imports | ||||||
| import gi | import gi | ||||||
| @@ -8,7 +8,8 @@ gi.require_version('GdkPixbuf', '2.0') | |||||||
| from gi.repository import Gtk, GLib, GdkPixbuf | from gi.repository import Gtk, GLib, GdkPixbuf | ||||||
|  |  | ||||||
| # Application imports | # Application imports | ||||||
| from tmdbscraper import scraper | from plugins.plugin_base import PluginBase | ||||||
|  | from .tmdbscraper import scraper | ||||||
|  |  | ||||||
|  |  | ||||||
| # NOTE: Threads WILL NOT die with parent's destruction. | # NOTE: Threads WILL NOT die with parent's destruction. | ||||||
| @@ -26,14 +27,15 @@ def daemon_threaded(fn): | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugin: | class Plugin(PluginBase): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|  |         super().__init__() | ||||||
|  |  | ||||||
|         self.path                   = os.path.dirname(os.path.realpath(__file__)) |         self.path                   = os.path.dirname(os.path.realpath(__file__)) | ||||||
|         self.name                   = "Movie/TV Info"   # NOTE: Need to remove after establishing private bidirectional 1-1 message bus |         self.name                   = "Movie/TV Info"   # NOTE: Need to remove after establishing private bidirectional 1-1 message bus | ||||||
|                                                         #       where self.name should not be needed for message comms |                                                         #       where self.name should not be needed for message comms | ||||||
|         self._GLADE_FILE            = f"{self.path}/movie_tv_info.glade" |         self._GLADE_FILE            = f"{self.path}/movie_tv_info.glade" | ||||||
|  |  | ||||||
|         self._builder               = None |  | ||||||
|         self._dialog                = None |         self._dialog                = None | ||||||
|         self._thumbnail_preview_img = None |         self._thumbnail_preview_img = None | ||||||
|         self._tmdb                  = scraper.get_tmdb_scraper() |         self._tmdb                  = scraper.get_tmdb_scraper() | ||||||
| @@ -43,12 +45,16 @@ class Plugin: | |||||||
|         self._file_location         = None |         self._file_location         = None | ||||||
|         self._trailer_link          = None |         self._trailer_link          = None | ||||||
|  |  | ||||||
|         self._event_system          = None |  | ||||||
|         self._event_sleep_time      = .5 |  | ||||||
|         self._event_message         = None |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def get_ui_element(self): |     def get_ui_element(self): | ||||||
|  |         button = Gtk.Button(label=self.name) | ||||||
|  |         button.connect("button-release-event", self._show_info_page) | ||||||
|  |         return button | ||||||
|  |  | ||||||
|  |     def run(self): | ||||||
|  |         self._module_event_observer() | ||||||
|  |  | ||||||
|         self._builder           = Gtk.Builder() |         self._builder           = Gtk.Builder() | ||||||
|         self._builder.add_from_file(self._GLADE_FILE) |         self._builder.add_from_file(self._GLADE_FILE) | ||||||
|  |  | ||||||
| @@ -72,17 +78,6 @@ class Plugin: | |||||||
|         self._file_hash             = self._builder.get_object("file_hash") |         self._file_hash             = self._builder.get_object("file_hash") | ||||||
|         self._trailer_link          = self._builder.get_object("trailer_link") |         self._trailer_link          = self._builder.get_object("trailer_link") | ||||||
|  |  | ||||||
|         button = Gtk.Button(label=self.name) |  | ||||||
|         button.connect("button-release-event", self._show_info_page) |  | ||||||
|         return button |  | ||||||
|  |  | ||||||
|     def set_fm_event_system(self, fm_event_system): |  | ||||||
|         self._event_system = fm_event_system |  | ||||||
|  |  | ||||||
|     def run(self): |  | ||||||
|         self._module_event_observer() |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     @threaded |     @threaded | ||||||
|     def _show_info_page(self, widget=None, eve=None): |     def _show_info_page(self, widget=None, eve=None): | ||||||
|         self._event_system.push_gui_event([self.name, "get_current_state", ()]) |         self._event_system.push_gui_event([self.name, "get_current_state", ()]) | ||||||
| @@ -186,31 +181,3 @@ class Plugin: | |||||||
|     def set_trailer_link(self, trailer): |     def set_trailer_link(self, trailer): | ||||||
|         if trailer: |         if trailer: | ||||||
|             self._trailer_link.set_uri(f"https://www.youtube.com/watch?v={trailer}") |             self._trailer_link.set_uri(f"https://www.youtube.com/watch?v={trailer}") | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def wait_for_fm_message(self): |  | ||||||
|         while not self._event_message: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     @daemon_threaded |  | ||||||
|     def _module_event_observer(self): |  | ||||||
|         while True: |  | ||||||
|             time.sleep(self._event_sleep_time) |  | ||||||
|             event = self._event_system.read_module_event() |  | ||||||
|             if event: |  | ||||||
|                 try: |  | ||||||
|                     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}") |  | ||||||
|                             if data: |  | ||||||
|                                 data = method(*(self, *data)) |  | ||||||
|                             else: |  | ||||||
|                                 method(*(self,)) |  | ||||||
|                 except Exception as e: |  | ||||||
|                     print(repr(e)) |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ gi.require_version('Gtk', '3.0') | |||||||
| from gi.repository import Gtk, GLib, GObject | from gi.repository import Gtk, GLib, GObject | ||||||
|  |  | ||||||
| # Application imports | # Application imports | ||||||
|  | from plugins.plugin_base import PluginBase | ||||||
|  |  | ||||||
|  |  | ||||||
| # NOTE: Threads WILL NOT die with parent's destruction. | # NOTE: Threads WILL NOT die with parent's destruction. | ||||||
| @@ -74,19 +75,16 @@ grep_result_set  = manager.dict() | |||||||
| file_result_set  = manager.list() | file_result_set  = manager.list() | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugin: | class Plugin(PluginBase): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|  |         super().__init__() | ||||||
|  |  | ||||||
|         self.path              = os.path.dirname(os.path.realpath(__file__)) |         self.path              = os.path.dirname(os.path.realpath(__file__)) | ||||||
|         self.name              = "Search"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus |         self.name              = "Search"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus | ||||||
|                                            #       where self.name should not be needed for message comms |                                            #       where self.name should not be needed for message comms | ||||||
|         self._GLADE_FILE       = f"{self.path}/search_dialog.glade" |         self._GLADE_FILE       = f"{self.path}/search_dialog.glade" | ||||||
|         self._builder          = None |  | ||||||
|         self._search_dialog    = None |         self._search_dialog    = None | ||||||
|  |  | ||||||
|         self._event_system     = None |  | ||||||
|         self._event_sleep_time = .5 |  | ||||||
|         self._event_message    = None |  | ||||||
|  |  | ||||||
|         self._active_path      = None |         self._active_path      = None | ||||||
|         self._file_list        = None |         self._file_list        = None | ||||||
|         self._grep_list        = None |         self._grep_list        = None | ||||||
| @@ -95,6 +93,13 @@ class Plugin: | |||||||
|  |  | ||||||
|  |  | ||||||
|     def get_ui_element(self): |     def get_ui_element(self): | ||||||
|  |         button = Gtk.Button(label=self.name) | ||||||
|  |         button.connect("button-release-event", self._show_grep_list_page) | ||||||
|  |         return button | ||||||
|  |  | ||||||
|  |     def run(self): | ||||||
|  |         self._module_event_observer() | ||||||
|  |  | ||||||
|         self._builder          = Gtk.Builder() |         self._builder          = Gtk.Builder() | ||||||
|         self._builder.add_from_file(self._GLADE_FILE) |         self._builder.add_from_file(self._GLADE_FILE) | ||||||
|  |  | ||||||
| @@ -119,16 +124,6 @@ class Plugin: | |||||||
|         GObject.signal_new("update-grep-ui-signal", self._search_dialog, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT, (GObject.TYPE_PYOBJECT,)) |         GObject.signal_new("update-grep-ui-signal", self._search_dialog, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT, (GObject.TYPE_PYOBJECT,)) | ||||||
|         self._search_dialog.connect("update-grep-ui-signal", self._load_grep_ui) |         self._search_dialog.connect("update-grep-ui-signal", self._load_grep_ui) | ||||||
|  |  | ||||||
|         button = Gtk.Button(label=self.name) |  | ||||||
|         button.connect("button-release-event", self._show_grep_list_page) |  | ||||||
|         return button |  | ||||||
|  |  | ||||||
|     def set_fm_event_system(self, fm_event_system): |  | ||||||
|         self._event_system = fm_event_system |  | ||||||
|  |  | ||||||
|     def run(self): |  | ||||||
|         self._module_event_observer() |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     @daemon_threaded |     @daemon_threaded | ||||||
|     def _show_grep_list_page(self, widget=None, eve=None): |     def _show_grep_list_page(self, widget=None, eve=None): | ||||||
| @@ -234,36 +229,3 @@ class Plugin: | |||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             if debug: |             if debug: | ||||||
|                 print("Couldn't read file. Might be binary or other cause...") |                 print("Couldn't read file. Might be binary or other cause...") | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def clear_children(self, widget: type) -> None: |  | ||||||
|         ''' Clear children of a gtk widget. ''' |  | ||||||
|         for child in widget.get_children(): |  | ||||||
|             widget.remove(child) |  | ||||||
|  |  | ||||||
|     def wait_for_fm_message(self): |  | ||||||
|         while not self._event_message: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     @daemon_threaded |  | ||||||
|     def _module_event_observer(self): |  | ||||||
|         while True: |  | ||||||
|             time.sleep(self._event_sleep_time) |  | ||||||
|             event = self._event_system.read_module_event() |  | ||||||
|             if event: |  | ||||||
|                 try: |  | ||||||
|                     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}") |  | ||||||
|                             if data: |  | ||||||
|                                 data = method(*(self, *data)) |  | ||||||
|                             else: |  | ||||||
|                                 method(*(self,)) |  | ||||||
|                 except Exception as e: |  | ||||||
|                     print(repr(e)) |  | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ gi.require_version('Gtk', '3.0') | |||||||
| from gi.repository import Gtk | from gi.repository import Gtk | ||||||
|  |  | ||||||
| # Application imports | # Application imports | ||||||
|  | from plugins.plugin_base import PluginBase | ||||||
|  |  | ||||||
|  |  | ||||||
| # NOTE: Threads WILL NOT die with parent's destruction. | # NOTE: Threads WILL NOT die with parent's destruction. | ||||||
| @@ -24,13 +25,12 @@ def daemon_threaded(fn): | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugin: | class Plugin(PluginBase): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|  |         super().__init__() | ||||||
|  |  | ||||||
|         self.name               = "Example Plugin"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus |         self.name               = "Example Plugin"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus | ||||||
|                                                     #       where self.name should not be needed for message comms |                                                     #       where self.name should not be needed for message comms | ||||||
|         self._event_system      = None |  | ||||||
|         self._event_sleep_time  = .5 |  | ||||||
|         self._event_message     = None |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def get_ui_element(self): |     def get_ui_element(self): | ||||||
| @@ -38,39 +38,9 @@ class Plugin: | |||||||
|         button.connect("button-release-event", self.send_message) |         button.connect("button-release-event", self.send_message) | ||||||
|         return button |         return button | ||||||
|  |  | ||||||
|     def set_fm_event_system(self, fm_event_system): |  | ||||||
|         self._event_system = fm_event_system |  | ||||||
|  |  | ||||||
|     def run(self): |     def run(self): | ||||||
|         self._module_event_observer() |         self._module_event_observer() | ||||||
|  |  | ||||||
|  |  | ||||||
|     def send_message(self, widget=None, eve=None): |     def send_message(self, widget=None, eve=None): | ||||||
|         message = "Hello, World!" |         message = "Hello, World!" | ||||||
|         self._event_system.push_gui_event([self.name, "display_message", ("warning", message, None)]) |         self._event_system.push_gui_event([self.name, "display_message", ("warning", message, None)]) | ||||||
|  |  | ||||||
|  |  | ||||||
|     def wait_for_fm_message(self): |  | ||||||
|         while not self._event_message: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     @daemon_threaded |  | ||||||
|     def _module_event_observer(self): |  | ||||||
|         while True: |  | ||||||
|             time.sleep(self._event_sleep_time) |  | ||||||
|             event = self._event_system.read_module_event() |  | ||||||
|             if event: |  | ||||||
|                 try: |  | ||||||
|                     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}") |  | ||||||
|                             if data: |  | ||||||
|                                 data = method(*(self, *data)) |  | ||||||
|                             else: |  | ||||||
|                                 method(*(self,)) |  | ||||||
|                 except Exception as e: |  | ||||||
|                     print(repr(e)) |  | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ gi.require_version('GdkPixbuf', '2.0') | |||||||
| from gi.repository import Gtk, GLib, Gio, GdkPixbuf | from gi.repository import Gtk, GLib, Gio, GdkPixbuf | ||||||
|  |  | ||||||
| # Application imports | # Application imports | ||||||
|  | from plugins.plugin_base import PluginBase | ||||||
|  |  | ||||||
|  |  | ||||||
| # NOTE: Threads WILL NOT die with parent's destruction. | # NOTE: Threads WILL NOT die with parent's destruction. | ||||||
| @@ -26,13 +27,15 @@ def daemon_threaded(fn): | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugin: | class Plugin(PluginBase): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|  |         super().__init__() | ||||||
|  |  | ||||||
|         self.path                   = os.path.dirname(os.path.realpath(__file__)) |         self.path                   = os.path.dirname(os.path.realpath(__file__)) | ||||||
|  |         self._GLADE_FILE            = f"{self.path}/re_thumbnailer.glade" | ||||||
|         self.name                   = "VOD Thumbnailer"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus |         self.name                   = "VOD Thumbnailer"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus | ||||||
|                                                          #       where self.name should not be needed for message comms |                                                          #       where self.name should not be needed for message comms | ||||||
|         self._GLADE_FILE            = f"{self.path}/re_thumbnailer.glade" |  | ||||||
|         self._builder               = None |  | ||||||
|         self._thumbnailer_dialog    = None |         self._thumbnailer_dialog    = None | ||||||
|         self._thumbnail_preview_img = None |         self._thumbnail_preview_img = None | ||||||
|         self._scrub_step            = None |         self._scrub_step            = None | ||||||
| @@ -41,13 +44,15 @@ class Plugin: | |||||||
|         self._file_hash             = None |         self._file_hash             = None | ||||||
|         self._state                 = None |         self._state                 = None | ||||||
|  |  | ||||||
|         self._event_system          = None |  | ||||||
|         self._event_sleep_time      = .5 |  | ||||||
|         self._event_message         = None |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def get_ui_element(self): |     def get_ui_element(self): | ||||||
|  |         button = Gtk.Button(label=self.name) | ||||||
|  |         button.connect("button-release-event", self._show_thumbnailer_page) | ||||||
|  |         return button | ||||||
|  |  | ||||||
|  |     def run(self): | ||||||
|  |         self._module_event_observer() | ||||||
|  |  | ||||||
|         self._builder           = Gtk.Builder() |         self._builder           = Gtk.Builder() | ||||||
|         self._builder.add_from_file(self._GLADE_FILE) |         self._builder.add_from_file(self._GLADE_FILE) | ||||||
|  |  | ||||||
| @@ -70,18 +75,6 @@ class Plugin: | |||||||
|         self._thumbnail_preview_img = self._builder.get_object("thumbnail_preview_img") |         self._thumbnail_preview_img = self._builder.get_object("thumbnail_preview_img") | ||||||
|         self._file_hash             = self._builder.get_object("file_hash") |         self._file_hash             = self._builder.get_object("file_hash") | ||||||
|  |  | ||||||
|         button = Gtk.Button(label=self.name) |  | ||||||
|         button.connect("button-release-event", self._show_thumbnailer_page) |  | ||||||
|         return button |  | ||||||
|  |  | ||||||
|     def set_fm_event_system(self, fm_event_system): |  | ||||||
|         self._event_system = fm_event_system |  | ||||||
|  |  | ||||||
|     def run(self): |  | ||||||
|         self._module_event_observer() |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     @threaded |     @threaded | ||||||
|     def _show_thumbnailer_page(self, widget=None, eve=None): |     def _show_thumbnailer_page(self, widget=None, eve=None): | ||||||
| @@ -142,30 +135,3 @@ class Plugin: | |||||||
|         self._file_name.set_text(parts[ len(parts) - 1 ]) |         self._file_name.set_text(parts[ len(parts) - 1 ]) | ||||||
|         self._file_location.set_text(path) |         self._file_location.set_text(path) | ||||||
|         self._file_hash.set_text(file_hash) |         self._file_hash.set_text(file_hash) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def wait_for_fm_message(self): |  | ||||||
|         while not self._event_message: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     @daemon_threaded |  | ||||||
|     def _module_event_observer(self): |  | ||||||
|         while True: |  | ||||||
|             time.sleep(self._event_sleep_time) |  | ||||||
|             event = self._event_system.read_module_event() |  | ||||||
|             if event: |  | ||||||
|                 try: |  | ||||||
|                     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}") |  | ||||||
|                             if data: |  | ||||||
|                                 data = method(*(self, *data)) |  | ||||||
|                             else: |  | ||||||
|                                 method(*(self,)) |  | ||||||
|                 except Exception as e: |  | ||||||
|                     print(repr(e)) |  | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ gi.require_version('Gtk', '3.0') | |||||||
| from gi.repository import Gtk | from gi.repository import Gtk | ||||||
|  |  | ||||||
| # Application imports | # Application imports | ||||||
|  | from plugins.plugin_base import PluginBase | ||||||
|  |  | ||||||
|  |  | ||||||
| # NOTE: Threads WILL NOT die with parent's destruction. | # NOTE: Threads WILL NOT die with parent's destruction. | ||||||
| @@ -24,13 +25,13 @@ def daemon_threaded(fn): | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugin: | class Plugin(PluginBase): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|  |         super().__init__() | ||||||
|  |  | ||||||
|  |         self.path              = os.path.dirname(os.path.realpath(__file__)) | ||||||
|         self.name              = "Youtube Download"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus |         self.name              = "Youtube Download"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus | ||||||
|                                                      #       where self.name should not be needed for message comms |                                                      #       where self.name should not be needed for message comms | ||||||
|         self._event_system     = None |  | ||||||
|         self._event_sleep_time = .5 |  | ||||||
|         self._event_message    = None |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def get_ui_element(self): |     def get_ui_element(self): | ||||||
| @@ -38,9 +39,6 @@ class Plugin: | |||||||
|         button.connect("button-release-event", self._do_download) |         button.connect("button-release-event", self._do_download) | ||||||
|         return button |         return button | ||||||
|  |  | ||||||
|     def set_fm_event_system(self, fm_event_system): |  | ||||||
|         self._event_system = fm_event_system |  | ||||||
|  |  | ||||||
|     def run(self): |     def run(self): | ||||||
|         self._module_event_observer() |         self._module_event_observer() | ||||||
|  |  | ||||||
| @@ -53,29 +51,3 @@ class Plugin: | |||||||
|         state = self._event_message |         state = self._event_message | ||||||
|         subprocess.Popen([f'{self.path}/download.sh' , state.tab.get_current_directory()]) |         subprocess.Popen([f'{self.path}/download.sh' , state.tab.get_current_directory()]) | ||||||
|         self._event_message = None |         self._event_message = None | ||||||
|  |  | ||||||
|  |  | ||||||
|     def wait_for_fm_message(self): |  | ||||||
|         while not self._event_message: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     @daemon_threaded |  | ||||||
|     def _module_event_observer(self): |  | ||||||
|         while True: |  | ||||||
|             time.sleep(self._event_sleep_time) |  | ||||||
|             event = self._event_system.read_module_event() |  | ||||||
|             if event: |  | ||||||
|                 try: |  | ||||||
|                     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}") |  | ||||||
|                             if data: |  | ||||||
|                                 data = method(*(self, *data)) |  | ||||||
|                             else: |  | ||||||
|                                 method(*(self,)) |  | ||||||
|                 except Exception as e: |  | ||||||
|                     print(repr(e)) |  | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ class Application(IPCServer): | |||||||
|                     message = f"FILE|{args.new_tab}" |                     message = f"FILE|{args.new_tab}" | ||||||
|                     self.send_ipc_message(message) |                     self.send_ipc_message(message) | ||||||
|  |  | ||||||
|                 raise App_Launch_Exception("IPC Server Exists: Will send path(s) to it and close...\nNote: If no fm exists, remove /tmp/solarfm-ipc.sock") |                 raise App_Launch_Exception(f"IPC Server Exists: Will send path(s) to it and close...\nNote: If no fm exists, remove /tmp/{app_name}-ipc.sock") | ||||||
|  |  | ||||||
|  |  | ||||||
|         settings = Settings() |         settings = Settings() | ||||||
|   | |||||||
| @@ -9,7 +9,11 @@ from os.path import join | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugin: | class ManifestProcessorException(Exception): | ||||||
|  |     ... | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class PluginInfo: | ||||||
|     path: str       = None |     path: str       = None | ||||||
|     name: str       = None |     name: str       = None | ||||||
|     author: str     = None |     author: str     = None | ||||||
| @@ -23,7 +27,7 @@ class ManifestProcessor: | |||||||
|     def __init__(self, path, builder): |     def __init__(self, path, builder): | ||||||
|         manifest = join(path, "manifest.json") |         manifest = join(path, "manifest.json") | ||||||
|         if not os.path.exists(manifest): |         if not os.path.exists(manifest): | ||||||
|             raise Exception("Invalid Plugin Structure: Plugin doesn't have 'manifest.json'. Aboarting load...") |             raise ManifestProcessorException("Invalid Plugin Structure: Plugin doesn't have 'manifest.json'. Aboarting load...") | ||||||
|  |  | ||||||
|         self._path    = path |         self._path    = path | ||||||
|         self._builder = builder |         self._builder = builder | ||||||
| @@ -32,8 +36,8 @@ class ManifestProcessor: | |||||||
|             self._manifest = data["manifest"] |             self._manifest = data["manifest"] | ||||||
|             self._plugin   = self.collect_info() |             self._plugin   = self.collect_info() | ||||||
|  |  | ||||||
|     def collect_info(self) -> Plugin: |     def collect_info(self) -> PluginInfo: | ||||||
|         plugin          = Plugin() |         plugin          = PluginInfo() | ||||||
|         plugin.path     = self._path |         plugin.path     = self._path | ||||||
|         plugin.name     = self._manifest["name"] |         plugin.name     = self._manifest["name"] | ||||||
|         plugin.author   = self._manifest["author"] |         plugin.author   = self._manifest["author"] | ||||||
| @@ -58,13 +62,13 @@ class ManifestProcessor: | |||||||
|                     if "ui_target_id" in keys: |                     if "ui_target_id" in keys: | ||||||
|                         loading_data["ui_target"] = self._builder.get_object(requests["ui_target_id"]) |                         loading_data["ui_target"] = self._builder.get_object(requests["ui_target_id"]) | ||||||
|                         if loading_data["ui_target"] == None: |                         if loading_data["ui_target"] == None: | ||||||
|                             raise Exception('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...') |                             raise ManifestProcessorException('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...') | ||||||
|                     else: |                     else: | ||||||
|                         raise Exception('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...') |                         raise ManifestProcessorException('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...') | ||||||
|                 else: |                 else: | ||||||
|                     loading_data["ui_target"] = self._builder.get_object(requests["ui_target"]) |                     loading_data["ui_target"] = self._builder.get_object(requests["ui_target"]) | ||||||
|             else: |             else: | ||||||
|                 raise Exception('Unknown "ui_target" given in requests.') |                 raise ManifestProcessorException('Unknown "ui_target" given in requests.') | ||||||
|  |  | ||||||
|         if "pass_fm_events" in keys: |         if "pass_fm_events" in keys: | ||||||
|             if requests["pass_fm_events"] in ["true"]: |             if requests["pass_fm_events"] in ["true"]: | ||||||
|   | |||||||
| @@ -0,0 +1,55 @@ | |||||||
|  | # Python imports | ||||||
|  | import os, time | ||||||
|  |  | ||||||
|  | # Lib imports | ||||||
|  |  | ||||||
|  | # Application imports | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class PluginBase: | ||||||
|  |     def __init__(self): | ||||||
|  |         self.name               = "Example Plugin"  # NOTE: Need to remove after establishing private bidirectional 1-1 message bus | ||||||
|  |                                                     #       where self.name should not be needed for message comms | ||||||
|  |  | ||||||
|  |         self._builder           = None | ||||||
|  |         self._ui_objects        = None | ||||||
|  |  | ||||||
|  |         self._event_system      = None | ||||||
|  |         self._event_sleep_time  = .5 | ||||||
|  |         self._event_message     = None | ||||||
|  |  | ||||||
|  |     def set_fm_event_system(self, fm_event_system): | ||||||
|  |         self._event_system = fm_event_system | ||||||
|  |  | ||||||
|  |     def set_ui_object_collection(self, ui_objects): | ||||||
|  |         self._ui_objects = ui_objects | ||||||
|  |  | ||||||
|  |     def wait_for_fm_message(self): | ||||||
|  |         while not self._event_message: | ||||||
|  |             pass | ||||||
|  |  | ||||||
|  |     def clear_children(self, widget: type) -> None: | ||||||
|  |         ''' Clear children of a gtk widget. ''' | ||||||
|  |         for child in widget.get_children(): | ||||||
|  |             widget.remove(child) | ||||||
|  |  | ||||||
|  |     @daemon_threaded | ||||||
|  |     def _module_event_observer(self): | ||||||
|  |         while True: | ||||||
|  |             time.sleep(self._event_sleep_time) | ||||||
|  |             event = self._event_system.read_module_event() | ||||||
|  |             if event: | ||||||
|  |                 try: | ||||||
|  |                     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}") | ||||||
|  |                             if data: | ||||||
|  |                                 data = method(*(self, *data)) | ||||||
|  |                             else: | ||||||
|  |                                 method(*(self,)) | ||||||
|  |                 except Exception as e: | ||||||
|  |                     print(repr(e)) | ||||||
| @@ -8,15 +8,22 @@ gi.require_version('Gtk', '3.0') | |||||||
| from gi.repository import Gtk, Gio | from gi.repository import Gtk, Gio | ||||||
|  |  | ||||||
| # Application imports | # Application imports | ||||||
| from .manifest import Plugin, ManifestProcessor | from .manifest import PluginInfo, ManifestProcessor | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class InvalidPluginException(Exception): | ||||||
|  |     ... | ||||||
|  |  | ||||||
|  |  | ||||||
| class Plugins: | class Plugins: | ||||||
|     """Plugins controller""" |     """Plugins controller""" | ||||||
|  |  | ||||||
|     def __init__(self, settings: type): |     def __init__(self, settings: type): | ||||||
|  |         path                      = os.path.dirname(os.path.realpath(__file__)) | ||||||
|  |         sys.path.insert(0, path)  # NOTE: I think I'm not using this correctly... | ||||||
|  |  | ||||||
|         self._settings            = settings |         self._settings            = settings | ||||||
|         self._builder             = self._settings.get_builder() |         self._builder             = self._settings.get_builder() | ||||||
|         self._plugins_path        = self._settings.get_plugins_path() |         self._plugins_path        = self._settings.get_plugins_path() | ||||||
| @@ -51,7 +58,7 @@ class Plugins: | |||||||
|                 manifest = ManifestProcessor(path, self._builder) |                 manifest = ManifestProcessor(path, self._builder) | ||||||
|  |  | ||||||
|                 if not os.path.exists(target): |                 if not os.path.exists(target): | ||||||
|                     raise Exception("Invalid Plugin Structure: Plugin doesn't have 'plugin.py'. Aboarting load...") |                     raise InvalidPluginException("Invalid Plugin Structure: Plugin doesn't have 'plugin.py'. Aboarting load...") | ||||||
|  |  | ||||||
|                 plugin, loading_data = manifest.get_loading_data() |                 plugin, loading_data = manifest.get_loading_data() | ||||||
|                 module               = self.load_plugin_module(path, folder, target) |                 module               = self.load_plugin_module(path, folder, target) | ||||||
| @@ -65,17 +72,15 @@ class Plugins: | |||||||
|  |  | ||||||
|     def load_plugin_module(self, path, folder, target): |     def load_plugin_module(self, path, folder, target): | ||||||
|         os.chdir(path) |         os.chdir(path) | ||||||
|         sys.path.insert(0, path)  # NOTE: I think I'm not using this correctly... |         spec   = importlib.util.spec_from_file_location(folder, target, submodule_search_locations=path) | ||||||
|         # The folder and target aren't working to create parent package references, so using as stopgap. |  | ||||||
|         # The above is probably polutling import logic and will cause unforseen import issues. |  | ||||||
|         spec   = importlib.util.spec_from_file_location(folder, target) |  | ||||||
|         module = importlib.util.module_from_spec(spec) |         module = importlib.util.module_from_spec(spec) | ||||||
|  |         sys.modules[folder] = module | ||||||
|         spec.loader.exec_module(module) |         spec.loader.exec_module(module) | ||||||
|  |  | ||||||
|         return module |         return module | ||||||
|  |  | ||||||
|  |  | ||||||
|     def execute_plugin(self, module: type, plugin: Plugin, loading_data: []): |     def execute_plugin(self, module: type, plugin: PluginInfo, loading_data: []): | ||||||
|         plugin.reference = module.Plugin() |         plugin.reference = module.Plugin() | ||||||
|         keys             = loading_data.keys() |         keys             = loading_data.keys() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,6 +7,10 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class EventSystemPushException(Exception): | ||||||
|  |     ... | ||||||
|  |  | ||||||
|  |  | ||||||
| class EventSystem: | class EventSystem: | ||||||
|     """ Inheret IPCServerMixin. Create an pub/sub systems. """ |     """ Inheret IPCServerMixin. Create an pub/sub systems. """ | ||||||
|  |  | ||||||
| @@ -37,14 +41,14 @@ class EventSystem: | |||||||
|             self._gui_events.append(event) |             self._gui_events.append(event) | ||||||
|             return None |             return None | ||||||
|  |  | ||||||
|         raise Exception("Invald event format! Please do:  ['sender_id': str, method_target: method, (data,): any]") |         raise EventSystemPushException("Invald event format! Please do:  ['sender_id': str, method_target: method, (data,): any]") | ||||||
|  |  | ||||||
|     def push_module_event(self, event: list) -> None: |     def push_module_event(self, event: list) -> None: | ||||||
|         if len(event) == 3: |         if len(event) == 3: | ||||||
|             self._module_events.append(event) |             self._module_events.append(event) | ||||||
|             return None |             return None | ||||||
|  |  | ||||||
|         raise Exception("Invald event format! Please do:  ['target_id': str, method_target: method, (data,): any]") |         raise EventSystemPushException("Invald event format! Please do:  ['target_id': str, method_target: method, (data,): any]") | ||||||
|  |  | ||||||
|     def read_gui_event(self) -> list: |     def read_gui_event(self) -> list: | ||||||
|         return self._gui_events[0] if self._gui_events else None |         return self._gui_events[0] if self._gui_events else None | ||||||
|   | |||||||
| @@ -16,11 +16,11 @@ class IPCServer: | |||||||
|         self._ipc_port        = 4848 |         self._ipc_port        = 4848 | ||||||
|         self._ipc_address     = ipc_address |         self._ipc_address     = ipc_address | ||||||
|         self._conn_type       = conn_type |         self._conn_type       = conn_type | ||||||
|         self._ipc_authkey     = b'solarfm-ipc' |         self._ipc_authkey     = b'' + bytes(f'{app_name}-ipc', 'utf-8') | ||||||
|         self._ipc_timeout     = 15.0 |         self._ipc_timeout     = 15.0 | ||||||
|  |  | ||||||
|         if conn_type == "socket": |         if conn_type == "socket": | ||||||
|             self._ipc_address = '/tmp/solarfm-ipc.sock' |             self._ipc_address = f'/tmp/{app_name}-ipc.sock' | ||||||
|         elif conn_type == "full_network": |         elif conn_type == "full_network": | ||||||
|             self._ipc_address = '0.0.0.0' |             self._ipc_address = '0.0.0.0' | ||||||
|         elif conn_type == "full_network_unsecured": |         elif conn_type == "full_network_unsecured": | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user