Rewired settings, improved plugin structural coupling, cleanedup session file generation n load

This commit is contained in:
2022-10-09 20:59:44 -05:00
parent 206f67f2f0
commit e96d9e682d
31 changed files with 232 additions and 172 deletions

View File

@@ -6,7 +6,7 @@ import builtins, threading
# Application imports
from utils.event_system import EventSystem
from utils.endpoint_registry import EndpointRegistry
from utils.settings import Settings
@@ -28,11 +28,11 @@ def daemon_threaded_wrapper(fn):
# NOTE: Just reminding myself we can add to builtins two different ways...
# __builtins__.update({"event_system": Builtins()})
builtins.app_name = "SolarFM"
builtins.settings = Settings()
builtins.logger = settings.get_logger()
builtins.event_system = EventSystem()
builtins.endpoint_registry = EndpointRegistry()
builtins.threaded = threaded_wrapper
builtins.daemon_threaded = daemon_threaded_wrapper
builtins.event_sleep_time = 0.05
builtins.trace_debug = False
builtins.debug = False
builtins.app_settings = None

View File

@@ -15,6 +15,7 @@ gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from __builtins__ import *
from app import Application
@@ -27,6 +28,9 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser()
# Add long and short arguments
parser.add_argument("--debug", "-d", default="false", help="Do extra console messaging.")
parser.add_argument("--trace-debug", "-td", default="false", help="Disable saves, ignore IPC lock, do extra console messaging.")
parser.add_argument("--new-tab", "-t", default="", help="Open a file into new tab.")
parser.add_argument("--new-window", "-w", default="", help="Open a file into a new window.")
# Read arguments (If any...)

View File

@@ -4,7 +4,7 @@ import os, inspect, time
# Lib imports
# Application imports
from __builtins__ import *
from utils.ipc_server import IPCServer
from utils.settings import Settings
from core.controller import Controller
@@ -22,8 +22,14 @@ class Application(IPCServer):
def __init__(self, args, unknownargs):
super(Application, self).__init__()
if args.debug == "true":
settings.set_debug(True)
if not trace_debug:
if args.trace_debug == "true":
settings.set_trace_debug(True)
# NOTE: Instance found, sending files to it...
if not settings.is_trace_debug():
self.create_ipc_listener()
time.sleep(0.05)
@@ -41,10 +47,9 @@ class Application(IPCServer):
raise AppLaunchException(f"IPC Server Exists: Will send path(s) to it and close...\nNote: If no fm exists, remove /tmp/{app_name}-ipc.sock")
settings = Settings()
settings.create_window()
controller = Controller(args, unknownargs, settings)
controller = Controller(args, unknownargs)
if not controller:
raise ControllerStartExceptio("Controller exited and doesn't exist...")

View File

@@ -18,18 +18,18 @@ from .controller_data import Controller_Data
class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMixin, Controller_Data):
""" Controller coordinates the mixins and is somewhat the root hub of it all. """
def __init__(self, args, unknownargs, _settings):
self.setup_controller_data(_settings)
def __init__(self, args, unknownargs):
self.setup_controller_data()
self.window.show()
self.generate_windows(self.fm_controller_data)
self.plugins.launch_plugins()
if debug:
if settings.is_debug():
self.window.set_interactive_debugging(True)
if not trace_debug:
# NOTE: Open files if passed in from cli and not trace debugging...
if not settings.is_trace_debug():
self._subscribe_to_events()
if unknownargs:
@@ -51,7 +51,9 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
event_system.subscribe("do_hide_context_menu", self.do_hide_context_menu)
def tear_down(self, widget=None, eve=None):
self.fm_controller.save_state()
if not settings.is_trace_debug():
self.fm_controller.save_state()
time.sleep(event_sleep_time)
Gtk.main_quit()
@@ -62,7 +64,9 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
save_load_dialog = self.builder.get_object("save_load_dialog")
if action == "save_session":
self.fm_controller.save_state()
if not settings.is_trace_debug():
self.fm_controller.save_state()
return
elif action == "save_session_as":
save_load_dialog.set_action(Gtk.FileChooserAction.SAVE)
@@ -88,8 +92,8 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
save_load_dialog.hide()
def load_session(self, session_json):
if debug:
self.logger.debug(f"Session Data: {session_json}")
if settings.is_debug():
logger.debug(f"Session Data: {session_json}")
self.ctrl_down = False
self.shift_down = False

