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:
 | 
			
		||||
    file_uri: str      = None
 | 
			
		||||
    file_name: str     = None
 | 
			
		||||
@@ -50,8 +39,11 @@ class Properties:
 | 
			
		||||
    chmod_stat: str    = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Plugin(Manifest):
 | 
			
		||||
class Plugin:
 | 
			
		||||
    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._builder           = 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):
 | 
			
		||||
    def __init__(self, path, file):
 | 
			
		||||
        super(FilePreviewWidget, self).__init__()
 | 
			
		||||
@@ -89,8 +74,11 @@ grep_result_set  = manager.dict()
 | 
			
		||||
file_result_set  = manager.list()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Plugin(Manifest):
 | 
			
		||||
class Plugin:
 | 
			
		||||
    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._builder          = 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:
 | 
			
		||||
    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):
 | 
			
		||||
class Plugin:
 | 
			
		||||
    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_sleep_time  = .5
 | 
			
		||||
        self._event_message     = None
 | 
			
		||||
@@ -58,7 +47,6 @@ class Plugin(Manifest):
 | 
			
		||||
 | 
			
		||||
    def send_message(self, widget=None, eve=None):
 | 
			
		||||
        message = "Hello, World!"
 | 
			
		||||
        print("here")
 | 
			
		||||
        self._event_system.push_gui_event([self.name, "display_message", ("warning", message, None)])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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:
 | 
			
		||||
    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):
 | 
			
		||||
class Plugin:
 | 
			
		||||
    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._builder               = 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:
 | 
			
		||||
    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):
 | 
			
		||||
class Plugin:
 | 
			
		||||
    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_sleep_time = .5
 | 
			
		||||
        self._event_message    = None
 | 
			
		||||
 
 | 
			
		||||
@@ -4,16 +4,18 @@ import builtins, threading
 | 
			
		||||
# Lib 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 wrapper(*args, **kwargs):
 | 
			
		||||
        threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start()
 | 
			
		||||
    return wrapper
 | 
			
		||||
 | 
			
		||||
# NOTE: Insure threads die with parent's destruction
 | 
			
		||||
# NOTE: Threads WILL die with parent's destruction.
 | 
			
		||||
def daemon_threaded_wrapper(fn):
 | 
			
		||||
    def wrapper(*args, **kwargs):
 | 
			
		||||
        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():
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self._endpoints = {}
 | 
			
		||||
 | 
			
		||||
    def register(self, rule, **options):
 | 
			
		||||
        def decorator(f):
 | 
			
		||||
            _endpoint = options.pop("endpoint", None)
 | 
			
		||||
            self._endpoints[rule] = f
 | 
			
		||||
            return f
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,31 +4,33 @@ import os, inspect, time
 | 
			
		||||
# Lib imports
 | 
			
		||||
 | 
			
		||||
# Application imports
 | 
			
		||||
from __builtins__ import EventSystem
 | 
			
		||||
from __builtins__ import *
 | 
			
		||||
from utils.ipc_server import IPCServer
 | 
			
		||||
from utils.settings import Settings
 | 
			
		||||
from core.controller import Controller
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Application(EventSystem):
 | 
			
		||||
class Application(IPCServer):
 | 
			
		||||
    """ Create Settings and Controller classes. Bind signal to Builder. Inherit from Builtins to bind global methods and classes. """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, args, unknownargs):
 | 
			
		||||
        super(Application, self).__init__()
 | 
			
		||||
 | 
			
		||||
        if not trace_debug:
 | 
			
		||||
            event_system.create_ipc_listener()
 | 
			
		||||
            self.create_ipc_listener()
 | 
			
		||||
            time.sleep(0.05)
 | 
			
		||||
 | 
			
		||||
            if not event_system.is_ipc_alive:
 | 
			
		||||
            if not self.is_ipc_alive:
 | 
			
		||||
                if unknownargs:
 | 
			
		||||
                    for arg in unknownargs:
 | 
			
		||||
                        if os.path.isdir(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):
 | 
			
		||||
                    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")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,6 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def tear_down(self, widget=None, eve=None):
 | 
			
		||||
        event_system.send_ipc_message("close server")
 | 
			
		||||
        self.fm_controller.save_state()
 | 
			
		||||
        time.sleep(event_sleep_time)
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
# 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:
 | 
			
		||||
@@ -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)]:
 | 
			
		||||
            try:
 | 
			
		||||
                target   = join(path, "plugin.py")
 | 
			
		||||
                manifest = ManifestProcessor(path, self._builder)
 | 
			
		||||
 | 
			
		||||
                if not os.path.exists(target):
 | 
			
		||||
                    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)
 | 
			
		||||
                plugin       = self.collect_info(module, path)
 | 
			
		||||
                loading_data = self.parse_requests(plugin)
 | 
			
		||||
 | 
			
		||||
                self.execute_plugin(module, plugin, loading_data)
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                print(f"Malformed Plugin: Not loading -->: '{folder}' !")
 | 
			
		||||
                traceback.print_exc() 
 | 
			
		||||
                # if debug:
 | 
			
		||||
                #     traceback.print_exc()
 | 
			
		||||
 | 
			
		||||
        os.chdir(parent_path)
 | 
			
		||||
 | 
			
		||||
@@ -82,49 +72,6 @@ class Plugins:
 | 
			
		||||
 | 
			
		||||
        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: []):
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def threaded(fn):
 | 
			
		||||
    def wrapper(*args, **kwargs):
 | 
			
		||||
        threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
 | 
			
		||||
    return wrapper
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IPCServer:
 | 
			
		||||
@@ -36,7 +30,7 @@ class IPCServer:
 | 
			
		||||
            self._ipc_authkey = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @threaded
 | 
			
		||||
    @daemon_threaded
 | 
			
		||||
    def create_ipc_listener(self) -> None:
 | 
			
		||||
        if self._conn_type == "socket":
 | 
			
		||||
            if os.path.exists(self._ipc_address):
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user