Moved custom exception hook; added some doc strings
This commit is contained in:
parent
95c6f79627
commit
ca855712b1
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)])
|
|
@ -1,2 +1,3 @@
|
|||
from .ShowHideMixin import ShowHideMixin
|
||||
from .ExceptionHookMixin import ExceptionHookMixin
|
||||
from .UIMixin import UIMixin
|
||||
|
|
Loading…
Reference in New Issue