From 55515a08256262f49cf624f7f7d5ccdf8f79c3d0 Mon Sep 17 00:00:00 2001
From: itdominator <1itdominator@gmail.com>
Date: Sat, 27 Aug 2022 03:50:01 -0500
Subject: [PATCH] Reworked logic - in progress
---
1.0.2/__builtins__.py | 79 ++++++
1.0.2/__init__.py | 3 +
1.0.2/__main__.py | 42 +++
1.0.2/app.py | 20 ++
1.0.2/core/__init__.py | 3 +
1.0.2/core/columns/__init__.py | 3 +
1.0.2/core/columns/keys_column.py | 64 +++++
1.0.2/core/columns/left_column.py | 37 +++
1.0.2/core/columns/right_column.py | 31 ++
1.0.2/core/container.py | 37 +++
1.0.2/core/signals_mixin.py | 17 ++
1.0.2/core/widgets/__init__.py | 3 +
1.0.2/core/widgets/key.py | 34 +++
1.0.2/core/window.py | 36 +++
1.0.2/resources/Main_Window.glade | 436 +++++++++++++++++++++++++++++
1.0.2/resources/icon.png | Bin 0 -> 10224 bytes
1.0.2/resources/stylesheet.css | 8 +
1.0.2/utils/__init__.py | 3 +
1.0.2/utils/logger.py | 56 ++++
1.0.2/utils/pyautogui_control.py | 102 +++++++
20 files changed, 1014 insertions(+)
create mode 100644 1.0.2/__builtins__.py
create mode 100644 1.0.2/__init__.py
create mode 100644 1.0.2/__main__.py
create mode 100644 1.0.2/app.py
create mode 100644 1.0.2/core/__init__.py
create mode 100644 1.0.2/core/columns/__init__.py
create mode 100644 1.0.2/core/columns/keys_column.py
create mode 100644 1.0.2/core/columns/left_column.py
create mode 100644 1.0.2/core/columns/right_column.py
create mode 100644 1.0.2/core/container.py
create mode 100644 1.0.2/core/signals_mixin.py
create mode 100644 1.0.2/core/widgets/__init__.py
create mode 100644 1.0.2/core/widgets/key.py
create mode 100644 1.0.2/core/window.py
create mode 100644 1.0.2/resources/Main_Window.glade
create mode 100644 1.0.2/resources/icon.png
create mode 100644 1.0.2/resources/stylesheet.css
create mode 100644 1.0.2/utils/__init__.py
create mode 100644 1.0.2/utils/logger.py
create mode 100644 1.0.2/utils/pyautogui_control.py
diff --git a/1.0.2/__builtins__.py b/1.0.2/__builtins__.py
new file mode 100644
index 0000000..7d6fa47
--- /dev/null
+++ b/1.0.2/__builtins__.py
@@ -0,0 +1,79 @@
+# Python imports
+import builtins, threading
+
+# Lib imports
+
+# Application imports
+from utils.pyautogui_control import ControlMixin
+
+
+
+# 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()
+ 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()
+ return wrapper
+
+
+
+
+class EndpointRegistry():
+ def __init__(self):
+ self._endpoints = {}
+
+ def register(self, rule, **options):
+ def decorator(f):
+ self._endpoints[rule] = f
+ return f
+
+ return decorator
+
+ def get_endpoints(self):
+ return self._endpoints
+
+class Pyautogui_Controller(ControlMixin):
+ def __init__(self):
+ pass
+
+
+
+keys_json = {
+ "keys": {
+ "row1": {
+ "pKeys": ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
+ "sKeys": ['~', '@', '#', '$', '%', '&', '-', '_', '(', ')'],
+ },
+ "row2": {
+ "pKeys": ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
+ "sKeys": ['\\', '/', '|', ':', '{', '}', '[', ']', '<', '>'],
+ },
+ "row3": {
+ "pKeys": ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', "'"],
+ "sKeys": ['=', '+', '"', '*', '^', '`', ';', '!', '', ''],
+ },
+ "row4": {
+ "pKeys": ['z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '?'],
+ "sKeys": ['', '', '', '', '', '', '', '', '', '']
+ },
+ }
+}
+
+
+
+# NOTE: Just reminding myself we can add to builtins two different ways...
+# __builtins__.update({"event_system": Builtins()})
+builtins.app_name = "Mouse Keyboard"
+builtins.endpoint_registry = EndpointRegistry()
+builtins.typwriter = Pyautogui_Controller()
+builtins.threaded = threaded_wrapper
+builtins.daemon_threaded = daemon_threaded_wrapper
+builtins.keys_set = keys_json
+builtins.trace_debug = False
+builtins.debug = False
+builtins.app_settings = None
diff --git a/1.0.2/__init__.py b/1.0.2/__init__.py
new file mode 100644
index 0000000..cd8371b
--- /dev/null
+++ b/1.0.2/__init__.py
@@ -0,0 +1,3 @@
+"""
+ Base module
+"""
diff --git a/1.0.2/__main__.py b/1.0.2/__main__.py
new file mode 100644
index 0000000..87d25a0
--- /dev/null
+++ b/1.0.2/__main__.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python3
+
+
+# Python imports
+import argparse, faulthandler, traceback
+from setproctitle import setproctitle
+
+import tracemalloc
+tracemalloc.start()
+
+
+# Lib imports
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+
+# Application imports
+from app import Application
+
+
+if __name__ == "__main__":
+ """ Set process title, get arguments, and create GTK main thread. """
+
+ try:
+ # import web_pdb
+ # web_pdb.set_trace()
+
+ setproctitle('Mouse Keyboard')
+ faulthandler.enable() # For better debug info
+ parser = argparse.ArgumentParser()
+ # Add long and short arguments
+ 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...)
+ args, unknownargs = parser.parse_known_args()
+
+ Application(args, unknownargs)
+ Gtk.main()
+ except Exception as e:
+ traceback.print_exc()
+ quit()
diff --git a/1.0.2/app.py b/1.0.2/app.py
new file mode 100644
index 0000000..d80a172
--- /dev/null
+++ b/1.0.2/app.py
@@ -0,0 +1,20 @@
+# Python imports
+import inspect
+
+
+# Gtk imports
+
+
+# Application imports
+from __builtins__ import *
+from core.window import Window
+
+
+
+
+class Application(object):
+ def __init__(self, args, unknownargs):
+ try:
+ Window(args, unknownargs)
+ except Exception as e:
+ raise
diff --git a/1.0.2/core/__init__.py b/1.0.2/core/__init__.py
new file mode 100644
index 0000000..1509597
--- /dev/null
+++ b/1.0.2/core/__init__.py
@@ -0,0 +1,3 @@
+"""
+ Core module
+"""
diff --git a/1.0.2/core/columns/__init__.py b/1.0.2/core/columns/__init__.py
new file mode 100644
index 0000000..5acbeb8
--- /dev/null
+++ b/1.0.2/core/columns/__init__.py
@@ -0,0 +1,3 @@
+from .left_column import Left_Column
+from .keys_column import Keys_Column
+from .right_column import Right_Column
diff --git a/1.0.2/core/columns/keys_column.py b/1.0.2/core/columns/keys_column.py
new file mode 100644
index 0000000..904450b
--- /dev/null
+++ b/1.0.2/core/columns/keys_column.py
@@ -0,0 +1,64 @@
+# Python imports
+
+# Lib imports
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+
+# Application imports
+from ..widgets.key import Key
+
+
+
+class KeyboardRowMatchError(Exception):
+ pass
+
+
+class Keys_Column(Gtk.Box):
+ """docstring for Keys_Column."""
+
+ def __init__(self):
+ super(Keys_Column, self).__init__()
+
+ self.setup_styling()
+ self.setup_signals()
+ self.setup_key_buttons()
+
+ self.show_all()
+
+
+ def setup_styling(self):
+ self.set_orientation(1) # HORIZONTAL = 0, VERTICAL = 1
+ self.set_property("homogeneous", True)
+ self.set_hexpand(True)
+
+ def setup_signals(self):
+ pass
+
+ def setup_key_buttons(self):
+ keys = keys_set["keys"]
+ children = keys.keys()
+
+ for child in children:
+ pKeys = keys[child]["pKeys"]
+ sKeys = keys[child]["sKeys"]
+
+ row_box = self.add_row()
+ if len(pKeys) == len(sKeys):
+ for i in range(9):
+ pkey = pKeys[i]
+ sKey = sKeys[i]
+ row_box.add(Key(pkey, sKey))
+ else:
+ raise KeyboardRowMatchError("A row in keys_json has missmatched pKeys and sKeys lengths.")
+
+ row_box = self.add_row()
+ for key in ['Symbols', 'Space', 'Backspace']:
+ row_box.add(Key(key, key))
+
+ def add_row(self):
+ row_box = Gtk.Box()
+ row_box.set_property("homogeneous", True)
+ self.add(row_box)
+
+ return row_box
diff --git a/1.0.2/core/columns/left_column.py b/1.0.2/core/columns/left_column.py
new file mode 100644
index 0000000..a5d2540
--- /dev/null
+++ b/1.0.2/core/columns/left_column.py
@@ -0,0 +1,37 @@
+# Python imports
+
+# Lib imports
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+
+# Application imports
+
+
+
+
+class Left_Column(Gtk.Button):
+ """docstring for Left_Column."""
+
+ def __init__(self):
+ super(Left_Column, self).__init__()
+
+ self.setup_styling()
+ self.setup_signals()
+ self.show_all()
+
+
+ def setup_styling(self):
+ self.set_label("Caps")
+
+ def setup_signals(self):
+ self.connect("released", self._clicked)
+
+ def _clicked(self, widget = None):
+ key_columns = self.get_parent().get_children()[1]
+ limit = len(key_columns.get_children()) - 1
+
+ for i, row in enumerate(key_columns.get_children()):
+ if not i == limit:
+ for key in row:
+ key.emit("toggle-caps", ())
diff --git a/1.0.2/core/columns/right_column.py b/1.0.2/core/columns/right_column.py
new file mode 100644
index 0000000..eba6e2a
--- /dev/null
+++ b/1.0.2/core/columns/right_column.py
@@ -0,0 +1,31 @@
+# Python imports
+
+# Lib imports
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+
+# Application imports
+
+
+
+
+class Right_Column(Gtk.Button):
+ """docstring for Right_Column."""
+
+ def __init__(self):
+ super(Right_Column, self).__init__()
+
+ self.setup_styling()
+ self.setup_signals()
+ self.show_all()
+
+
+ def setup_styling(self):
+ self.set_label("Enter")
+
+ def setup_signals(self):
+ self.connect("released", self._clicked)
+
+ def _clicked(self, widget = None):
+ typwriter.enter()
diff --git a/1.0.2/core/container.py b/1.0.2/core/container.py
new file mode 100644
index 0000000..d8aaac0
--- /dev/null
+++ b/1.0.2/core/container.py
@@ -0,0 +1,37 @@
+# Python imports
+
+# Lib imports
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+
+# Application imports
+from .columns import Left_Column, Keys_Column, Right_Column
+from .signals_mixin import SignalsMixin
+
+
+
+class Container(SignalsMixin, Gtk.Box):
+ """docstring for Container."""
+
+ def __init__(self):
+ super(Container, self).__init__()
+
+ self.setup_custom_event_signals()
+ self.setup_styling()
+ self.add_columns()
+
+ self.show_all()
+
+
+ def setup_styling(self):
+ self.set_orientation(0) # HORIZONTAL = 0, VERTICAL = 1
+ self.set_vexpand(True)
+
+ def setup_signals(self):
+ pass
+
+ def add_columns(self):
+ self.add(Left_Column())
+ self.add(Keys_Column())
+ self.add(Right_Column())
diff --git a/1.0.2/core/signals_mixin.py b/1.0.2/core/signals_mixin.py
new file mode 100644
index 0000000..40e540a
--- /dev/null
+++ b/1.0.2/core/signals_mixin.py
@@ -0,0 +1,17 @@
+# Python imports
+
+# Lib imports
+from gi.repository import GObject
+
+
+# Application imports
+from .widgets.key import Key
+
+
+
+
+class SignalsMixin:
+ """docstring for SignalsMixin."""
+
+ def setup_custom_event_signals(self):
+ GObject.signal_new('toggle-caps', Key, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT, (GObject.TYPE_PYOBJECT,))
diff --git a/1.0.2/core/widgets/__init__.py b/1.0.2/core/widgets/__init__.py
new file mode 100644
index 0000000..1678cd7
--- /dev/null
+++ b/1.0.2/core/widgets/__init__.py
@@ -0,0 +1,3 @@
+"""
+ Widgets module
+"""
diff --git a/1.0.2/core/widgets/key.py b/1.0.2/core/widgets/key.py
new file mode 100644
index 0000000..5d06eff
--- /dev/null
+++ b/1.0.2/core/widgets/key.py
@@ -0,0 +1,34 @@
+# Python imports
+
+# Lib imports
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+
+# Application imports
+
+
+class Key(Gtk.Button):
+ def __init__(self, primary = "NULL", secondary = "NULL"):
+ super(Key, self).__init__()
+
+ self._primary_symbol = primary
+ self._secondary_symbol = secondary
+ self._is_upper = False
+
+ self.set_label(self._primary_symbol)
+
+ self.setup_signals()
+
+
+ def toggle_caps(self, widget = None, eve = None):
+ self._is_upper = not self._is_upper
+ self.set_label(self._primary_symbol.upper()) if self._is_upper else self.set_label(self._primary_symbol.lower())
+
+ def setup_signals(self):
+ self.connect("released", self._clicked)
+ self.connect("toggle-caps", self.toggle_caps)
+
+ def _clicked(self, widget = None):
+ key = self.get_label().strip()
+ typwriter.type(key)
diff --git a/1.0.2/core/window.py b/1.0.2/core/window.py
new file mode 100644
index 0000000..2b15909
--- /dev/null
+++ b/1.0.2/core/window.py
@@ -0,0 +1,36 @@
+# Python imports
+
+# Lib imports
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+
+# Application imports
+from .container import Container
+
+
+
+class Window(Gtk.ApplicationWindow):
+ """docstring for Window."""
+
+ def __init__(self, args, unknownargs):
+ super(Window, self).__init__()
+
+ self.setup_styling()
+ self.setup_signals()
+ self.add(Container())
+
+ self.show_all()
+
+
+ def setup_styling(self):
+ # self.set_icon_from_file("/usr/share/bulkr/bulkr.png")
+ self.set_title(app_name)
+ self.set_default_size(800, 200)
+ self.set_type_hint(3) # 3 = TOOLBAR
+ self.set_gravity(8) # 5 = CENTER, 8 = SOUTH
+ self.set_position(1) # 1 = CENTER, 4 = CENTER_ALWAYS
+ self.stick()
+
+ def setup_signals(self):
+ self.connect("delete-event", Gtk.main_quit)
diff --git a/1.0.2/resources/Main_Window.glade b/1.0.2/resources/Main_Window.glade
new file mode 100644
index 0000000..7931fad
--- /dev/null
+++ b/1.0.2/resources/Main_Window.glade
@@ -0,0 +1,436 @@
+
+
+
+
+
+
+
diff --git a/1.0.2/resources/icon.png b/1.0.2/resources/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..bcf986ea8ed78737ede3b3732eeb173501a10b7a
GIT binary patch
literal 10224
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 logging.Logger:
+ log = logging.getLogger(loggerName)
+ log.setLevel(self.global_lvl)
+
+ # Set our log output styles
+ fFormatter = logging.Formatter('[%(asctime)s] %(pathname)s:%(lineno)d %(levelname)s - %(message)s', '%m-%d %H:%M:%S')
+ cFormatter = logging.Formatter('%(pathname)s:%(lineno)d] %(levelname)s - %(message)s')
+
+ ch = logging.StreamHandler()
+ ch.setLevel(level=self.ch_log_lvl)
+ ch.setFormatter(cFormatter)
+ log.addHandler(ch)
+
+ if createFile:
+ folder = self._CONFIG_PATH
+ file = f"{folder}/application.log"
+
+ if not os.path.exists(folder):
+ os.mkdir(folder)
+
+ fh = logging.FileHandler(file)
+ fh.setLevel(level=self.fh_log_lvl)
+ fh.setFormatter(fFormatter)
+ log.addHandler(fh)
+
+ return log
diff --git a/1.0.2/utils/pyautogui_control.py b/1.0.2/utils/pyautogui_control.py
new file mode 100644
index 0000000..f3a58c3
--- /dev/null
+++ b/1.0.2/utils/pyautogui_control.py
@@ -0,0 +1,102 @@
+# Python imports
+import pyautogui
+
+# Gtk imports
+
+# Application imports
+
+
+# Let piautogui make updates as quick as it can...
+pyautogui.FAILSAFE = False # If we hit corner, that's ok
+pyautogui.MINIMUM_DURATION = 0
+pyautogui.PAUSE = 0
+
+
+class ControlMixin:
+
+ def type(self, key):
+ pyautogui.typewrite(key)
+
+
+ def enter(self, widget = None, data = None):
+ pyautogui.press("enter")
+
+
+ # def typeString(self, widget = None, data = None):
+ # text = self.autoTypeField.get_text()
+ # for char in text:
+ # self.do_insert(char)
+ #
+ # def insert(self, widget = None, data = None, key = None):
+ # if not key:
+ # key = widget.get_label().strip()
+ #
+ # if self.is_keypress_type(key):
+ # return
+ #
+ # if self.isCapsLockOn:
+ # key = key.upper()
+ #
+ # self.do_insert(key)
+ #
+ #
+ # def do_insert(self, key):
+ # if self.isCtrlOn or self.isShiftOn or self.isAltOn:
+ # self.set_hotkeys()
+ #
+ # pyautogui.typewrite(key)
+ #
+ # if self.isCtrlOn or self.isShiftOn or self.isAltOn:
+ # self.unset_hotkeys()
+ #
+ #
+ # def is_keypress_type(self, key):
+ # if key in ["Esc", "Tab", "Space", "Del", "Up", "Down", "Left", "Right", "PrtSc"]:
+ # pyautogui.press(key.lower())
+ # return True
+ #
+ # for i in range(1, 13):
+ # fkey = 'F' + str(i)
+ # if key == fkey:
+ # pyautogui.press(key.lower())
+ # return True
+ #
+ # return False
+ #
+ #
+ # def set_hotkeys(self):
+ # if self.isCtrlOn:
+ # pyautogui.keyDown('ctrl')
+ # if self.isShiftOn:
+ # pyautogui.keyDown('shiftleft')
+ # pyautogui.keyDown('shiftright')
+ # if self.isAltOn:
+ # pyautogui.keyDown('alt')
+ #
+ #
+ # def unset_hotkeys(self):
+ # pyautogui.keyUp('ctrl')
+ # pyautogui.keyUp('shiftleft')
+ # pyautogui.keyUp('shiftright')
+ # pyautogui.keyUp('alt')
+ #
+ #
+ # def toggleCaps(self, widget, data=None):
+ # self.isCapsLockOn = False if self.isCapsLockOn else True
+ #
+ # def tgglCtrl(self, widget, data=None):
+ # self.isCtrlOn = False if self.isCtrlOn else True
+ #
+ # def tgglShift(self, widget, data=None):
+ # self.isShiftOn = False if self.isShiftOn else True
+ #
+ # def tgglAlt(self, widget, data=None):
+ # self.isAltOn = False if self.isAltOn else True
+ #
+ #
+ # def enter(self, widget, data=None):
+ # pyautogui.press("enter")
+ #
+ #
+ # def backspace(self, widget, data=None):
+ # pyautogui.press("backspace")