Update logging, update event system, update plugin structure
This commit is contained in:
parent
ee086f67f4
commit
793621745a
|
@ -1,5 +1,5 @@
|
|||
# Python imports
|
||||
import sys, threading, subprocess, time
|
||||
import os, threading, subprocess, time
|
||||
|
||||
# Gtk imports
|
||||
import gi
|
||||
|
@ -9,45 +9,74 @@ from gi.repository import Gtk
|
|||
# Application imports
|
||||
|
||||
|
||||
# NOTE: Threads will not die with parent's destruction
|
||||
def threaded(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
|
||||
def daemon_threaded(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
|
||||
return wrapper
|
||||
|
||||
|
||||
|
||||
|
||||
class Plugin:
|
||||
def __init__(self, builder, event_system):
|
||||
self._plugin_name = "Example Plugin"
|
||||
self._builder = builder
|
||||
self._event_system = event_system
|
||||
self._message = None
|
||||
self._time_out = 5
|
||||
self.SCRIPT_PTH = os.path.dirname(os.path.realpath(__file__))
|
||||
self._plugin_name = "Example Plugin"
|
||||
self._plugin_author = "John Doe"
|
||||
self._plugin_version = "0.0.1"
|
||||
|
||||
button = Gtk.Button(label=self._plugin_name)
|
||||
button.connect("button-release-event", self._do_action)
|
||||
self._builder = builder
|
||||
self._event_system = event_system
|
||||
self._event_sleep_time = .5
|
||||
self._event_message = None
|
||||
|
||||
plugin_list = self._builder.get_object("plugin_socket")
|
||||
button = Gtk.Button(label=self._plugin_name)
|
||||
button.connect("button-release-event", self.send_message)
|
||||
|
||||
# self._module_event_observer() # NOTE: Enable if you want the plugin to watch for events sent to it
|
||||
|
||||
plugin_list = self._builder.get_object("plugin_socket")
|
||||
plugin_list.add(button)
|
||||
plugin_list.show_all()
|
||||
|
||||
|
||||
@threaded
|
||||
def _do_action(self, widget=None, eve=None):
|
||||
def send_message(self, widget=None, eve=None):
|
||||
message = "Hello, World!"
|
||||
self._event_system.push_gui_event(["some_type", "display_message", ("warning", message, None)])
|
||||
self._event_system.push_gui_event([self._plugin_name, "display_message", ("warning", message, None)])
|
||||
|
||||
|
||||
def set_message(self, data):
|
||||
self._message = data
|
||||
|
||||
def get_plugin_name(self):
|
||||
return self._plugin_name
|
||||
|
||||
def get_plugin_author(self):
|
||||
return self._plugin_author
|
||||
|
||||
def get_plugin_version(self):
|
||||
return self._plugin_version
|
||||
|
||||
def get_socket_id(self):
|
||||
return self._socket_id
|
||||
|
||||
def _run_timeout(self):
|
||||
timeout = 0
|
||||
while not self._message and timeout < self._time_out:
|
||||
time.sleep(1)
|
||||
timeout += 1
|
||||
@daemon_threaded
|
||||
def _module_event_observer(self):
|
||||
while True:
|
||||
time.sleep(self._event_sleep_time)
|
||||
event = self._event_system.read_module_event()
|
||||
if event:
|
||||
try:
|
||||
if event[0] is self._plugin_name:
|
||||
target_id, method_target, data = self._event_system.consume_module_event()
|
||||
|
||||
if not method_target:
|
||||
self._event_message = data
|
||||
else:
|
||||
method = getattr(self.__class__, f"{method_target}")
|
||||
data = method(*(self, *parameters))
|
||||
except Exception as e:
|
||||
print(repr(e))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Python imports
|
||||
import os, sys, threading, subprocess, time
|
||||
import os, threading, subprocess, time
|
||||
|
||||
# Gtk imports
|
||||
import gi
|
||||
|
@ -9,49 +9,78 @@ from gi.repository import Gtk
|
|||
# Application imports
|
||||
|
||||
|
||||
# NOTE: Threads will not die with parent's destruction
|
||||
def threaded(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
|
||||
def daemon_threaded(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
|
||||
return wrapper
|
||||
|
||||
|
||||
|
||||
|
||||
class Plugin:
|
||||
def __init__(self, builder, event_system):
|
||||
self._plugin_name = "Youtube Download"
|
||||
self._builder = builder
|
||||
self._event_system = event_system
|
||||
self._message = None
|
||||
self._time_out = 5
|
||||
def __init__(self, fm_builder, fm_event_system):
|
||||
self.SCRIPT_PTH = os.path.dirname(os.path.realpath(__file__))
|
||||
self._plugin_name = "Youtube Download"
|
||||
self._plugin_author = "ITDominator"
|
||||
self._plugin_version = "0.0.1"
|
||||
|
||||
self.SCRIPT_PTH = os.path.dirname(os.path.realpath(__file__))
|
||||
self._fm_builder = fm_builder
|
||||
self._fm_event_system = fm_event_system
|
||||
self._event_sleep_time = .5
|
||||
self._fm_event_message = None
|
||||
|
||||
button = Gtk.Button(label=self._plugin_name)
|
||||
|
||||
button = Gtk.Button(label=self._plugin_name)
|
||||
button.connect("button-release-event", self._do_download)
|
||||
|
||||
plugin_list = self._builder.get_object("plugin_socket")
|
||||
self._module_event_observer()
|
||||
|
||||
plugin_list = self._fm_builder.get_object("plugin_socket")
|
||||
plugin_list.add(button)
|
||||
plugin_list.show_all()
|
||||
|
||||
@daemon_threaded
|
||||
def _module_event_observer(self):
|
||||
while True:
|
||||
time.sleep(self._event_sleep_time)
|
||||
event = self._fm_event_system.read_module_event()
|
||||
if event:
|
||||
try:
|
||||
if event[0] is self._plugin_name:
|
||||
target_id, method_target, data = self._fm_event_system.consume_module_event()
|
||||
|
||||
if not method_target:
|
||||
self._fm_event_message = data
|
||||
else:
|
||||
method = getattr(self.__class__, f"{method_target}")
|
||||
data = method(*(self, *parameters))
|
||||
except Exception as e:
|
||||
print(repr(e))
|
||||
|
||||
|
||||
@threaded
|
||||
def _do_download(self, widget=None, eve=None):
|
||||
self._event_system.push_gui_event([self._plugin_name, "get_current_state", ()])
|
||||
self._run_timeout()
|
||||
self._fm_event_system.push_gui_event([self._plugin_name, "get_current_state", ()])
|
||||
while not self._fm_event_message:
|
||||
pass
|
||||
|
||||
if self._message:
|
||||
state = self._message
|
||||
subprocess.Popen([f'{self.SCRIPT_PTH}/download.sh' , state.tab.get_current_directory()])
|
||||
self._message = None
|
||||
state = self._fm_event_message
|
||||
subprocess.Popen([f'{self.SCRIPT_PTH}/download.sh' , state.tab.get_current_directory()])
|
||||
self._fm_event_message = None
|
||||
|
||||
|
||||
def set_message(self, data):
|
||||
self._message = data
|
||||
|
||||
def get_plugin_name(self):
|
||||
return self._plugin_name
|
||||
|
||||
def _run_timeout(self):
|
||||
timeout = 0
|
||||
while not self._message and timeout < self._time_out:
|
||||
time.sleep(1)
|
||||
timeout += 1
|
||||
def get_plugin_author(self):
|
||||
return self._plugin_author
|
||||
|
||||
def get_plugin_version(self):
|
||||
return self._plugin_version
|
||||
|
|
|
@ -15,17 +15,17 @@ class EventSystem(IPCServer):
|
|||
def __init__(self):
|
||||
super(EventSystem, self).__init__()
|
||||
|
||||
# NOTE: The format used is list of [type, target, (data,)] Where:
|
||||
# type is useful context for control flow,
|
||||
# target is the method to call,
|
||||
# data is the method parameters to give
|
||||
# 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 fake "events" type system FIFO
|
||||
# Makeshift "events" system FIFO
|
||||
def _pop_gui_event(self) -> None:
|
||||
if len(self._gui_events) > 0:
|
||||
return self._gui_events.pop(0)
|
||||
|
@ -42,20 +42,20 @@ class EventSystem(IPCServer):
|
|||
self._gui_events.append(event)
|
||||
return None
|
||||
|
||||
raise Exception("Invald event format! Please do: [type, target, (data,)]")
|
||||
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: [type, target, (data,)]")
|
||||
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]
|
||||
return self._gui_events[0] if self._gui_events else None
|
||||
|
||||
def read_module_event(self) -> list:
|
||||
return self._module_events[0]
|
||||
return self._module_events[0] if self._module_events else None
|
||||
|
||||
def consume_gui_event(self) -> list:
|
||||
return self._pop_gui_event()
|
||||
|
@ -69,6 +69,6 @@ class EventSystem(IPCServer):
|
|||
# __builtins__.update({"event_system": Builtins()})
|
||||
builtins.app_name = "SolarFM"
|
||||
builtins.event_system = EventSystem()
|
||||
builtins.event_sleep_time = 0.2
|
||||
builtins.event_sleep_time = 0.05
|
||||
builtins.trace_debug = False
|
||||
builtins.debug = False
|
||||
|
|
|
@ -17,7 +17,7 @@ class Application(EventSystem):
|
|||
def __init__(self, args, unknownargs):
|
||||
if not trace_debug:
|
||||
event_system.create_ipc_listener()
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.05)
|
||||
|
||||
if not event_system.is_ipc_alive:
|
||||
if unknownargs:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Python imports
|
||||
import os, gc, threading, time, shlex
|
||||
import os, gc, threading, time
|
||||
|
||||
# Lib imports
|
||||
import gi
|
||||
|
@ -14,7 +14,14 @@ from .signals.keyboard_signals_mixin import KeyboardSignalsMixin
|
|||
from .controller_data import Controller_Data
|
||||
|
||||
|
||||
# NOTE: Threads will not die with parent's destruction
|
||||
def threaded(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
|
||||
def daemon_threaded(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start()
|
||||
return wrapper
|
||||
|
@ -62,20 +69,20 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
|
|||
event = event_system.consume_gui_event()
|
||||
if event:
|
||||
try:
|
||||
type, target, data = event
|
||||
if type:
|
||||
method = getattr(self.__class__, "handle_gui_event_and_set_message")
|
||||
GLib.idle_add(method, *(self, type, target, data))
|
||||
sender_id, method_target, parameters = event
|
||||
if sender_id:
|
||||
method = getattr(self.__class__, "handle_gui_event_and_return_message")
|
||||
GLib.idle_add(method, *(self, sender_id, method_target, parameters))
|
||||
else:
|
||||
method = getattr(self.__class__, target)
|
||||
GLib.idle_add(method, *(self, *data,))
|
||||
method = getattr(self.__class__, method_target)
|
||||
GLib.idle_add(method, *(self, *parameters,))
|
||||
except Exception as e:
|
||||
print(repr(e))
|
||||
|
||||
def handle_gui_event_and_set_message(self, type, target, parameters):
|
||||
method = getattr(self.__class__, f"{target}")
|
||||
def handle_gui_event_and_return_message(self, sender, method_target, parameters):
|
||||
method = getattr(self.__class__, f"{method_target}")
|
||||
data = method(*(self, *parameters))
|
||||
self.plugins.send_message_to_plugin(type, data)
|
||||
event_system.push_module_event([sender, None, data])
|
||||
|
||||
def save_load_session(self, action="save_session"):
|
||||
wid, tid = self.fm_controller.get_active_wid_and_tid()
|
||||
|
@ -110,7 +117,7 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
|
|||
|
||||
def load_session(self, session_json):
|
||||
if debug:
|
||||
print(f"Session Data: {session_json}")
|
||||
self.logger.debug(f"Session Data: {session_json}")
|
||||
|
||||
self.ctrl_down = False
|
||||
self.shift_down = False
|
||||
|
@ -186,5 +193,4 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
|
|||
def open_terminal(self, widget=None, eve=None):
|
||||
wid, tid = self.fm_controller.get_active_wid_and_tid()
|
||||
tab = self.get_fm_window(wid).get_tab_by_id(tid)
|
||||
dir = tab.get_current_directory()
|
||||
tab.execute([f"{tab.terminal_app}"], start_dir=shlex.quote(dir))
|
||||
tab.execute([f"{tab.terminal_app}"], start_dir=tab.get_current_directory())
|
||||
|
|
|
@ -45,7 +45,7 @@ class WidgetFileActionMixin:
|
|||
watcher = tab.get_dir_watcher()
|
||||
watcher.cancel()
|
||||
if debug:
|
||||
print(f"Watcher Is Cancelled: {watcher.is_cancelled()}")
|
||||
self.logger.debug(f"Watcher Is Cancelled: {watcher.is_cancelled()}")
|
||||
|
||||
cur_dir = tab.get_current_directory()
|
||||
|
||||
|
@ -64,7 +64,7 @@ class WidgetFileActionMixin:
|
|||
Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN,
|
||||
Gio.FileMonitorEvent.MOVED_OUT]:
|
||||
if debug:
|
||||
print(eve_type)
|
||||
self.logger.debug(eve_type)
|
||||
|
||||
if eve_type in [Gio.FileMonitorEvent.MOVED_IN, Gio.FileMonitorEvent.MOVED_OUT]:
|
||||
self.update_on_soft_lock_end(data[0])
|
||||
|
@ -85,7 +85,6 @@ class WidgetFileActionMixin:
|
|||
if (current_time - last_update_time) > 0.6:
|
||||
lock = False
|
||||
|
||||
|
||||
self.soft_update_lock.pop(tab_widget, None)
|
||||
GLib.idle_add(self.update_on_soft_lock_end, *(tab_widget,))
|
||||
|
||||
|
@ -427,10 +426,10 @@ class WidgetFileActionMixin:
|
|||
start = "-copy"
|
||||
|
||||
if debug:
|
||||
print(f"Path: {full_path}")
|
||||
print(f"Base Path: {base_path}")
|
||||
print(f'Name: {file_name}')
|
||||
print(f"Extension: {extension}")
|
||||
self.logger.debug(f"Path: {full_path}")
|
||||
self.logger.debug(f"Base Path: {base_path}")
|
||||
self.logger.debug(f'Name: {file_name}')
|
||||
self.logger.debug(f"Extension: {extension}")
|
||||
|
||||
i = 2
|
||||
while target.query_exists():
|
||||
|
|
|
@ -12,6 +12,8 @@ from gi.repository import Gtk, Gio
|
|||
|
||||
class Plugin:
|
||||
name: str = None
|
||||
author: str = None
|
||||
version: str = None
|
||||
module: str = None
|
||||
reference: type = None
|
||||
|
||||
|
@ -61,6 +63,9 @@ class Plugins:
|
|||
plugin_reference = app.Plugin(self._builder, event_system)
|
||||
plugin = Plugin()
|
||||
plugin.name = plugin_reference.get_plugin_name()
|
||||
plugin.author = plugin_reference.get_plugin_author()
|
||||
plugin.version = plugin_reference.get_plugin_version()
|
||||
|
||||
plugin.module = path
|
||||
plugin.reference = plugin_reference
|
||||
|
||||
|
@ -74,10 +79,3 @@ class Plugins:
|
|||
|
||||
def reload_plugins(self, file: str = None) -> None:
|
||||
print(f"Reloading plugins... stub.")
|
||||
|
||||
def send_message_to_plugin(self, target: str , data: type) -> None:
|
||||
print("Trying to send message to plugin...")
|
||||
for plugin in self._plugin_collection:
|
||||
if target in plugin.name:
|
||||
print('Found plugin; posting message...')
|
||||
plugin.reference.set_message(data)
|
||||
|
|
|
@ -59,7 +59,7 @@ class Launcher:
|
|||
app_info.launch_uris_async(uris)
|
||||
|
||||
def remux_video(self, hash, file):
|
||||
remux_vid_pth = self.REMUX_FOLDER + "/" + hash + ".mp4"
|
||||
remux_vid_pth = "{self.REMUX_FOLDER}/{hash}.mp4"
|
||||
self.logger.debug(remux_vid_pth)
|
||||
|
||||
if not os.path.isfile(remux_vid_pth):
|
||||
|
|
|
@ -5,39 +5,39 @@ import os, logging
|
|||
|
||||
|
||||
class Logger:
|
||||
def __init__(self, config_path: str):
|
||||
self._CONFIG_PATH = config_path
|
||||
|
||||
def get_logger(self, loggerName: str = "NO_LOGGER_NAME_PASSED", createFile: bool = True) -> logging.Logger:
|
||||
"""
|
||||
Create a new logging object and return it.
|
||||
:note:
|
||||
NOSET # Don't know the actual log level of this... (defaulting or literally none?)
|
||||
Log Levels (From least to most)
|
||||
"""
|
||||
Create a new logging object and return it.
|
||||
:note:
|
||||
NOSET # Don't know the actual log level of this... (defaulting or literally none?)
|
||||
Log Levels (From least to most)
|
||||
Type Value
|
||||
CRITICAL 50
|
||||
ERROR 40
|
||||
WARNING 30
|
||||
INFO 20
|
||||
DEBUG 10
|
||||
:param loggerName: Sets the name of the logger object. (Used in log lines)
|
||||
:param createFile: Whether we create a log file or just pump to terminal
|
||||
:param loggerName: Sets the name of the logger object. (Used in log lines)
|
||||
:param createFile: Whether we create a log file or just pump to terminal
|
||||
|
||||
:return: the logging object we created
|
||||
"""
|
||||
:return: the logging object we created
|
||||
"""
|
||||
|
||||
globalLogLvl = logging.DEBUG # Keep this at highest so that handlers can filter to their desired levels
|
||||
chLogLevel = logging.CRITICAL # Prety musch the only one we change ever
|
||||
fhLogLevel = logging.DEBUG
|
||||
def __init__(self, config_path: str, _ch_log_lvl = logging.CRITICAL, _fh_log_lvl = logging.INFO):
|
||||
self._CONFIG_PATH = config_path
|
||||
self.global_lvl = logging.DEBUG # Keep this at highest so that handlers can filter to their desired levels
|
||||
self.ch_log_lvl = _ch_log_lvl # Prety much the only one we ever change
|
||||
self.fh_log_lvl = _fh_log_lvl
|
||||
|
||||
def get_logger(self, loggerName: str = "NO_LOGGER_NAME_PASSED", createFile: bool = True) -> logging.Logger:
|
||||
log = logging.getLogger(loggerName)
|
||||
log.setLevel(globalLogLvl)
|
||||
log.setLevel(self.global_lvl)
|
||||
|
||||
# Set our log output styles
|
||||
fFormatter = logging.Formatter('[%(asctime)s] %(pathname)s:%(lineno)d %(levelname)s - %(message)s', '%m-%d %H:%M:%S')
|
||||
cFormatter = logging.Formatter('%(pathname)s:%(lineno)d] %(levelname)s - %(message)s')
|
||||
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(level=chLogLevel)
|
||||
ch.setLevel(level=self.ch_log_lvl)
|
||||
ch.setFormatter(cFormatter)
|
||||
log.addHandler(ch)
|
||||
|
||||
|
@ -49,7 +49,7 @@ class Logger:
|
|||
os.mkdir(folder)
|
||||
|
||||
fh = logging.FileHandler(file)
|
||||
fh.setLevel(level=fhLogLevel)
|
||||
fh.setLevel(level=self.fh_log_lvl)
|
||||
fh.setFormatter(fFormatter)
|
||||
log.addHandler(fh)
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ class Settings:
|
|||
self._keybindings.configure(keybindings)
|
||||
|
||||
self._main_window = None
|
||||
self._logger = Logger(self._CONFIG_PATH).get_logger()
|
||||
self._logger = Logger(self._CONFIG_PATH, _fh_log_lvl=20).get_logger()
|
||||
self._builder = Gtk.Builder()
|
||||
self._builder.add_from_file(self._GLADE_FILE)
|
||||
|
||||
|
|
Loading…
Reference in New Issue