diff --git a/src/__builtins__.py b/src/__builtins__.py index e1bfefc..6bcd9b1 100644 --- a/src/__builtins__.py +++ b/src/__builtins__.py @@ -6,14 +6,15 @@ import builtins # Lib imports # Application imports -from controller import IPCServerMixin +from ipc_server import IPCServer -class Builtins(IPCServerMixin): +class EventSystem(IPCServer): """Docstring for __builtins__ extender""" 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, @@ -21,11 +22,7 @@ class Builtins(IPCServerMixin): # Where data may be any kind of data self._gui_events = [] self._module_events = [] - self.is_ipc_alive = False - self.ipc_authkey = b'mirage-ipc' - self.ipc_address = '127.0.0.1' - self.ipc_port = 8877 - self.ipc_timeout = 15.0 + # Makeshift fake "events" type system FIFO def _pop_gui_event(self): @@ -70,7 +67,7 @@ class Builtins(IPCServerMixin): # NOTE: Just reminding myself we can add to builtins two different ways... # __builtins__.update({"event_system": Builtins()}) builtins.app_name = "Mirage2" -builtins.event_system = Builtins() +builtins.event_system = EventSystem() builtins.event_sleep_time = 0.2 builtins.debug = False builtins.trace_debug = False diff --git a/src/__init__.py b/src/__init__.py index 5e629c1..cd8371b 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,51 +1,3 @@ -# Python imports -import os, inspect, time - -# Lib imports - -# Application imports -from utils import Settings -from controller import Controller -from __builtins__ import Builtins - - - - -class Main(Builtins): - def __init__(self, args, unknownargs): - if not debug: - event_system.create_ipc_server() - - # NOTE: Keeping here just incase I change my mind... - # time.sleep(0.2) - # if not trace_debug: - # if not event_system.is_ipc_alive: - # if unknownargs: - # for arg in unknownargs: - # if os.path.isdir(arg): - # message = f"FILE|{arg}" - # event_system.send_ipc_message(message) - # - # raise Exception("IPC Server Exists: Will send data to it and close...") - - - settings = Settings() - settings.create_window() - - controller = Controller(settings, args, unknownargs) - if not controller: - raise Exception("Controller exited and doesn't exist...") - - # Gets the methods from the classes and sets to handler. - # Then, builder from settings will connect to any signals it needs. - classes = [controller] - handlers = {} - for c in classes: - methods = None - try: - methods = inspect.getmembers(c, predicate=inspect.ismethod) - handlers.update(methods) - except Exception as e: - print(repr(e)) - - settings.get_builder().connect_signals(handlers) +""" + Base module +""" diff --git a/src/__main__.py b/src/__main__.py index a58f911..6606814 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -15,7 +15,7 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from __init__ import Main +from app import Application if __name__ == "__main__": @@ -28,13 +28,13 @@ if __name__ == "__main__": parser = argparse.ArgumentParser() # Add long and short arguments - parser.add_argument("--file", "-f", default=None, help="JOpen an image.") - parser.add_argument("--dir", "-d", default=None, help="load a dir with images.") + parser.add_argument("--file", "-f", default=None, help="Open an image.") + parser.add_argument("--dir", "-d", default=None, help="Load a dir with images.") # Read arguments (If any...) args, unknownargs = parser.parse_known_args() - Main(args, unknownargs) + Application(args, unknownargs) Gtk.main() except Exception as e: traceback.print_exc() diff --git a/src/app.py b/src/app.py new file mode 100644 index 0000000..9d6e4d2 --- /dev/null +++ b/src/app.py @@ -0,0 +1,51 @@ +# Python imports +import os, inspect, time + +# Lib imports + +# Application imports +from utils.settings import Settings +from context.controller import Controller +from __builtins__ import EventSystem + + + + +class Application(EventSystem): + def __init__(self, args, unknownargs): + if not debug: + event_system.create_ipc_server() + + # NOTE: Keeping here just in case I change my mind... + # time.sleep(0.2) + # if not trace_debug: + # if not event_system.is_ipc_alive: + # if unknownargs: + # for arg in unknownargs: + # if os.path.isdir(arg): + # message = f"FILE|{arg}" + # event_system.send_ipc_message(message) + # + # raise Exception("IPC Server Exists: Will send data to it and close...") + + + settings = Settings() + settings.create_window() + + controller = Controller(settings, args, unknownargs) + if not controller: + raise Exception("Controller exited and doesn't exist...") + + # Gets the methods from the classes and sets to handler. + # Then, builder from settings will connect to any signals it needs. + classes = [controller] + handlers = {} + for c in classes: + methods = None + try: + methods = inspect.getmembers(c, predicate=inspect.ismethod) + handlers.update(methods) + except Exception as e: + print(repr(e)) + + settings.get_builder().connect_signals(handlers) diff --git a/src/context/__init__.py b/src/context/__init__.py new file mode 100644 index 0000000..90cfadc --- /dev/null +++ b/src/context/__init__.py @@ -0,0 +1,3 @@ +""" + Gtk Bound Signal Module +""" diff --git a/src/controller/Controller.py b/src/context/controller.py similarity index 73% rename from src/controller/Controller.py rename to src/context/controller.py index acba0f8..b43b1cf 100644 --- a/src/controller/Controller.py +++ b/src/context/controller.py @@ -9,9 +9,8 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib, GdkPixbuf # Application imports -from .mixins import * -from . import Controller_Data - +from .controller_data import Controller_Data +from .mixins.tree_view_update_mixin import TreeViewUpdateMixin def threaded(fn): @@ -51,6 +50,7 @@ class Controller(TreeViewUpdateMixin, Controller_Data): GLib.idle_add(method, *(self, type, target, data)) except Exception as e: print(repr(e)) + self.logger.debug(e) def hadle_gui_event_and_call_back(self, type, target, parameters): method = getattr(self.__class__, target) @@ -59,25 +59,24 @@ class Controller(TreeViewUpdateMixin, Controller_Data): def handle_args(self, args=None, unknownargs=None): + print(f"Args: {args}") + print(f"Unknownargs: {unknownargs}") if args.dir and os.path.isdir(args.dir): self.load_store(self.view, self.thumbnail_store, arg) if args.file and os.path.isfile(args.file): - path = "/" + '/'.join(rgs.file.split("/")[:-1]) + path = '/'.join(rgs.file.split("/")[:-1]) self.load_store(self.view, self.thumbnail_store, path) - image = Gtk.Image.new_from_pixbuf(self._get_pixbuf(args.file)) - self._load_image(image) + self.process_path(args.file) if unknownargs: for arg in unknownargs: if os.path.isdir(arg): self.load_store(self.view, self.thumbnail_store, arg) elif os.path.isfile(arg): - path = "/" + '/'.join(arg.split("/")[:-1]) + path = '/'.join(arg.split("/")[:-1]) self.load_store(self.view, self.thumbnail_store, path) - image = Gtk.Image.new_from_pixbuf(self._get_pixbuf(arg)) - self._load_image(image) - + self.process_path(arg) def _on_drag_data_received(self, widget, drag_context, x, y, data, info, time): @@ -96,22 +95,36 @@ class Controller(TreeViewUpdateMixin, Controller_Data): def load_image_from_treeview(self, widget): store, iter = widget.get_selection().get_selected() - uri = store.get_value(iter, 1) - image = Gtk.Image.new_from_pixbuf(self._get_pixbuf(uri)) - self._load_image(image) + uri = store.get_value(iter, 1) + + if uri == self.current_img_uri: + return + + self.process_path(uri) + + def process_path(self, uri): + self.current_img_uri = uri + self.current_path_label.set_label(uri) + if not uri.endswith(".gif"): + self.is_img_gif = False + self.current_img = Gtk.Image.new_from_pixbuf(self._get_pixbuf(uri)) + self._load_image() + else: + self.is_img_gif = True + self.current_img = Gtk.Image.new_from_file(uri) + self.gif_animation = self.current_img.get_animation() + self._load_image() def _get_pixbuf(self, uri): - self.current_path_label.set_label(uri) - self.current_img = uri geom_rec = self.image_area.get_parent().get_parent().get_allocated_size()[0] width = geom_rec.width - 15 height = geom_rec.height - 15 self.image_area.set_size_request(width, height) return GdkPixbuf.Pixbuf.new_from_file_at_scale(uri, width, height, True) - def _load_image(self, img): + def _load_image(self): self.clear_children(self.image_area) - self.image_area.add(img) + self.image_area.add(self.current_img) self.image_area.show_all() @threaded @@ -121,10 +134,19 @@ class Controller(TreeViewUpdateMixin, Controller_Data): def _on_scale_image_from_parent_resize(self, eve): - if self.current_img: + if self.current_img_uri: self.image_update_lock = True - image = Gtk.Image.new_from_pixbuf(self._get_pixbuf(self.current_img)) - self._load_image(image) + + if not self.is_img_gif: + self.current_img = Gtk.Image.new_from_pixbuf(self._get_pixbuf(self.current_img_uri)) + self._load_image() + else: + try: + self.gif_animation.advance() + self.current_img.set_from_animation(self.gif_animation) + except Exception: + pass + self.image_update_lock = False def get_clipboard_data(self): diff --git a/src/controller/Controller_Data.py b/src/context/controller_data.py similarity index 93% rename from src/controller/Controller_Data.py rename to src/context/controller_data.py index c74e03d..c880e37 100644 --- a/src/controller/Controller_Data.py +++ b/src/context/controller_data.py @@ -8,7 +8,7 @@ gi.require_version('Gdk', '3.0') from gi.repository import Gtk, Gdk, GLib # Application imports -from . import View +from .view import View @@ -40,14 +40,12 @@ class Controller_Data: self.warning_color = self.settings.get_warning_color() self.error_color = self.settings.get_error_color() - self.current_path_label = self.builder.get_object("current_path_label") self.thumbnails_view = self.builder.get_object("thumbnails_view") self.thumbnail_store = self.builder.get_object("thumbnail_store") self.image_area = self.builder.get_object("image_area") self.blank_image = self.settings.get_blank_image() - self.thumbnails_view.connect("drag-data-received", self._on_drag_data_received) URI_TARGET_TYPE = 80 uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE) @@ -58,7 +56,10 @@ class Controller_Data: self.images_filter = self.settings.get_images_filter() self.view = View(self.images_filter, self.blank_image) - self.current_img = None + self.current_img_uri = None + self.current_img = None + self.gif_animation = None + self.is_img_gif = False self.image_update_lock = False diff --git a/src/controller/icons/__init__.py b/src/context/icons/__init__.py similarity index 100% rename from src/controller/icons/__init__.py rename to src/context/icons/__init__.py diff --git a/src/controller/icons/icon.py b/src/context/icons/icon.py similarity index 100% rename from src/controller/icons/icon.py rename to src/context/icons/icon.py diff --git a/src/controller/icons/mixins/__init__.py b/src/context/icons/mixins/__init__.py similarity index 100% rename from src/controller/icons/mixins/__init__.py rename to src/context/icons/mixins/__init__.py diff --git a/src/controller/icons/mixins/desktopiconmixin.py b/src/context/icons/mixins/desktopiconmixin.py similarity index 100% rename from src/controller/icons/mixins/desktopiconmixin.py rename to src/context/icons/mixins/desktopiconmixin.py diff --git a/src/controller/icons/mixins/videoiconmixin.py b/src/context/icons/mixins/videoiconmixin.py similarity index 100% rename from src/controller/icons/mixins/videoiconmixin.py rename to src/context/icons/mixins/videoiconmixin.py diff --git a/src/controller/icons/mixins/xdg/BaseDirectory.py b/src/context/icons/mixins/xdg/BaseDirectory.py similarity index 100% rename from src/controller/icons/mixins/xdg/BaseDirectory.py rename to src/context/icons/mixins/xdg/BaseDirectory.py diff --git a/src/controller/icons/mixins/xdg/Config.py b/src/context/icons/mixins/xdg/Config.py similarity index 100% rename from src/controller/icons/mixins/xdg/Config.py rename to src/context/icons/mixins/xdg/Config.py diff --git a/src/controller/icons/mixins/xdg/DesktopEntry.py b/src/context/icons/mixins/xdg/DesktopEntry.py similarity index 100% rename from src/controller/icons/mixins/xdg/DesktopEntry.py rename to src/context/icons/mixins/xdg/DesktopEntry.py diff --git a/src/controller/icons/mixins/xdg/Exceptions.py b/src/context/icons/mixins/xdg/Exceptions.py similarity index 100% rename from src/controller/icons/mixins/xdg/Exceptions.py rename to src/context/icons/mixins/xdg/Exceptions.py diff --git a/src/controller/icons/mixins/xdg/IconTheme.py b/src/context/icons/mixins/xdg/IconTheme.py similarity index 100% rename from src/controller/icons/mixins/xdg/IconTheme.py rename to src/context/icons/mixins/xdg/IconTheme.py diff --git a/src/controller/icons/mixins/xdg/IniFile.py b/src/context/icons/mixins/xdg/IniFile.py similarity index 100% rename from src/controller/icons/mixins/xdg/IniFile.py rename to src/context/icons/mixins/xdg/IniFile.py diff --git a/src/controller/icons/mixins/xdg/Locale.py b/src/context/icons/mixins/xdg/Locale.py similarity index 100% rename from src/controller/icons/mixins/xdg/Locale.py rename to src/context/icons/mixins/xdg/Locale.py diff --git a/src/controller/icons/mixins/xdg/Menu.py b/src/context/icons/mixins/xdg/Menu.py similarity index 100% rename from src/controller/icons/mixins/xdg/Menu.py rename to src/context/icons/mixins/xdg/Menu.py diff --git a/src/controller/icons/mixins/xdg/MenuEditor.py b/src/context/icons/mixins/xdg/MenuEditor.py similarity index 100% rename from src/controller/icons/mixins/xdg/MenuEditor.py rename to src/context/icons/mixins/xdg/MenuEditor.py diff --git a/src/controller/icons/mixins/xdg/Mime.py b/src/context/icons/mixins/xdg/Mime.py similarity index 100% rename from src/controller/icons/mixins/xdg/Mime.py rename to src/context/icons/mixins/xdg/Mime.py diff --git a/src/controller/icons/mixins/xdg/RecentFiles.py b/src/context/icons/mixins/xdg/RecentFiles.py similarity index 100% rename from src/controller/icons/mixins/xdg/RecentFiles.py rename to src/context/icons/mixins/xdg/RecentFiles.py diff --git a/src/controller/icons/mixins/xdg/__init__.py b/src/context/icons/mixins/xdg/__init__.py similarity index 100% rename from src/controller/icons/mixins/xdg/__init__.py rename to src/context/icons/mixins/xdg/__init__.py diff --git a/src/controller/icons/mixins/xdg/util.py b/src/context/icons/mixins/xdg/util.py similarity index 100% rename from src/controller/icons/mixins/xdg/util.py rename to src/context/icons/mixins/xdg/util.py diff --git a/src/context/mixins/__init__.py b/src/context/mixins/__init__.py new file mode 100644 index 0000000..ded9abc --- /dev/null +++ b/src/context/mixins/__init__.py @@ -0,0 +1,3 @@ +""" +Mixins module +""" diff --git a/src/controller/mixins/TreeViewUpdateMixin.py b/src/context/mixins/tree_view_update_mixin.py similarity index 100% rename from src/controller/mixins/TreeViewUpdateMixin.py rename to src/context/mixins/tree_view_update_mixin.py diff --git a/src/controller/View.py b/src/context/view.py similarity index 100% rename from src/controller/View.py rename to src/context/view.py diff --git a/src/controller/__init__.py b/src/controller/__init__.py deleted file mode 100644 index c3eeae6..0000000 --- a/src/controller/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -""" - Gtk Bound Signal Module -""" -from .mixins import * -from .View import View -from .IPCServerMixin import IPCServerMixin -from .Controller_Data import Controller_Data -from .Controller import Controller diff --git a/src/controller/mixins/__init__.py b/src/controller/mixins/__init__.py deleted file mode 100644 index 183df50..0000000 --- a/src/controller/mixins/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .TreeViewUpdateMixin import TreeViewUpdateMixin diff --git a/src/controller/IPCServerMixin.py b/src/ipc_server.py similarity index 54% rename from src/controller/IPCServerMixin.py rename to src/ipc_server.py index 7410fb8..8f2f9c9 100644 --- a/src/controller/IPCServerMixin.py +++ b/src/ipc_server.py @@ -1,5 +1,5 @@ # Python imports -import threading, socket, time +import os, threading, time from multiprocessing.connection import Listener, Client # Lib imports @@ -15,11 +15,32 @@ def threaded(fn): -class IPCServerMixin: +class IPCServer: + """ Create a listener so that other SolarFM instances send requests back to existing instance. """ + def __init__(self, conn_type="socket"): + self.is_ipc_alive = False + self._conn_type = conn_type + self.ipc_authkey = b'mirage2-ipc' + self.ipc_timeout = 15.0 + + if conn_type == "socket": + self.ipc_address = '/tmp/mirage2-ipc.sock' + else: + self.ipc_address = '127.0.0.1' + self.ipc_port = 4848 + @threaded def create_ipc_server(self): - listener = Listener((self.ipc_address, self.ipc_port), authkey=self.ipc_authkey) + if self._conn_type == "socket": + if os.path.exists(self.ipc_address): + return + + listener = Listener(address=self.ipc_address, family="AF_UNIX", authkey=self.ipc_authkey) + else: + listener = Listener((self.ipc_address, self.ipc_port), authkey=self.ipc_authkey) + + self.is_ipc_alive = True while True: conn = listener.accept() @@ -47,7 +68,7 @@ class IPCServerMixin: conn.close() break - # NOTE: Not perfect but insures we don't lockup the connection for too long. + # NOTE: Not perfect but insures we don't lock up the connection for too long. end_time = time.time() if (end - start) > self.ipc_timeout: conn.close() @@ -57,7 +78,12 @@ class IPCServerMixin: def send_ipc_message(self, message="Empty Data..."): try: - conn = Client((self.ipc_address, self.ipc_port), authkey=self.ipc_authkey) + if self._conn_type == "socket": + conn = Client(address=self.ipc_address, family="AF_UNIX", authkey=self.ipc_authkey) + else: + conn = Client((self.ipc_address, self.ipc_port), authkey=self.ipc_authkey) + + conn.send(message) conn.send('close connection') except Exception as e: diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 415301e..a8e5edd 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -1,6 +1,3 @@ """ Utils module """ - -from .Logger import Logger -from .Settings import Settings diff --git a/src/utils/Logger.py b/src/utils/logger.py similarity index 100% rename from src/utils/Logger.py rename to src/utils/logger.py diff --git a/src/utils/Settings.py b/src/utils/settings.py similarity index 99% rename from src/utils/Settings.py rename to src/utils/settings.py index 3af0b58..3804c10 100644 --- a/src/utils/Settings.py +++ b/src/utils/settings.py @@ -11,7 +11,7 @@ from gi.repository import Gdk # Application imports -from . import Logger +from .logger import Logger