View File

@@ -28,17 +28,15 @@ class Controller_Data:
""" Controller_Data contains most of the state of the app at ay given time. It also has some support methods. """
__slots__ = "settings", "builder", "logger", "keybindings", "trashman", "fm_controller", "window", "window1", "window2", "window3", "window4"
def setup_controller_data(self, _settings: type) -> None:
self.settings = _settings
self.builder = self.settings.get_builder()
self.logger = self.settings.get_logger()
self.keybindings = self.settings.get_keybindings()
def setup_controller_data(self) -> None:
self.builder = settings.get_builder()
self.keybindings = settings.get_keybindings()
self.fm_controller = WindowController()
self.plugins = PluginsController(_settings)
self.plugins = PluginsController()
self.fm_controller_data = self.fm_controller.get_state_from_file()
self.window = self.settings.get_main_window()
self.window = settings.get_main_window()
self.window1 = self.builder.get_object("window_1")
self.window2 = self.builder.get_object("window_2")
self.window3 = self.builder.get_object("window_3")
@@ -64,7 +62,7 @@ class Controller_Data:
self.trash_files_path = f"{GLib.get_user_data_dir()}/Trash/files"
self.trash_info_path = f"{GLib.get_user_data_dir()}/Trash/info"
self.icon_theme = self.settings.get_icon_theme()
self.icon_theme = settings.get_icon_theme()
# In compress commands:
# %n: First selected filename/dir to archive
@@ -116,9 +114,9 @@ class Controller_Data:
self.shift_down = False
self.alt_down = False
self.success_color = self.settings.get_success_color()
self.warning_color = self.settings.get_warning_color()
self.error_color = self.settings.get_error_color()
self.success_color = settings.get_success_color()
self.warning_color = settings.get_warning_color()
self.error_color = settings.get_error_color()
# sys.excepthook = self.custom_except_hook
self.window.connect("delete-event", self.tear_down)

View File

@@ -61,7 +61,7 @@ class GridMixin:
self.create_icon(i, tab, store, dir, file[0])
# NOTE: Not likely called often from here but it could be useful
if save_state:
if save_state and not trace_debug:
self.fm_controller.save_state()
@threaded

View File

@@ -56,4 +56,5 @@ class PaneMixin:
def _save_state(self, state, pane_index):
window = self.fm_controller.get_window_by_index(pane_index - 1)
window.set_is_hidden(state)
self.fm_controller.save_state()
if not settings.is_trace_debug():
self.fm_controller.save_state()

View File

@@ -22,7 +22,7 @@ class TabMixin(GridMixin):
notebook = self.builder.get_object(f"window_{wid}")
path_entry = self.builder.get_object(f"path_entry")
tab = self.fm_controller.add_tab_for_window_by_nickname(f"window_{wid}")
tab.logger = self.logger
tab.logger = logger
tab.set_wid(wid)
if not path:
@@ -63,7 +63,8 @@ class TabMixin(GridMixin):
watcher.cancel()
self.get_fm_window(wid).delete_tab_by_id(tid)
notebook.remove_page(page)
self.fm_controller.save_state()
if not settings.is_trace_debug():
self.fm_controller.save_state()
self.set_window_title()
def on_tab_reorder(self, child, page_num, new_index):
@@ -80,7 +81,8 @@ class TabMixin(GridMixin):
tab = window.get_tab_by_id(tid)
self.set_file_watcher(tab)
self.fm_controller.save_state()
if not settings.is_trace_debug():
self.fm_controller.save_state()
def on_tab_switch_update(self, notebook, content=None, index=None):
self.selected_files.clear()
@@ -115,7 +117,8 @@ class TabMixin(GridMixin):
tab_label.set_label(tab.get_end_of_path())
self.set_window_title()
self.set_file_watcher(tab)
self.fm_controller.save_state()
if not settings.is_trace_debug():
self.fm_controller.save_state()
def do_action_from_bar_controls(self, widget, eve=None):
action = widget.get_name()
@@ -127,7 +130,9 @@ class TabMixin(GridMixin):
if action == "create_tab":
dir = tab.get_current_directory()
self.create_tab(wid, None, dir)
self.fm_controller.save_state()
if not settings.is_trace_debug():
self.fm_controller.save_state()
return
if action == "go_up":
tab.pop_from_path()

