import refactoring
This commit is contained in:
		@@ -6,26 +6,24 @@ import builtins
 | 
				
			|||||||
# Lib imports
 | 
					# Lib imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application imports
 | 
					# Application imports
 | 
				
			||||||
from controller import IPCServerMixin
 | 
					from ipc_server import IPCServer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Builtins(IPCServerMixin):
 | 
					class EventSystem(IPCServer):
 | 
				
			||||||
    """Docstring for __builtins__ extender"""
 | 
					    """ Inheret IPCServerMixin. Create an pub/sub systems. """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        # NOTE: The format used is list of [type, target, data] Where:
 | 
					        super(EventSystem, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # NOTE: The format used is list of [type, target, (data,)] Where:
 | 
				
			||||||
        #             type is useful context for control flow,
 | 
					        #             type is useful context for control flow,
 | 
				
			||||||
        #             target is the method to call,
 | 
					        #             target is the method to call,
 | 
				
			||||||
        #             data is the method parameters to give
 | 
					        #             data is the method parameters to give
 | 
				
			||||||
        #       Where data may be any kind of data
 | 
					        #       Where data may be any kind of data
 | 
				
			||||||
        self._gui_events    = []
 | 
					        self._gui_events    = []
 | 
				
			||||||
        self._module_events = []
 | 
					        self._module_events = []
 | 
				
			||||||
        self.is_ipc_alive   = False
 | 
					
 | 
				
			||||||
        self.ipc_authkey    = b'app-ipc'
 | 
					 | 
				
			||||||
        self.ipc_address    = '127.0.0.1'
 | 
					 | 
				
			||||||
        self.ipc_port       = 8888
 | 
					 | 
				
			||||||
        self.ipc_timeout    = 15.0
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Makeshift fake "events" type system FIFO
 | 
					    # Makeshift fake "events" type system FIFO
 | 
				
			||||||
    def _pop_gui_event(self):
 | 
					    def _pop_gui_event(self):
 | 
				
			||||||
@@ -44,14 +42,14 @@ class Builtins(IPCServerMixin):
 | 
				
			|||||||
            self._gui_events.append(event)
 | 
					            self._gui_events.append(event)
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        raise Exception("Invald event format! Please do:  [type, target, data]")
 | 
					        raise Exception("Invald event format! Please do:  [type, target, (data,)]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def push_module_event(self, event):
 | 
					    def push_module_event(self, event):
 | 
				
			||||||
        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:  [type, target, data]")
 | 
					        raise Exception("Invald event format! Please do:  [type, target, (data,)]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def read_gui_event(self):
 | 
					    def read_gui_event(self):
 | 
				
			||||||
        return self._gui_events[0]
 | 
					        return self._gui_events[0]
 | 
				
			||||||
@@ -70,7 +68,7 @@ class Builtins(IPCServerMixin):
 | 
				
			|||||||
# NOTE: Just reminding myself we can add to builtins two different ways...
 | 
					# NOTE: Just reminding myself we can add to builtins two different ways...
 | 
				
			||||||
# __builtins__.update({"event_system": Builtins()})
 | 
					# __builtins__.update({"event_system": Builtins()})
 | 
				
			||||||
builtins.app_name          = "<change_me>"
 | 
					builtins.app_name          = "<change_me>"
 | 
				
			||||||
builtins.event_system      = Builtins()
 | 
					builtins.event_system      = EventSystem()
 | 
				
			||||||
builtins.event_sleep_time  = 0.2
 | 
					builtins.event_sleep_time  = 0.2
 | 
				
			||||||
builtins.debug             = False
 | 
					builtins.debug             = False
 | 
				
			||||||
builtins.trace_debug       = False
 | 
					builtins.trace_debug       = False
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,50 +1,3 @@
 | 
				
			|||||||
# Python imports
 | 
					"""
 | 
				
			||||||
import os, inspect, time
 | 
					    Start of package.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
# Lib imports
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Application imports
 | 
					 | 
				
			||||||
from utils import Settings
 | 
					 | 
				
			||||||
from controller import Controller
 | 
					 | 
				
			||||||
from __builtins__ import Builtins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Main(Builtins):
 | 
					 | 
				
			||||||
    def __init__(self, args, unknownargs):
 | 
					 | 
				
			||||||
        if not debug:
 | 
					 | 
				
			||||||
            event_system.create_ipc_server()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        time.sleep(0.2)
 | 
					 | 
				
			||||||
        if not trace_debug:
 | 
					 | 
				
			||||||
            if not event_system.is_ipc_alive:
 | 
					 | 
				
			||||||
                if unknownargs:
 | 
					 | 
				
			||||||
                    for arg in unknownargs:
 | 
					 | 
				
			||||||
                        if os.path.isdir(arg):
 | 
					 | 
				
			||||||
                            message = f"FILE|{arg}"
 | 
					 | 
				
			||||||
                            event_system.send_ipc_message(message)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                raise Exception("IPC Server Exists: Will send data to it and close...")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        settings = Settings()
 | 
					 | 
				
			||||||
        settings.create_window()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        controller = Controller(settings, args, unknownargs)
 | 
					 | 
				
			||||||
        if not controller:
 | 
					 | 
				
			||||||
            raise Exception("Controller exited and doesn't exist...")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Gets the methods from the classes and sets to handler.
 | 
					 | 
				
			||||||
        # Then, builder from settings will connect to any signals it needs.
 | 
					 | 
				
			||||||
        classes  = [controller]
 | 
					 | 
				
			||||||
        handlers = {}
 | 
					 | 
				
			||||||
        for c in classes:
 | 
					 | 
				
			||||||
            methods = None
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                methods = inspect.getmembers(c, predicate=inspect.ismethod)
 | 
					 | 
				
			||||||
                handlers.update(methods)
 | 
					 | 
				
			||||||
            except Exception as e:
 | 
					 | 
				
			||||||
                print(repr(e))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        settings.get_builder().connect_signals(handlers)
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
#!/usr/bin/python3
 | 
					#!/usr/bin/python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Python imports
 | 
					# Python imports
 | 
				
			||||||
import argparse, faulthandler, traceback
 | 
					import argparse, faulthandler, traceback
 | 
				
			||||||
from setproctitle import setproctitle
 | 
					from setproctitle import setproctitle
 | 
				
			||||||
@@ -15,10 +14,12 @@ gi.require_version('Gtk', '3.0')
 | 
				
			|||||||
from gi.repository import Gtk
 | 
					from gi.repository import Gtk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application imports
 | 
					# Application imports
 | 
				
			||||||
from __init__ import Main
 | 
					from main import Main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    ''' Set process title, get arguments, and create GTK main thread. '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        # import web_pdb
 | 
					        # import web_pdb
 | 
				
			||||||
        # web_pdb.set_trace()
 | 
					        # web_pdb.set_trace()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								src/context/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/context/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    Gtk Bound Signal Module
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
@@ -8,8 +8,8 @@ gi.require_version('Gtk', '3.0')
 | 
				
			|||||||
from gi.repository import Gtk, GLib
 | 
					from gi.repository import Gtk, GLib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application imports
 | 
					# Application imports
 | 
				
			||||||
from .mixins import *
 | 
					from .mixins.dummy_mixin import DummyMixin
 | 
				
			||||||
from . import Controller_Data
 | 
					from .controller_data import Controller_Data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,22 +42,11 @@ class Controller(DummyMixin, Controller_Data):
 | 
				
			|||||||
            if event:
 | 
					            if event:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    type, target, data = event
 | 
					                    type, target, data = event
 | 
				
			||||||
                    if not type:
 | 
					                    method = getattr(self.__class__, target)
 | 
				
			||||||
                        method = getattr(self.__class__, target)
 | 
					                    GLib.idle_add(method, *(self, *data,))
 | 
				
			||||||
                        GLib.idle_add(method, *(self, *data,))
 | 
					 | 
				
			||||||
                    else:
 | 
					 | 
				
			||||||
                        method = getattr(self.__class__, "hadle_gui_event_and_call_back")
 | 
					 | 
				
			||||||
                        GLib.idle_add(method, *(self, type, target, data))
 | 
					 | 
				
			||||||
                except Exception as e:
 | 
					                except Exception as e:
 | 
				
			||||||
                    print(repr(e))
 | 
					                    print(repr(e))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def hadle_gui_event_and_call_back(self, type, target, parameters):
 | 
					 | 
				
			||||||
        method = getattr(self.__class__, target)
 | 
					 | 
				
			||||||
        data   = method(*(self, *parameters))
 | 
					 | 
				
			||||||
        event_system.push_module_event([type, None, (data,)])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def handle_file_from_ipc(self, path):
 | 
					    def handle_file_from_ipc(self, path):
 | 
				
			||||||
        print(f"Path From IPC: {path}")
 | 
					        print(f"Path From IPC: {path}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5,22 +5,15 @@ import os, signal
 | 
				
			|||||||
from gi.repository import GLib
 | 
					from gi.repository import GLib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application imports
 | 
					# Application imports
 | 
				
			||||||
 | 
					from plugins.plugins import Plugins
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Controller_Data:
 | 
					class Controller_Data:
 | 
				
			||||||
    def clear_console(self):
 | 
					    ''' Controller_Data contains most of the state of the app at ay given time. It also has some support methods. '''
 | 
				
			||||||
        os.system('cls' if os.name == 'nt' else 'clear')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def call_method(self, _method_name, data = None):
 | 
					 | 
				
			||||||
        method_name = str(_method_name)
 | 
					 | 
				
			||||||
        method      = getattr(self, method_name, lambda data: f"No valid key passed...\nkey={method_name}\nargs={data}")
 | 
					 | 
				
			||||||
        return method(data) if data else method()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def has_method(self, obj, name):
 | 
					 | 
				
			||||||
        return callable(getattr(obj, name, None))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_controller_data(self, _settings):
 | 
					    def setup_controller_data(self, _settings):
 | 
				
			||||||
 | 
					        self.plugins       = Plugins(_settings)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.settings      = _settings
 | 
					        self.settings      = _settings
 | 
				
			||||||
        self.builder       = self.settings.get_builder()
 | 
					        self.builder       = self.settings.get_builder()
 | 
				
			||||||
        self.window        = self.settings.get_main_window()
 | 
					        self.window        = self.settings.get_main_window()
 | 
				
			||||||
@@ -33,3 +26,34 @@ class Controller_Data:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        self.window.connect("delete-event", self.tear_down)
 | 
					        self.window.connect("delete-event", self.tear_down)
 | 
				
			||||||
        GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.tear_down)
 | 
					        GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.tear_down)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_console(self):
 | 
				
			||||||
 | 
					        ''' Clears the terminal screen. '''
 | 
				
			||||||
 | 
					        os.system('cls' if os.name == 'nt' else 'clear')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def call_method(self, _method_name, data = None):
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        Calls a method from scope of class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Parameters:
 | 
				
			||||||
 | 
					                        a (obj): self
 | 
				
			||||||
 | 
					                        b (str): method name to be called
 | 
				
			||||||
 | 
					                        c (*): Data (if any) to be passed to the method.
 | 
				
			||||||
 | 
					                                Note: It must be structured according to the given methods requirements.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Returns:
 | 
				
			||||||
 | 
					                        Return data is that which the calling method gives.
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        method_name = str(_method_name)
 | 
				
			||||||
 | 
					        method      = getattr(self, method_name, lambda data: f"No valid key passed...\nkey={method_name}\nargs={data}")
 | 
				
			||||||
 | 
					        return method(data) if data else method()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def has_method(self, obj, name):
 | 
				
			||||||
 | 
					        ''' Checks if a given method exists. '''
 | 
				
			||||||
 | 
					        return callable(getattr(obj, name, None))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_children(self, widget):
 | 
				
			||||||
 | 
					        ''' Clear children of a gtk widget. '''
 | 
				
			||||||
 | 
					        for child in widget.get_children():
 | 
				
			||||||
 | 
					            widget.remove(child)
 | 
				
			||||||
							
								
								
									
										3
									
								
								src/context/mixins/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/context/mixins/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    Generic Mixins Module
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
							
								
								
									
										4
									
								
								src/context/mixins/dummy_mixin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/context/mixins/dummy_mixin.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					class DummyMixin:
 | 
				
			||||||
 | 
					    """ DummyMixin is an example of how mixins are used and structured in a project. """
 | 
				
			||||||
 | 
					    def print_hello_world(self):
 | 
				
			||||||
 | 
					        print("Hello, World!")
 | 
				
			||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
"""
 | 
					 | 
				
			||||||
    Gtk Bound Signal Module
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
from .mixins import *
 | 
					 | 
				
			||||||
from .IPCServerMixin import IPCServerMixin
 | 
					 | 
				
			||||||
from .Controller_Data import Controller_Data
 | 
					 | 
				
			||||||
from .Controller import Controller
 | 
					 | 
				
			||||||
@@ -1,4 +0,0 @@
 | 
				
			|||||||
class DummyMixin:
 | 
					 | 
				
			||||||
    """docstring for DummyMixin"""
 | 
					 | 
				
			||||||
    def print_hello_world(self):
 | 
					 | 
				
			||||||
        print("Hello, World!")
 | 
					 | 
				
			||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
from .DummyMixin import DummyMixin
 | 
					 | 
				
			||||||
@@ -15,7 +15,14 @@ def threaded(fn):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IPCServerMixin:
 | 
					class IPCServer:
 | 
				
			||||||
 | 
					    ''' Create a listener so that other instances send requests back to existing instance. '''
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self.is_ipc_alive   = False
 | 
				
			||||||
 | 
					        self.ipc_authkey    = b'app-ipc'
 | 
				
			||||||
 | 
					        self.ipc_address    = '127.0.0.1'
 | 
				
			||||||
 | 
					        self.ipc_port       = 8888
 | 
				
			||||||
 | 
					        self.ipc_timeout    = 15.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @threaded
 | 
					    @threaded
 | 
				
			||||||
    def create_ipc_server(self):
 | 
					    def create_ipc_server(self):
 | 
				
			||||||
							
								
								
									
										52
									
								
								src/main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/main.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					# Python imports
 | 
				
			||||||
 | 
					import os, inspect, time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Lib imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Application imports
 | 
				
			||||||
 | 
					from utils.settings import Settings
 | 
				
			||||||
 | 
					from context.controller import Controller
 | 
				
			||||||
 | 
					from __builtins__ import EventSystem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Main(EventSystem):
 | 
				
			||||||
 | 
					    ''' Create Settings and Controller classes. Bind signal to Builder. Inherit from Builtins to bind global methods and classes.'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, args, unknownargs):
 | 
				
			||||||
 | 
					        if not debug:
 | 
				
			||||||
 | 
					            event_system.create_ipc_server()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        time.sleep(0.2)
 | 
				
			||||||
 | 
					        if not trace_debug:
 | 
				
			||||||
 | 
					            if not event_system.is_ipc_alive:
 | 
				
			||||||
 | 
					                if unknownargs:
 | 
				
			||||||
 | 
					                    for arg in unknownargs:
 | 
				
			||||||
 | 
					                        if os.path.isdir(arg):
 | 
				
			||||||
 | 
					                            message = f"FILE|{arg}"
 | 
				
			||||||
 | 
					                            event_system.send_ipc_message(message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                raise Exception("IPC Server Exists: Will send data to it and close...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        settings = Settings()
 | 
				
			||||||
 | 
					        settings.create_window()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        controller = Controller(settings, args, unknownargs)
 | 
				
			||||||
 | 
					        if not controller:
 | 
				
			||||||
 | 
					            raise Exception("Controller exited and doesn't exist...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Gets the methods from the classes and sets to handler.
 | 
				
			||||||
 | 
					        # Then, builder from settings will connect to any signals it needs.
 | 
				
			||||||
 | 
					        classes  = [controller]
 | 
				
			||||||
 | 
					        handlers = {}
 | 
				
			||||||
 | 
					        for c in classes:
 | 
				
			||||||
 | 
					            methods = None
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                methods = inspect.getmembers(c, predicate=inspect.ismethod)
 | 
				
			||||||
 | 
					                handlers.update(methods)
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                print(repr(e))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        settings.get_builder().connect_signals(handlers)
 | 
				
			||||||
							
								
								
									
										3
									
								
								src/plugins/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/plugins/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    Gtk Bound Plugins Module
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
							
								
								
									
										78
									
								
								src/plugins/plugins.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/plugins/plugins.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					# Python imports
 | 
				
			||||||
 | 
					import os, sys, importlib, traceback
 | 
				
			||||||
 | 
					from os.path import join, isdir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Lib imports
 | 
				
			||||||
 | 
					import gi
 | 
				
			||||||
 | 
					gi.require_version('Gtk', '3.0')
 | 
				
			||||||
 | 
					from gi.repository import Gtk, Gio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Application imports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Plugin:
 | 
				
			||||||
 | 
					    name          = None
 | 
				
			||||||
 | 
					    module        = None
 | 
				
			||||||
 | 
					    reference     = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Plugins:
 | 
				
			||||||
 | 
					    """Plugins controller"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, settings):
 | 
				
			||||||
 | 
					        self._settings            = settings
 | 
				
			||||||
 | 
					        self._builder             = self._settings.get_builder()
 | 
				
			||||||
 | 
					        self._plugins_path        = self._settings.get_plugins_path()
 | 
				
			||||||
 | 
					        self._plugins_dir_watcher = None
 | 
				
			||||||
 | 
					        self._plugin_collection   = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def launch_plugins(self):
 | 
				
			||||||
 | 
					        self._set_plugins_watcher()
 | 
				
			||||||
 | 
					        self.load_plugins()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _set_plugins_watcher(self):
 | 
				
			||||||
 | 
					        self._plugins_dir_watcher  = Gio.File.new_for_path(self._plugins_path) \
 | 
				
			||||||
 | 
					                                            .monitor_directory(Gio.FileMonitorFlags.WATCH_MOVES, Gio.Cancellable())
 | 
				
			||||||
 | 
					        self._plugins_dir_watcher.connect("changed", self._on_plugins_changed, ())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _on_plugins_changed(self, file_monitor, file, other_file=None, eve_type=None, data=None):
 | 
				
			||||||
 | 
					        if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED,
 | 
				
			||||||
 | 
					                        Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN,
 | 
				
			||||||
 | 
					                                                    Gio.FileMonitorEvent.MOVED_OUT]:
 | 
				
			||||||
 | 
					            self.reload_plugins(file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def load_plugins(self, file=None):
 | 
				
			||||||
 | 
					        print(f"Loading plugins...")
 | 
				
			||||||
 | 
					        parent_path = os.getcwd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for file in os.listdir(self._plugins_path):
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                path = join(self._plugins_path, file)
 | 
				
			||||||
 | 
					                if isdir(path):
 | 
				
			||||||
 | 
					                    os.chdir(path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    sys.path.insert(0, path)
 | 
				
			||||||
 | 
					                    spec          = importlib.util.spec_from_file_location(file, join(path, "__main__.py"))
 | 
				
			||||||
 | 
					                    app           = importlib.util.module_from_spec(spec)
 | 
				
			||||||
 | 
					                    spec.loader.exec_module(app)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    plugin_reference     = app.Plugin(self._builder, event_system)
 | 
				
			||||||
 | 
					                    plugin               = Plugin()
 | 
				
			||||||
 | 
					                    plugin.name          = plugin_reference.get_plugin_name()
 | 
				
			||||||
 | 
					                    plugin.module        = path
 | 
				
			||||||
 | 
					                    plugin.reference     = plugin_reference
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    self._plugin_collection.append(plugin)
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                print("Malformed plugin! Not loading!")
 | 
				
			||||||
 | 
					                traceback.print_exc()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        os.chdir(parent_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reload_plugins(self, file=None):
 | 
				
			||||||
 | 
					        print(f"Reloading plugins...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set_message_on_plugin(self, type, data):
 | 
				
			||||||
 | 
					        print("Trying to send message to plugin...")
 | 
				
			||||||
@@ -1,6 +1,3 @@
 | 
				
			|||||||
"""
 | 
					"""
 | 
				
			||||||
    Utils module
 | 
					    Utils module
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					 | 
				
			||||||
from .Logger import Logger
 | 
					 | 
				
			||||||
from .Settings import Settings
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,8 @@ from gi.repository import Gdk
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application imports
 | 
					# Application imports
 | 
				
			||||||
from . import Logger
 | 
					from .logger import Logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,6 +21,7 @@ class Settings:
 | 
				
			|||||||
        self._SCRIPT_PTH    = os.path.dirname(os.path.realpath(__file__))
 | 
					        self._SCRIPT_PTH    = os.path.dirname(os.path.realpath(__file__))
 | 
				
			||||||
        self._USER_HOME     = os.path.expanduser('~')
 | 
					        self._USER_HOME     = os.path.expanduser('~')
 | 
				
			||||||
        self._CONFIG_PATH   = f"{self._USER_HOME}/.config/{app_name.lower()}"
 | 
					        self._CONFIG_PATH   = f"{self._USER_HOME}/.config/{app_name.lower()}"
 | 
				
			||||||
 | 
					        self._PLUGINS_PATH  = f"{self._CONFIG_PATH}/plugins"
 | 
				
			||||||
        self._GLADE_FILE    = f"{self._CONFIG_PATH}/Main_Window.glade"
 | 
					        self._GLADE_FILE    = f"{self._CONFIG_PATH}/Main_Window.glade"
 | 
				
			||||||
        self._CSS_FILE      = f"{self._CONFIG_PATH}/stylesheet.css"
 | 
					        self._CSS_FILE      = f"{self._CONFIG_PATH}/stylesheet.css"
 | 
				
			||||||
        self._DEFAULT_ICONS = f"{self._CONFIG_PATH}/icons"
 | 
					        self._DEFAULT_ICONS = f"{self._CONFIG_PATH}/icons"
 | 
				
			||||||
@@ -28,6 +30,9 @@ class Settings:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if not os.path.exists(self._CONFIG_PATH):
 | 
					        if not os.path.exists(self._CONFIG_PATH):
 | 
				
			||||||
            os.mkdir(self._CONFIG_PATH)
 | 
					            os.mkdir(self._CONFIG_PATH)
 | 
				
			||||||
 | 
					        if not os.path.exists(self._PLUGINS_PATH):
 | 
				
			||||||
 | 
					            os.mkdir(self._PLUGINS_PATH)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not os.path.exists(self._GLADE_FILE):
 | 
					        if not os.path.exists(self._GLADE_FILE):
 | 
				
			||||||
            self._GLADE_FILE   = f"{self._USR_PATH}/Main_Window.glade"
 | 
					            self._GLADE_FILE   = f"{self._USR_PATH}/Main_Window.glade"
 | 
				
			||||||
        if not os.path.exists(self._CSS_FILE):
 | 
					        if not os.path.exists(self._CSS_FILE):
 | 
				
			||||||
@@ -42,7 +47,7 @@ class Settings:
 | 
				
			|||||||
        self._vids_filter   = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
 | 
					        self._vids_filter   = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv', '.mpeg', '.mp4', '.webm')
 | 
				
			||||||
        self._txt_filter    = ('.txt', '.text', '.sh', '.cfg', '.conf')
 | 
					        self._txt_filter    = ('.txt', '.text', '.sh', '.cfg', '.conf')
 | 
				
			||||||
        self._music_filter  = ('.psf', '.mp3', '.ogg' , '.flac')
 | 
					        self._music_filter  = ('.psf', '.mp3', '.ogg' , '.flac')
 | 
				
			||||||
        self._images_filter = ('.png', '.jpg', '.jpeg', '.gif')
 | 
					        self._images_filter = ('.png', '.jpg', '.jpeg', '.gif', '.ico', '.tga')
 | 
				
			||||||
        self._pdf_filter    = ('.pdf')
 | 
					        self._pdf_filter    = ('.pdf')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._success_color = "#88cc27"
 | 
					        self._success_color = "#88cc27"
 | 
				
			||||||
@@ -102,6 +107,7 @@ class Settings:
 | 
				
			|||||||
    def get_logger(self):         return self._logger
 | 
					    def get_logger(self):         return self._logger
 | 
				
			||||||
    def get_main_window(self):    return self._main_window
 | 
					    def get_main_window(self):    return self._main_window
 | 
				
			||||||
    def get_home_path(self):      return self._USER_HOME
 | 
					    def get_home_path(self):      return self._USER_HOME
 | 
				
			||||||
 | 
					    def get_plugins_path(self):   return self._PLUGINS_PATH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Filter returns
 | 
					    # Filter returns
 | 
				
			||||||
    def get_office_filter(self):  return self._office_filter
 | 
					    def get_office_filter(self):  return self._office_filter
 | 
				
			||||||
		Reference in New Issue
	
	Block a user