From ca855712b195aa0cc5e06601c1990a2da9ac322c Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Tue, 1 Feb 2022 21:08:02 -0600 Subject: [PATCH] Moved custom exception hook; added some doc strings --- .../SolarFM/solarfm/__builtins__.py | 2 +- .../solarfm-0.0.1/SolarFM/solarfm/__init__.py | 2 + .../solarfm-0.0.1/SolarFM/solarfm/__main__.py | 2 + .../SolarFM/solarfm/controller/Controller.py | 62 ++----------------- .../solarfm/controller/Controller_Data.py | 54 ++++++++++++++-- .../solarfm/controller/IPCServerMixin.py | 1 + .../controller/mixins/ExceptionHookMixin.py | 62 +++++++++++++++++++ .../solarfm/controller/mixins/__init__.py | 1 + 8 files changed, 123 insertions(+), 63 deletions(-) create mode 100644 src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/mixins/ExceptionHookMixin.py diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/__builtins__.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/__builtins__.py index 519135a..3dcbd14 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/__builtins__.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/__builtins__.py @@ -10,7 +10,7 @@ from controller import IPCServerMixin class Builtins(IPCServerMixin): - """Docstring for __builtins__ extender""" + """ Inheret IPCServerMixin. Create an pub/sub systems. """ def __init__(self): # NOTE: The format used is list of [type, target, (data,)] Where: diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/__init__.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/__init__.py index cb48f8c..34d1fbd 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/__init__.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/__init__.py @@ -12,6 +12,8 @@ from __builtins__ import Builtins class Main(Builtins): + ''' 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() diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/__main__.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/__main__.py index 66870d2..727a85f 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/__main__.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/__main__.py @@ -19,6 +19,8 @@ from __init__ import Main if __name__ == "__main__": + ''' Set process title, get arguments, and create GTK main thread. ''' + try: # import web_pdb # web_pdb.set_trace() diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/Controller.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/Controller.py index 56f3949..3cfb511 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/Controller.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/Controller.py @@ -1,5 +1,5 @@ # Python imports -import sys, traceback, threading, inspect, os, time +import traceback, threading, inspect, os, time # Lib imports import gi @@ -7,7 +7,7 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib # Application imports -from .mixins import UIMixin +from .mixins import ExceptionHookMixin, UIMixin from .signals import IPCSignalsMixin, KeyboardSignalsMixin from . import Controller_Data @@ -20,9 +20,9 @@ def threaded(fn): -class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, 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): - sys.excepthook = self.custom_except_hook self.setup_controller_data(_settings) self.window.show() self.generate_windows(self.state) @@ -71,60 +71,6 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, Controller_Data data = method(*(self, *parameters)) self.plugins.set_message_on_plugin(type, data) - def custom_except_hook(self, exctype, value, _traceback): - trace = ''.join(traceback.format_tb(_traceback)) - data = f"Exectype: {exctype} <--> Value: {value}\n\n{trace}\n\n\n\n" - start_itr = self.message_buffer.get_start_iter() - self.message_buffer.place_cursor(start_itr) - self.display_message(self.error, data) - - def display_message(self, type, text, seconds=None): - self.message_buffer.insert_at_cursor(text) - self.message_widget.popup() - if seconds: - self.hide_message_timeout(seconds) - - @threaded - def hide_message_timeout(self, seconds=3): - time.sleep(seconds) - GLib.idle_add(self.message_widget.popdown) - - def save_debug_alerts(self, widget=None, eve=None): - start_itr, end_itr = self.message_buffer.get_bounds() - save_location_prompt = Gtk.FileChooserDialog("Choose Save Folder", self.window, \ - action = Gtk.FileChooserAction.SAVE, \ - buttons = (Gtk.STOCK_CANCEL, \ - Gtk.ResponseType.CANCEL, \ - Gtk.STOCK_SAVE, \ - Gtk.ResponseType.OK)) - - text = self.message_buffer.get_text(start_itr, end_itr, False) - resp = save_location_prompt.run() - if (resp == Gtk.ResponseType.CANCEL) or (resp == Gtk.ResponseType.DELETE_EVENT): - pass - elif resp == Gtk.ResponseType.OK: - target = save_location_prompt.get_filename(); - with open(target, "w") as f: - f.write(text) - - save_location_prompt.destroy() - - - def set_arc_buffer_text(self, widget=None, eve=None): - id = widget.get_active_id() - self.arc_command_buffer.set_text(self.arc_commands[int(id)]) - - - def clear_children(self, widget): - for child in widget.get_children(): - widget.remove(child) - - def get_current_state(self): - wid, tid = self.window_controller.get_active_data() - view = self.get_fm_window(wid).get_view_by_id(tid) - iconview = self.builder.get_object(f"{wid}|{tid}|iconview") - store = iconview.get_model() - return wid, tid, view, iconview, store def do_action_from_menu_controls(self, widget, eventbutton): action = widget.get_name() diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/Controller_Data.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/Controller_Data.py index fe97040..7453a63 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/Controller_Data.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/Controller_Data.py @@ -1,5 +1,5 @@ # Python imports -import signal +import sys, os, signal # Lib imports from gi.repository import GLib @@ -13,8 +13,7 @@ from plugins import Plugins class Controller_Data: - def has_method(self, o, name): - return callable(getattr(o, name, None)) + ''' Controller_Data contains most of the state of the app at ay given time. It also has some support methods. ''' def setup_controller_data(self, _settings): self.trashman = XDGTrash() @@ -104,6 +103,53 @@ class Controller_Data: self.warning = "#ffa800" self.error = "#ff0000" - + sys.excepthook = self.custom_except_hook self.window.connect("delete-event", self.tear_down) GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.tear_down) + + def get_current_state(self): + ''' + Returns the state info most useful for any given context and action intent. + + Parameters: + a (obj): self + + Returns: + wid, tid, view, iconview, store + ''' + wid, tid = self.window_controller.get_active_data() + view = self.get_fm_window(wid).get_view_by_id(tid) + iconview = self.builder.get_object(f"{wid}|{tid}|iconview") + store = iconview.get_model() + return wid, tid, view, iconview, store + + + 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) diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/IPCServerMixin.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/IPCServerMixin.py index 7410fb8..b273c9b 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/IPCServerMixin.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/IPCServerMixin.py @@ -16,6 +16,7 @@ def threaded(fn): class IPCServerMixin: + ''' Create a listener so that other SolarFM instances send requests back to existing instance. ''' @threaded def create_ipc_server(self): diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/mixins/ExceptionHookMixin.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/mixins/ExceptionHookMixin.py new file mode 100644 index 0000000..fecab38 --- /dev/null +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/mixins/ExceptionHookMixin.py @@ -0,0 +1,62 @@ +# Python imports +import traceback, threading, time + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk, GLib + +# Application imports + + +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start() + return wrapper + + +class ExceptionHookMixin: + ''' ExceptionHookMixin custom exception hook to reroute to a Gtk text area. ''' + + def custom_except_hook(self, exctype, value, _traceback): + trace = ''.join(traceback.format_tb(_traceback)) + data = f"Exectype: {exctype} <--> Value: {value}\n\n{trace}\n\n\n\n" + start_itr = self.message_buffer.get_start_iter() + self.message_buffer.place_cursor(start_itr) + self.display_message(self.error, data) + + def display_message(self, type, text, seconds=None): + self.message_buffer.insert_at_cursor(text) + self.message_widget.popup() + if seconds: + self.hide_message_timeout(seconds) + + @threaded + def hide_message_timeout(self, seconds=3): + time.sleep(seconds) + GLib.idle_add(self.message_widget.popdown) + + def save_debug_alerts(self, widget=None, eve=None): + start_itr, end_itr = self.message_buffer.get_bounds() + save_location_prompt = Gtk.FileChooserDialog("Choose Save Folder", self.window, \ + action = Gtk.FileChooserAction.SAVE, \ + buttons = (Gtk.STOCK_CANCEL, \ + Gtk.ResponseType.CANCEL, \ + Gtk.STOCK_SAVE, \ + Gtk.ResponseType.OK)) + + text = self.message_buffer.get_text(start_itr, end_itr, False) + resp = save_location_prompt.run() + if (resp == Gtk.ResponseType.CANCEL) or (resp == Gtk.ResponseType.DELETE_EVENT): + pass + elif resp == Gtk.ResponseType.OK: + target = save_location_prompt.get_filename(); + with open(target, "w") as f: + f.write(text) + + save_location_prompt.destroy() + + + def set_arc_buffer_text(self, widget=None, eve=None): + id = widget.get_active_id() + self.arc_command_buffer.set_text(self.arc_commands[int(id)]) diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/mixins/__init__.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/mixins/__init__.py index d4205b8..ec27013 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/mixins/__init__.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/controller/mixins/__init__.py @@ -1,2 +1,3 @@ from .ShowHideMixin import ShowHideMixin +from .ExceptionHookMixin import ExceptionHookMixin from .UIMixin import UIMixin