View File

@@ -40,8 +40,8 @@ class WidgetFileActionMixin:
if tab.get_dir_watcher():
watcher = tab.get_dir_watcher()
watcher.cancel()
if debug:
self.logger.debug(f"Watcher Is Cancelled: {watcher.is_cancelled()}")
if settings.is_debug():
logger.debug(f"Watcher Is Cancelled: {watcher.is_cancelled()}")
cur_dir = tab.get_current_directory()
@@ -59,8 +59,8 @@ class WidgetFileActionMixin:
if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED,
Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN,
Gio.FileMonitorEvent.MOVED_OUT]:
if debug:
self.logger.debug(eve_type)
if settings.is_debug():
logger.debug(eve_type)
if eve_type in [Gio.FileMonitorEvent.MOVED_IN, Gio.FileMonitorEvent.MOVED_OUT]:
self.update_on_soft_lock_end(data[0])
@@ -389,11 +389,11 @@ class WidgetFileActionMixin:
target = Gio.File.new_for_path(full_path)
start = "-copy"
if debug:
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}")
if settings.is_debug():
logger.debug(f"Path: {full_path}")
logger.debug(f"Base Path: {base_path}")
logger.debug(f'Name: {file_name}')
logger.debug(f"Extension: {extension}")
i = 2
while target.query_exists():

View File

@@ -24,8 +24,8 @@ class WindowMixin(TabMixin):
for j, value in enumerate(session_json):
i = j + 1
notebook_tggl_button = self.builder.get_object(f"tggl_notebook_{i}")
is_hidden = True if value[0]["window"]["isHidden"] == "True" else False
tabs = value[0]["window"]["tabs"]
is_hidden = True if value["window"]["isHidden"] == "True" else False
tabs = value["window"]["tabs"]
self.fm_controller.create_window()
notebook_tggl_button.set_active(True)
@@ -112,7 +112,7 @@ class WindowMixin(TabMixin):
file_size = file_info.get_size()
combined_size += file_size
except WindowException as e:
if debug:
if settings.is_debug():
print(repr(e))

View File

@@ -55,7 +55,7 @@ class KeyboardSignalsMixin:
sender, eve_type = mapping.split("||")
self.handle_plugin_key_event(sender, eve_type)
else:
if debug:
if settings.is_debug():
print(f"on_global_key_release_controller > key > {keyname}")
if self.ctrl_down:
@@ -91,5 +91,6 @@ class KeyboardSignalsMixin:
self.get_fm_window(wid).delete_tab_by_id(tid)
notebook.remove_page(page)
self.fm_controller.save_state()
if not trace_debug:
self.fm_controller.save_state()
self.set_window_title()

View File

