develop #4
							
								
								
									
										3
									
								
								plugins/file_properties/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								plugins/file_properties/__main__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    Pligin Package
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
							
								
								
									
										12
									
								
								plugins/file_properties/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								plugins/file_properties/manifest.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "manifest": {
 | 
				
			||||||
 | 
					        "name": "Properties",
 | 
				
			||||||
 | 
					        "author": "ITDominator",
 | 
				
			||||||
 | 
					        "version": "0.0.1",
 | 
				
			||||||
 | 
					        "support": "",
 | 
				
			||||||
 | 
					        "requests": {
 | 
				
			||||||
 | 
					            "ui_target": "context_menu",
 | 
				
			||||||
 | 
					            "pass_fm_events": "true"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -25,17 +25,6 @@ def daemon_threaded(fn):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Manifest:
 | 
					 | 
				
			||||||
    path: str     = os.path.dirname(os.path.realpath(__file__))
 | 
					 | 
				
			||||||
    name: str     = "Properties"
 | 
					 | 
				
			||||||
    author: str   = "ITDominator"
 | 
					 | 
				
			||||||
    version: str  = "0.0.1"
 | 
					 | 
				
			||||||
    support: str  = ""
 | 
					 | 
				
			||||||
    requests: {}  = {
 | 
					 | 
				
			||||||
        'ui_target': "context_menu",
 | 
					 | 
				
			||||||
        'pass_fm_events': "true"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Properties:
 | 
					class Properties:
 | 
				
			||||||
    file_uri: str      = None
 | 
					    file_uri: str      = None
 | 
				
			||||||
    file_name: str     = None
 | 
					    file_name: str     = None
 | 
				
			||||||
@@ -50,8 +39,11 @@ class Properties:
 | 
				
			|||||||
    chmod_stat: str    = None
 | 
					    chmod_stat: str    = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Plugin(Manifest):
 | 
					class Plugin:
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self.path               = os.path.dirname(os.path.realpath(__file__))
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
        self._GLADE_FILE        = f"{self.path}/file_properties.glade"
 | 
					        self._GLADE_FILE        = f"{self.path}/file_properties.glade"
 | 
				
			||||||
        self._builder           = None
 | 
					        self._builder           = None
 | 
				
			||||||
        self._properties_dialog = None
 | 
					        self._properties_dialog = None
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								plugins/searcher/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								plugins/searcher/__main__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    Pligin Package
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
							
								
								
									
										13
									
								
								plugins/searcher/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								plugins/searcher/manifest.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "manifest": {
 | 
				
			||||||
 | 
					        "name": "Search",
 | 
				
			||||||
 | 
					        "author": "ITDominator",
 | 
				
			||||||
 | 
					        "version": "0.0.1",
 | 
				
			||||||
 | 
					        "support": "",
 | 
				
			||||||
 | 
					        "requests": {
 | 
				
			||||||
 | 
					            "ui_target": "context_menu",
 | 
				
			||||||
 | 
					            "pass_fm_events": "true",
 | 
				
			||||||
 | 
					            "bind_keys": ["Search||_show_grep_list_page:<Control>f"]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -25,21 +25,6 @@ def daemon_threaded(fn):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Manifest:
 | 
					 | 
				
			||||||
    path: str     = os.path.dirname(os.path.realpath(__file__))
 | 
					 | 
				
			||||||
    name: str     = "Search"
 | 
					 | 
				
			||||||
    author: str   = "ITDominator"
 | 
					 | 
				
			||||||
    version: str  = "0.0.1"
 | 
					 | 
				
			||||||
    support: str  = ""
 | 
					 | 
				
			||||||
    requests: {}  = {
 | 
					 | 
				
			||||||
        'ui_target': "context_menu",
 | 
					 | 
				
			||||||
        'pass_fm_events': "true",
 | 
					 | 
				
			||||||
        'bind_keys': [f"{name}||_show_grep_list_page:<Control>f"]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FilePreviewWidget(Gtk.LinkButton):
 | 
					class FilePreviewWidget(Gtk.LinkButton):
 | 
				
			||||||
    def __init__(self, path, file):
 | 
					    def __init__(self, path, file):
 | 
				
			||||||
        super(FilePreviewWidget, self).__init__()
 | 
					        super(FilePreviewWidget, self).__init__()
 | 
				
			||||||
@@ -89,8 +74,11 @@ grep_result_set  = manager.dict()
 | 
				
			|||||||
file_result_set  = manager.list()
 | 
					file_result_set  = manager.list()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Plugin(Manifest):
 | 
					class Plugin:
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self.path              = os.path.dirname(os.path.realpath(__file__))
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
        self._GLADE_FILE       = f"{self.path}/search_dialog.glade"
 | 
					        self._GLADE_FILE       = f"{self.path}/search_dialog.glade"
 | 
				
			||||||
        self._builder          = None
 | 
					        self._builder          = None
 | 
				
			||||||
        self._search_dialog    = None
 | 
					        self._search_dialog    = None
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								plugins/template/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								plugins/template/__main__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    Pligin Package
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
							
								
								
									
										13
									
								
								plugins/template/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								plugins/template/manifest.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "manifest": {
 | 
				
			||||||
 | 
					        "name": "Example Plugin",
 | 
				
			||||||
 | 
					        "author": "John Doe",
 | 
				
			||||||
 | 
					        "version": "0.0.1",
 | 
				
			||||||
 | 
					        "support": "",
 | 
				
			||||||
 | 
					        "requests": {
 | 
				
			||||||
 | 
					            "ui_target": "plugin_control_list",
 | 
				
			||||||
 | 
					            "pass_fm_events": "true",
 | 
				
			||||||
 | 
					            "bind_keys": ["Example Plugin||send_message:<Control>f"]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -24,21 +24,10 @@ def daemon_threaded(fn):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Manifest:
 | 
					class Plugin:
 | 
				
			||||||
    path: str     = os.path.dirname(os.path.realpath(__file__))
 | 
					 | 
				
			||||||
    name: str     = "Example Plugin"
 | 
					 | 
				
			||||||
    author: str   = "John Doe"
 | 
					 | 
				
			||||||
    version: str  = "0.0.1"
 | 
					 | 
				
			||||||
    support: str  = ""
 | 
					 | 
				
			||||||
    requests: {}  = {
 | 
					 | 
				
			||||||
        'ui_target': "plugin_control_list",
 | 
					 | 
				
			||||||
        'pass_fm_events': "true",
 | 
					 | 
				
			||||||
        'bind_keys': [f"{name}||send_message:<Control>f"]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Plugin(Manifest):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					    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._event_system      = None
 | 
					        self._event_system      = None
 | 
				
			||||||
        self._event_sleep_time  = .5
 | 
					        self._event_sleep_time  = .5
 | 
				
			||||||
        self._event_message     = None
 | 
					        self._event_message     = None
 | 
				
			||||||
@@ -58,7 +47,6 @@ class Plugin(Manifest):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def send_message(self, widget=None, eve=None):
 | 
					    def send_message(self, widget=None, eve=None):
 | 
				
			||||||
        message = "Hello, World!"
 | 
					        message = "Hello, World!"
 | 
				
			||||||
        print("here")
 | 
					 | 
				
			||||||
        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)])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								plugins/vod_thumbnailer/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								plugins/vod_thumbnailer/__main__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    Pligin Package
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
							
								
								
									
										12
									
								
								plugins/vod_thumbnailer/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								plugins/vod_thumbnailer/manifest.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "manifest": {
 | 
				
			||||||
 | 
					        "name": "VOD Thumbnailer",
 | 
				
			||||||
 | 
					        "author": "ITDominator",
 | 
				
			||||||
 | 
					        "version": "0.0.1",
 | 
				
			||||||
 | 
					        "support": "",
 | 
				
			||||||
 | 
					        "requests": {
 | 
				
			||||||
 | 
					            "ui_target": "context_menu",
 | 
				
			||||||
 | 
					            "pass_fm_events": "true"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -26,19 +26,11 @@ def daemon_threaded(fn):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Manifest:
 | 
					class Plugin:
 | 
				
			||||||
    path: str     = os.path.dirname(os.path.realpath(__file__))
 | 
					 | 
				
			||||||
    name: str     = "VOD Thumbnailer"
 | 
					 | 
				
			||||||
    author: str   = "ITDominator"
 | 
					 | 
				
			||||||
    version: str  = "0.0.1"
 | 
					 | 
				
			||||||
    support: str  = ""
 | 
					 | 
				
			||||||
    requests: {}  = {
 | 
					 | 
				
			||||||
        'ui_target': "context_menu",
 | 
					 | 
				
			||||||
        'pass_fm_events': "true"
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Plugin(Manifest):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self.path                   = os.path.dirname(os.path.realpath(__file__))
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
        self._GLADE_FILE            = f"{self.path}/re_thumbnailer.glade"
 | 
					        self._GLADE_FILE            = f"{self.path}/re_thumbnailer.glade"
 | 
				
			||||||
        self._builder               = None
 | 
					        self._builder               = None
 | 
				
			||||||
        self._thumbnailer_dialog    = None
 | 
					        self._thumbnailer_dialog    = None
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								plugins/youtube_download/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								plugins/youtube_download/__main__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    Pligin Package
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
							
								
								
									
										12
									
								
								plugins/youtube_download/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								plugins/youtube_download/manifest.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "manifest": {
 | 
				
			||||||
 | 
					        "name": "Youtube Download",
 | 
				
			||||||
 | 
					        "author": "ITDominator",
 | 
				
			||||||
 | 
					        "version": "0.0.1",
 | 
				
			||||||
 | 
					        "support": "",
 | 
				
			||||||
 | 
					        "requests": {
 | 
				
			||||||
 | 
					            "ui_target": "plugin_control_list",
 | 
				
			||||||
 | 
					            "pass_fm_events": "true"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -24,21 +24,10 @@ def daemon_threaded(fn):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Manifest:
 | 
					class Plugin:
 | 
				
			||||||
    path: str     = os.path.dirname(os.path.realpath(__file__))
 | 
					 | 
				
			||||||
    name: str     = "Youtube Download"
 | 
					 | 
				
			||||||
    author: str   = "ITDominator"
 | 
					 | 
				
			||||||
    version: str  = "0.0.1"
 | 
					 | 
				
			||||||
    support: str  = ""
 | 
					 | 
				
			||||||
    requests: {}  = {
 | 
					 | 
				
			||||||
        'ui_target': "plugin_control_list",
 | 
					 | 
				
			||||||
        'pass_fm_events': "true"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Plugin(Manifest):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        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
 | 
				
			||||||
        self._event_system     = None
 | 
					        self._event_system     = None
 | 
				
			||||||
        self._event_sleep_time = .5
 | 
					        self._event_sleep_time = .5
 | 
				
			||||||
        self._event_message    = None
 | 
					        self._event_message    = None
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,16 +4,18 @@ import builtins, threading
 | 
				
			|||||||
# Lib imports
 | 
					# Lib imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application imports
 | 
					# Application imports
 | 
				
			||||||
from utils.ipc_server import IPCServer
 | 
					from utils.event_system import EventSystem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# NOTE: Threads will not die with parent's destruction
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# NOTE: Threads WILL NOT die with parent's destruction.
 | 
				
			||||||
def threaded_wrapper(fn):
 | 
					def threaded_wrapper(fn):
 | 
				
			||||||
    def wrapper(*args, **kwargs):
 | 
					    def wrapper(*args, **kwargs):
 | 
				
			||||||
        threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start()
 | 
					        threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start()
 | 
				
			||||||
    return wrapper
 | 
					    return wrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# NOTE: Insure threads die with parent's destruction
 | 
					# NOTE: Threads WILL die with parent's destruction.
 | 
				
			||||||
def daemon_threaded_wrapper(fn):
 | 
					def daemon_threaded_wrapper(fn):
 | 
				
			||||||
    def wrapper(*args, **kwargs):
 | 
					    def wrapper(*args, **kwargs):
 | 
				
			||||||
        threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
 | 
					        threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
 | 
				
			||||||
@@ -22,71 +24,12 @@ def daemon_threaded_wrapper(fn):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class EventSystem(IPCServer):
 | 
					 | 
				
			||||||
    """ Inheret IPCServerMixin. Create an pub/sub systems. """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        super(EventSystem, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # NOTE: The format used is list of ['who', target, (data,)] Where:
 | 
					 | 
				
			||||||
        #             who is the sender or target ID and is used for context and control flow,
 | 
					 | 
				
			||||||
        #             method_target is the method to call,
 | 
					 | 
				
			||||||
        #             data is the method parameters OR message data to give
 | 
					 | 
				
			||||||
        #       Where data may be any kind of data
 | 
					 | 
				
			||||||
        self._gui_events    = []
 | 
					 | 
				
			||||||
        self._module_events = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Makeshift "events" system FIFO
 | 
					 | 
				
			||||||
    def _pop_gui_event(self) -> None:
 | 
					 | 
				
			||||||
        if len(self._gui_events) > 0:
 | 
					 | 
				
			||||||
            return self._gui_events.pop(0)
 | 
					 | 
				
			||||||
        return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _pop_module_event(self) -> None:
 | 
					 | 
				
			||||||
        if len(self._module_events) > 0:
 | 
					 | 
				
			||||||
            return self._module_events.pop(0)
 | 
					 | 
				
			||||||
        return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def push_gui_event(self, event: list) -> None:
 | 
					 | 
				
			||||||
        if len(event) == 3:
 | 
					 | 
				
			||||||
            self._gui_events.append(event)
 | 
					 | 
				
			||||||
            return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        raise Exception("Invald event format! Please do:  ['sender_id': str, method_target: method, (data,): any]")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def push_module_event(self, event: list) -> None:
 | 
					 | 
				
			||||||
        if len(event) == 3:
 | 
					 | 
				
			||||||
            self._module_events.append(event)
 | 
					 | 
				
			||||||
            return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        raise Exception("Invald event format! Please do:  ['target_id': str, method_target: method, (data,): any]")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def read_gui_event(self) -> list:
 | 
					 | 
				
			||||||
        return self._gui_events[0] if self._gui_events else None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def read_module_event(self) -> list:
 | 
					 | 
				
			||||||
        return self._module_events[0] if self._module_events else None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def consume_gui_event(self) -> list:
 | 
					 | 
				
			||||||
        return self._pop_gui_event()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def consume_module_event(self) -> list:
 | 
					 | 
				
			||||||
        return self._pop_module_event()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class EndpointRegistry():
 | 
					class EndpointRegistry():
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        self._endpoints = {}
 | 
					        self._endpoints = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def register(self, rule, **options):
 | 
					    def register(self, rule, **options):
 | 
				
			||||||
        def decorator(f):
 | 
					        def decorator(f):
 | 
				
			||||||
            _endpoint = options.pop("endpoint", None)
 | 
					 | 
				
			||||||
            self._endpoints[rule] = f
 | 
					            self._endpoints[rule] = f
 | 
				
			||||||
            return f
 | 
					            return f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,31 +4,33 @@ import os, inspect, time
 | 
				
			|||||||
# Lib imports
 | 
					# Lib imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application imports
 | 
					# Application imports
 | 
				
			||||||
from __builtins__ import EventSystem
 | 
					from __builtins__ import *
 | 
				
			||||||
 | 
					from utils.ipc_server import IPCServer
 | 
				
			||||||
from utils.settings import Settings
 | 
					from utils.settings import Settings
 | 
				
			||||||
from core.controller import Controller
 | 
					from core.controller import Controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Application(IPCServer):
 | 
				
			||||||
class Application(EventSystem):
 | 
					 | 
				
			||||||
    """ Create Settings and Controller classes. Bind signal to Builder. Inherit from Builtins to bind global methods and classes. """
 | 
					    """ Create Settings and Controller classes. Bind signal to Builder. Inherit from Builtins to bind global methods and classes. """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, args, unknownargs):
 | 
					    def __init__(self, args, unknownargs):
 | 
				
			||||||
 | 
					        super(Application, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not trace_debug:
 | 
					        if not trace_debug:
 | 
				
			||||||
            event_system.create_ipc_listener()
 | 
					            self.create_ipc_listener()
 | 
				
			||||||
            time.sleep(0.05)
 | 
					            time.sleep(0.05)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if not event_system.is_ipc_alive:
 | 
					            if not self.is_ipc_alive:
 | 
				
			||||||
                if unknownargs:
 | 
					                if unknownargs:
 | 
				
			||||||
                    for arg in unknownargs:
 | 
					                    for arg in unknownargs:
 | 
				
			||||||
                        if os.path.isdir(arg):
 | 
					                        if os.path.isdir(arg):
 | 
				
			||||||
                            message = f"FILE|{arg}"
 | 
					                            message = f"FILE|{arg}"
 | 
				
			||||||
                            event_system.send_ipc_message(message)
 | 
					                            self.send_ipc_message(message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if args.new_tab and os.path.isdir(args.new_tab):
 | 
					                if args.new_tab and os.path.isdir(args.new_tab):
 | 
				
			||||||
                    message = f"FILE|{args.new_tab}"
 | 
					                    message = f"FILE|{args.new_tab}"
 | 
				
			||||||
                    event_system.send_ipc_message(message)
 | 
					                    self.send_ipc_message(message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                raise Exception("IPC Server Exists: Will send path(s) to it and close...\nNote: If no fm exists, remove /tmp/solarfm-ipc.sock")
 | 
					                raise Exception("IPC Server Exists: Will send path(s) to it and close...\nNote: If no fm exists, remove /tmp/solarfm-ipc.sock")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,6 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tear_down(self, widget=None, eve=None):
 | 
					    def tear_down(self, widget=None, eve=None):
 | 
				
			||||||
        event_system.send_ipc_message("close server")
 | 
					 | 
				
			||||||
        self.fm_controller.save_state()
 | 
					        self.fm_controller.save_state()
 | 
				
			||||||
        time.sleep(event_sleep_time)
 | 
					        time.sleep(event_sleep_time)
 | 
				
			||||||
        Gtk.main_quit()
 | 
					        Gtk.main_quit()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					# Python imports
 | 
				
			||||||
 | 
					import os, json
 | 
				
			||||||
 | 
					from os.path import join
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Lib imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Application imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Plugin:
 | 
				
			||||||
 | 
					    path: str       = None
 | 
				
			||||||
 | 
					    name: str       = None
 | 
				
			||||||
 | 
					    author: str     = None
 | 
				
			||||||
 | 
					    version: str    = None
 | 
				
			||||||
 | 
					    support: str    = None
 | 
				
			||||||
 | 
					    requests:{}     = None
 | 
				
			||||||
 | 
					    reference: type = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ManifestProcessor:
 | 
				
			||||||
 | 
					    def __init__(self, path, builder):
 | 
				
			||||||
 | 
					        manifest = join(path, "manifest.json")
 | 
				
			||||||
 | 
					        if not os.path.exists(manifest):
 | 
				
			||||||
 | 
					            raise Exception("Invalid Plugin Structure: Plugin doesn't have 'manifest.json'. Aboarting load...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._path    = path
 | 
				
			||||||
 | 
					        self._builder = builder
 | 
				
			||||||
 | 
					        with open(manifest) as f:
 | 
				
			||||||
 | 
					            data           = json.load(f)
 | 
				
			||||||
 | 
					            self._manifest = data["manifest"]
 | 
				
			||||||
 | 
					            self._plugin   = self.collect_info()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def collect_info(self) -> Plugin:
 | 
				
			||||||
 | 
					        plugin          = Plugin()
 | 
				
			||||||
 | 
					        plugin.path     = self._path
 | 
				
			||||||
 | 
					        plugin.name     = self._manifest["name"]
 | 
				
			||||||
 | 
					        plugin.author   = self._manifest["author"]
 | 
				
			||||||
 | 
					        plugin.version  = self._manifest["version"]
 | 
				
			||||||
 | 
					        plugin.support  = self._manifest["support"]
 | 
				
			||||||
 | 
					        plugin.requests = self._manifest["requests"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_loading_data(self):
 | 
				
			||||||
 | 
					        loading_data = {}
 | 
				
			||||||
 | 
					        requests     = self._plugin.requests
 | 
				
			||||||
 | 
					        keys         = requests.keys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if "ui_target" in keys:
 | 
				
			||||||
 | 
					            if requests["ui_target"] in  [
 | 
				
			||||||
 | 
					                                            "none", "other", "main_Window", "main_menu_bar", "path_menu_bar", "plugin_control_list",
 | 
				
			||||||
 | 
					                                            "context_menu", "window_1", "window_2", "window_3", "window_4"
 | 
				
			||||||
 | 
					                                        ]:
 | 
				
			||||||
 | 
					                if requests["ui_target"] == "other":
 | 
				
			||||||
 | 
					                    if "ui_target_id" in keys:
 | 
				
			||||||
 | 
					                        loading_data["ui_target"] = self._builder.get_object(requests["ui_target_id"])
 | 
				
			||||||
 | 
					                        if loading_data["ui_target"] == None:
 | 
				
			||||||
 | 
					                            raise Exception('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...')
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        raise Exception('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...')
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    loading_data["ui_target"] = self._builder.get_object(requests["ui_target"])
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                raise Exception('Unknown "ui_target" given in requests.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if "pass_fm_events" in keys:
 | 
				
			||||||
 | 
					            if requests["pass_fm_events"] in ["true"]:
 | 
				
			||||||
 | 
					                loading_data["pass_fm_events"] = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if "bind_keys" in keys:
 | 
				
			||||||
 | 
					            if isinstance(requests["bind_keys"], list):
 | 
				
			||||||
 | 
					                loading_data["bind_keys"] = requests["bind_keys"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self._plugin, loading_data
 | 
				
			||||||
@@ -8,17 +8,9 @@ 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Plugin:
 | 
					 | 
				
			||||||
    path: str       = None
 | 
					 | 
				
			||||||
    name: str       = None
 | 
					 | 
				
			||||||
    author: str     = None
 | 
					 | 
				
			||||||
    version: str    = None
 | 
					 | 
				
			||||||
    support: str    = None
 | 
					 | 
				
			||||||
    requests:{}  = None
 | 
					 | 
				
			||||||
    reference: type = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Plugins:
 | 
					class Plugins:
 | 
				
			||||||
@@ -56,19 +48,17 @@ class Plugins:
 | 
				
			|||||||
        for path, folder in [[join(self._plugins_path, item), item] if os.path.isdir(join(self._plugins_path, item)) else None for item in os.listdir(self._plugins_path)]:
 | 
					        for path, folder in [[join(self._plugins_path, item), item] if os.path.isdir(join(self._plugins_path, item)) else None for item in os.listdir(self._plugins_path)]:
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                target   = join(path, "plugin.py")
 | 
					                target   = join(path, "plugin.py")
 | 
				
			||||||
 | 
					                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 Exception("Invalid Plugin Structure: Plugin doesn't have 'plugin.py'. Aboarting load...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                plugin, loading_data = manifest.get_loading_data()
 | 
				
			||||||
                module               = self.load_plugin_module(path, folder, target)
 | 
					                module               = self.load_plugin_module(path, folder, target)
 | 
				
			||||||
                plugin       = self.collect_info(module, path)
 | 
					 | 
				
			||||||
                loading_data = self.parse_requests(plugin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                self.execute_plugin(module, plugin, loading_data)
 | 
					                self.execute_plugin(module, plugin, loading_data)
 | 
				
			||||||
            except Exception as e:
 | 
					            except Exception as e:
 | 
				
			||||||
                print(f"Malformed Plugin: Not loading -->: '{folder}' !")
 | 
					                print(f"Malformed Plugin: Not loading -->: '{folder}' !")
 | 
				
			||||||
                traceback.print_exc() 
 | 
					                traceback.print_exc() 
 | 
				
			||||||
                # if debug:
 | 
					 | 
				
			||||||
                #     traceback.print_exc()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        os.chdir(parent_path)
 | 
					        os.chdir(parent_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,49 +72,6 @@ class Plugins:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return module
 | 
					        return module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def collect_info(self, module, path) -> Plugin:
 | 
					 | 
				
			||||||
        plugin          = Plugin()
 | 
					 | 
				
			||||||
        plugin.path     = module.Manifest.path
 | 
					 | 
				
			||||||
        plugin.name     = module.Manifest.name
 | 
					 | 
				
			||||||
        plugin.author   = module.Manifest.author
 | 
					 | 
				
			||||||
        plugin.version  = module.Manifest.version
 | 
					 | 
				
			||||||
        plugin.support  = module.Manifest.support
 | 
					 | 
				
			||||||
        plugin.requests = module.Manifest.requests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return plugin
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def parse_requests(self, plugin):
 | 
					 | 
				
			||||||
        loading_data = {}
 | 
					 | 
				
			||||||
        requests     = plugin.requests
 | 
					 | 
				
			||||||
        keys         = requests.keys()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if "ui_target" in keys:
 | 
					 | 
				
			||||||
            if requests["ui_target"] in  [
 | 
					 | 
				
			||||||
                                            "none", "other", "main_Window", "main_menu_bar", "path_menu_bar", "plugin_control_list",
 | 
					 | 
				
			||||||
                                            "context_menu", "window_1", "window_2", "window_3", "window_4"
 | 
					 | 
				
			||||||
                                        ]:
 | 
					 | 
				
			||||||
                if requests["ui_target"] == "other":
 | 
					 | 
				
			||||||
                    if "ui_target_id" in keys:
 | 
					 | 
				
			||||||
                        loading_data["ui_target"] = self._builder.get_object(requests["ui_target_id"])
 | 
					 | 
				
			||||||
                        if loading_data["ui_target"] == None:
 | 
					 | 
				
			||||||
                            raise Exception('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...')
 | 
					 | 
				
			||||||
                    else:
 | 
					 | 
				
			||||||
                        raise Exception('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...')
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    loading_data["ui_target"] = self._builder.get_object(requests["ui_target"])
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                raise Exception('Unknown "ui_target" given in requests.')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if "pass_fm_events" in keys:
 | 
					 | 
				
			||||||
            if requests["pass_fm_events"] in ["true"]:
 | 
					 | 
				
			||||||
                loading_data["pass_fm_events"] = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if "bind_keys" in keys:
 | 
					 | 
				
			||||||
            if isinstance(requests["bind_keys"], list):
 | 
					 | 
				
			||||||
                loading_data["bind_keys"] = requests["bind_keys"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return loading_data
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def execute_plugin(self, module: type, plugin: Plugin, loading_data: []):
 | 
					    def execute_plugin(self, module: type, plugin: Plugin, loading_data: []):
 | 
				
			||||||
        plugin.reference = module.Plugin()
 | 
					        plugin.reference = module.Plugin()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					# Python imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Lib imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Application imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class EventSystem:
 | 
				
			||||||
 | 
					    """ Inheret IPCServerMixin. Create an pub/sub systems. """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        # NOTE: The format used is list of ['who', target, (data,)] Where:
 | 
				
			||||||
 | 
					        #             who is the sender or target ID and is used for context and control flow,
 | 
				
			||||||
 | 
					        #             method_target is the method to call,
 | 
				
			||||||
 | 
					        #             data is the method parameters OR message data to give
 | 
				
			||||||
 | 
					        #       Where data may be any kind of data
 | 
				
			||||||
 | 
					        self._gui_events    = []
 | 
				
			||||||
 | 
					        self._module_events = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Makeshift "events" system FIFO
 | 
				
			||||||
 | 
					    def _pop_gui_event(self) -> None:
 | 
				
			||||||
 | 
					        if len(self._gui_events) > 0:
 | 
				
			||||||
 | 
					            return self._gui_events.pop(0)
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _pop_module_event(self) -> None:
 | 
				
			||||||
 | 
					        if len(self._module_events) > 0:
 | 
				
			||||||
 | 
					            return self._module_events.pop(0)
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def push_gui_event(self, event: list) -> None:
 | 
				
			||||||
 | 
					        if len(event) == 3:
 | 
				
			||||||
 | 
					            self._gui_events.append(event)
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raise Exception("Invald event format! Please do:  ['sender_id': str, method_target: method, (data,): any]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def push_module_event(self, event: list) -> None:
 | 
				
			||||||
 | 
					        if len(event) == 3:
 | 
				
			||||||
 | 
					            self._module_events.append(event)
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raise Exception("Invald event format! Please do:  ['target_id': str, method_target: method, (data,): any]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def read_gui_event(self) -> list:
 | 
				
			||||||
 | 
					        return self._gui_events[0] if self._gui_events else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def read_module_event(self) -> list:
 | 
				
			||||||
 | 
					        return self._module_events[0] if self._module_events else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def consume_gui_event(self) -> list:
 | 
				
			||||||
 | 
					        return self._pop_gui_event()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def consume_module_event(self) -> list:
 | 
				
			||||||
 | 
					        return self._pop_module_event()
 | 
				
			||||||
@@ -7,12 +7,6 @@ from multiprocessing.connection import Listener, Client
 | 
				
			|||||||
# Application imports
 | 
					# Application imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def threaded(fn):
 | 
					 | 
				
			||||||
    def wrapper(*args, **kwargs):
 | 
					 | 
				
			||||||
        threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
 | 
					 | 
				
			||||||
    return wrapper
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IPCServer:
 | 
					class IPCServer:
 | 
				
			||||||
@@ -36,7 +30,7 @@ class IPCServer:
 | 
				
			|||||||
            self._ipc_authkey = None
 | 
					            self._ipc_authkey = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @threaded
 | 
					    @daemon_threaded
 | 
				
			||||||
    def create_ipc_listener(self) -> None:
 | 
					    def create_ipc_listener(self) -> None:
 | 
				
			||||||
        if self._conn_type == "socket":
 | 
					        if self._conn_type == "socket":
 | 
				
			||||||
            if os.path.exists(self._ipc_address):
 | 
					            if os.path.exists(self._ipc_address):
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user