diff --git a/README.md b/README.md index de5bb36..cb2c302 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ A template project for Python with Gtk applications. * sqlmodel (SQL databases and is powered by Pydantic and SQLAlchemy) ### Note +* Move respetive sub folder content under user_config to the same places in Linux. Though, user/share/ can go to ~/.config folder if prefered. +* In additiion, place the plugins folder in the same app folder you moved to /usr/share/ or ~/.config/ . There are a "\" strings and files that need to be set according to your app's name located at: * \_\_builtins\_\_.py * user_config/bin/app_name @@ -18,4 +20,4 @@ There are a "\" strings and files that need to be set according to y For the user_config, after changing names and files, copy all content to their respective destinations. -The logic follows Debian Dpkg packaging and its placement logic. +The logic follows Debian Dpkg packaging and its placement logic. \ No newline at end of file diff --git a/src/__builtins__.py b/src/__builtins__.py index ef8f994..35fb50f 100644 --- a/src/__builtins__.py +++ b/src/__builtins__.py @@ -6,7 +6,7 @@ import sys # Lib imports # Application imports -from utils.models import engine +from utils.db import DB from utils.event_system import EventSystem from utils.endpoint_registry import EndpointRegistry from utils.keybindings import Keybindings @@ -18,13 +18,17 @@ from utils.settings_manager.manager import SettingsManager # NOTE: Threads WILL NOT die with parent's destruction. def threaded_wrapper(fn): def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start() + thread = threading.Thread(target = fn, args = args, kwargs = kwargs, daemon = False) + thread.start() + return thread return wrapper # NOTE: Threads WILL die with parent's destruction. def daemon_threaded_wrapper(fn): def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start() + thread = threading.Thread(target = fn, args = args, kwargs = kwargs, daemon = True) + thread.start() + return thread return wrapper @@ -32,12 +36,12 @@ 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 = "" -builtins.db = engine builtins.keybindings = Keybindings() builtins.event_system = EventSystem() builtins.endpoint_registry = EndpointRegistry() builtins.settings_manager = SettingsManager() +builtins.db = DB() settings_manager.load_settings() @@ -58,4 +62,4 @@ def custom_except_hook(exc_type, exc_value, exc_traceback): logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) -sys.excepthook = custom_except_hook +sys.excepthook = custom_except_hook \ No newline at end of file diff --git a/src/app.py b/src/app.py index 6621415..8bb6255 100644 --- a/src/app.py +++ b/src/app.py @@ -15,6 +15,7 @@ class AppLaunchException(Exception): ... + class Application(IPCServer): """ docstring for Application. """ @@ -30,7 +31,7 @@ class Application(IPCServer): message = f"FILE|{arg}" self.send_ipc_message(message) - raise AppLaunchException(f"{app_name} IPC Server Exists: Will send path(s) to it and close...") + raise AppLaunchException(f"{app_name} IPC Server Exists: Have sent path(s) to it and closing...") self.setup_debug_hook() Window(args, unknownargs) @@ -56,4 +57,4 @@ class Application(IPCServer): ) except ValueError: # Typically: ValueError: signal only works in main thread - ... + ... \ No newline at end of file diff --git a/src/core/containers/base_container.py b/src/core/containers/base_container.py index 7af1310..387cbbd 100644 --- a/src/core/containers/base_container.py +++ b/src/core/containers/base_container.py @@ -6,9 +6,8 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from .left_container import LeftContainer -from .center_container import CenterContainer -from .right_container import RightContainer +from .header_container import HeaderContainer +from .body_container import BodyContainer @@ -38,12 +37,11 @@ class BaseContainer(Gtk.Box): event_system.subscribe("remove_transparency", self._remove_transparency) def _load_widgets(self): - self.add(LeftContainer()) - self.add(CenterContainer()) - self.add(RightContainer()) + self.add(HeaderContainer()) + self.add(BodyContainer()) def _update_transparency(self): self.ctx.add_class(f"mw_transparency_{settings.theming.transparency}") def _remove_transparency(self): - self.ctx.remove_class(f"mw_transparency_{settings.theming.transparency}") + self.ctx.remove_class(f"mw_transparency_{settings.theming.transparency}") \ No newline at end of file diff --git a/src/core/containers/body_container.py b/src/core/containers/body_container.py new file mode 100644 index 0000000..e1d94b2 --- /dev/null +++ b/src/core/containers/body_container.py @@ -0,0 +1,44 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from .left_container import LeftContainer +from .center_container import CenterContainer +from .right_container import RightContainer + + + +class BodyContainer(Gtk.Box): + def __init__(self): + super(BodyContainer, self).__init__() + + self.ctx = self.get_style_context() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show_all() + + + def _setup_styling(self): + self.set_orientation(Gtk.Orientation.HORIZONTAL) + self.ctx.add_class("body-container") + self.set_homogeneous(True) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + + def _load_widgets(self): + self.add(LeftContainer()) + self.add(CenterContainer()) + self.add(RightContainer()) \ No newline at end of file diff --git a/src/core/containers/center_container.py b/src/core/containers/center_container.py index 102ea7a..58d7d71 100644 --- a/src/core/containers/center_container.py +++ b/src/core/containers/center_container.py @@ -6,7 +6,7 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from ..widgets.transparency_scale import TransparencyScale + class CenterContainer(Gtk.Box): @@ -35,21 +35,12 @@ class CenterContainer(Gtk.Box): def _load_widgets(self): glade_box = self._builder.get_object("glade_box") - glade_box = self._builder.get_object("glade_box") - button = Gtk.Button(label = "Interactive Debug") - button2 = Gtk.Button(label = "Click Me!") + button = Gtk.Button(label = "Click Me!") - button.connect("clicked", self._interactive_debug) - button2.connect("clicked", self._hello_world) + button.connect("clicked", self._hello_world) - self.add(TransparencyScale()) self.add(button) - self.add(button2) self.add(glade_box) - - def _interactive_debug(self, widget = None, eve = None): - event_system.emit("load_interactive_debug") - def _hello_world(self, widget = None, eve = None): - logger.debug("Hello, World!") + logger.debug("Hello, World!") \ No newline at end of file diff --git a/src/core/containers/header_container.py b/src/core/containers/header_container.py new file mode 100644 index 0000000..857cbeb --- /dev/null +++ b/src/core/containers/header_container.py @@ -0,0 +1,46 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from ..widgets.transparency_scale import TransparencyScale + + + +class HeaderContainer(Gtk.Box): + def __init__(self): + super(HeaderContainer, self).__init__() + + self.ctx = self.get_style_context() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show_all() + + + def _setup_styling(self): + self.set_orientation(Gtk.Orientation.HORIZONTAL) + self.ctx.add_class("header-container") + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + + def _load_widgets(self): + button = Gtk.Button(label = "Interactive Debug") + button.connect("clicked", self._interactive_debug) + + self.add(TransparencyScale()) + self.add(button) + + def _interactive_debug(self, widget = None, eve = None): + event_system.emit("load_interactive_debug") diff --git a/src/core/widgets/transparency_scale.py b/src/core/widgets/transparency_scale.py index f38ecae..1e48177 100644 --- a/src/core/widgets/transparency_scale.py +++ b/src/core/widgets/transparency_scale.py @@ -26,7 +26,7 @@ class TransparencyScale(Gtk.Scale): self.set_digits(0) self.set_value_pos(Gtk.PositionType.RIGHT) self.add_mark(50.0, Gtk.PositionType.TOP, "50%") - + self.set_hexpand(True) def _setup_signals(self): self.connect("value-changed", self._update_transparency) @@ -45,4 +45,4 @@ class TransparencyScale(Gtk.Scale): event_system.emit("remove_transparency") tp = int(range.get_value()) settings.theming.transparency = tp - event_system.emit("update_transparency") + event_system.emit("update_transparency") \ No newline at end of file diff --git a/src/utils/db.py b/src/utils/db.py new file mode 100644 index 0000000..0ff6ea2 --- /dev/null +++ b/src/utils/db.py @@ -0,0 +1,38 @@ +# Python imports +from typing import Optional +from os import path + +# Lib imports +from sqlmodel import Session, create_engine + +# Application imports +from .models import SQLModel, User + + + +class DB: + def __init__(self): + super(DB, self).__init__() + + self.create_engine() + + # NOTE: for sake of example we create an admin user with no password set. + self.add_user_entry(name = "Admin", password = "", email = "admin@domain.com") + + def create_engine(self): + db_path = f"sqlite:///{settings_manager.get_home_config_path()}/database.db" + self.engine = create_engine(db_path) + + SQLModel.metadata.create_all(self.engine) + + def _add_entry(self, entry): + with Session(self.engine) as session: + session.add(entry) + session.commit() + + + def add_user_entry(self, name = None, password = None, email = None): + if not name or not password or not email: return + + user = User(name, password, email) + self._add_entry(user) diff --git a/src/utils/models.py b/src/utils/models.py index 2f6100b..4ce4007 100644 --- a/src/utils/models.py +++ b/src/utils/models.py @@ -2,7 +2,7 @@ from typing import Optional # Lib imports -from sqlmodel import Field, Session, SQLModel, create_engine +from sqlmodel import SQLModel, Field # Application imports @@ -13,13 +13,3 @@ class User(SQLModel, table = True): name: str password: str email: Optional[str] = None - - -# NOTE: for sake of example we create an admin user with no password set. -user = User(name = "Admin", password = "", email = "admin@domain.com") -engine = create_engine("sqlite:///database.db") -SQLModel.metadata.create_all(engine) - -with Session(engine) as session: - session.add(user) - session.commit()