@@ -6,6 +6,10 @@ import os, time
# Application imports
class PluginBaseException(Exception):
...
class PluginBase:
def __init__(self):
self.name = "Example Plugin" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus
@@ -18,14 +22,23 @@ class PluginBase:
def set_fm_event_system(self, fm_event_system):
"""
Requests Key: 'pass_fm_events': "true"
Must define in plugin if "pass_fm_events" is set to "true" string.
"""
self._event_system = fm_event_system
def set_ui_object_collection(self, ui_objects):
"""
Requests Key: "pass_ui_objects": [""]
Request reference to a UI component. Will be passed back as array to plugin.
Must define in plugin if set and an array of valid glade UI IDs is given.
"""
self._ui_objects = ui_objects
def clear_children(self, widget: type) -> None:
''' Clear children of a gtk widget. '''
""" Clear children of a gtk widget. """
for child in widget.get_children():
widget.remove(child)
@@ -34,3 +47,18 @@ class PluginBase:
def _update_fm_state_info(self, state):
self._fm_state = state
def generate_reference_ui_element(self):
"""
Requests Key: 'ui_target': "plugin_control_list",
Must define regardless if needed and can 'pass' if plugin doesn't use it.
Must return a widget if "ui_target" is set.
"""
raise PluginBaseException("Method hasn't been overriden...")
def run(self):
"""
Must define regardless if needed and can 'pass' if plugin doesn't need it.
Is intended to be used to setup internal signals or custom Gtk Builders/UI logic.
"""
raise PluginBaseException("Method hasn't been overriden...")

View File

@@ -20,14 +20,13 @@ class InvalidPluginException(Exception):
class PluginsController:
"""PluginsController controller"""
def __init__(self, settings: type):
def __init__(self):
path = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, path) # NOTE: I think I'm not using this correctly...
self._settings = settings
self._builder = self._settings.get_builder()
self._plugins_path = self._settings.get_plugins_path()
self._keybindings = self._settings.get_keybindings()
self._builder = settings.get_builder()
self._plugins_path = settings.get_plugins_path()
self._keybindings = settings.get_keybindings()
self._plugins_dir_watcher = None
self._plugin_collection = []
@@ -95,7 +94,7 @@ class PluginsController:
keys = loading_data.keys()
if "ui_target" in keys:
loading_data["ui_target"].add( plugin.reference.get_ui_element() )
loading_data["ui_target"].add( plugin.reference.generate_reference_ui_element() )
loading_data["ui_target"].show_all()
if "pass_ui_objects" in keys:

View File

@@ -158,17 +158,15 @@ class WindowController:
tabs.append(tab.get_current_directory())
windows.append(
[
{
'window':{
"ID": window.get_id(),
"Name": window.get_name(),
"Nickname": window.get_nickname(),
"isHidden": f"{window.is_hidden()}",
'tabs': tabs
}
{
'window':{
"ID": window.get_id(),
"Name": window.get_name(),
"Nickname": window.get_nickname(),
"isHidden": f"{window.is_hidden()}",
'tabs': tabs
}
]
}
)
with open(session_file, 'w') as outfile:

View File

@@ -322,10 +322,8 @@ def getIconPath(iconname, size = None, theme = None, extensions = ["png", "svg",
icon_cache[tmp] = [time.time(), icon]
return icon
except UnicodeDecodeError as e:
if debug:
raise e
else:
pass
...
# we haven't found anything? "hicolor" is our fallback
if theme != "hicolor":

View File

@@ -59,7 +59,7 @@ class IPCServer:
def handle_message(self, conn, start_time) -> None:
while True:
msg = conn.recv()
if debug:
if settings.is_debug():
print(msg)
if "FILE|" in msg:

View File

@@ -63,6 +63,9 @@ class Settings:
self._builder = Gtk.Builder()
self._builder.add_from_file(self._GLADE_FILE)
self._trace_debug = False
self._debug = False
def create_window(self) -> None:
# Get window and connect signals
@@ -111,3 +114,13 @@ class Settings:
def get_success_color(self) -> str: return self._success_color
def get_warning_color(self) -> str: return self._warning_color
def get_error_color(self) -> str: return self._error_color
def is_trace_debug(self) -> str: return self._trace_debug
def is_debug(self) -> str: return self._debug
def set_trace_debug(self, trace_debug):
self._trace_debug = trace_debug
def set_debug(self, debug):
self._debug = debug