Plugin rework/fixes #8
@@ -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