aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@dailly.me>2025-07-07 08:31:38 +0200
committerSébastien Dailly <sebastien@dailly.me>2025-07-07 08:32:41 +0200
commitf2b300d9e01547628cd409f9666d457b5ea045ee (patch)
treedaf4e52ebd5bd8d2f4e708d4e467b88cdba3f724
parent69a6777bf3b849ec2ab0627b6ad66a57298f9d45 (diff)
Added error messageHEADmaster
-rw-r--r--configuration.py13
-rwxr-xr-xinterfaces/message.py19
-rwxr-xr-xmacropad.pyw26
3 files changed, 48 insertions, 10 deletions
diff --git a/configuration.py b/configuration.py
index fceef14..78cce27 100644
--- a/configuration.py
+++ b/configuration.py
@@ -1,7 +1,15 @@
+""" The configuration from the user.
+"""
+
from collections import OrderedDict
from os import path
import json
+from zope import component
+from interfaces.message import Error
class Mapping():
+ """Represent the configuration. This class is provided as an utility and is
+ used in the IDesktop interfaces.
+ """
def __init__(self, configuration):
self.init_mapping = configuration["mapping"]
@@ -10,7 +18,7 @@ class Mapping():
for key in tmp_mapping.keys() :
json_file = self.init_mapping[key]
if not path.exists(json_file):
- print("The file '%s' does not exists" % json_file)
+ component.handle(Error(f"The file '{json_file}' does not exists"))
continue
with open(json_file, "r") as file:
json_data = file.read()
@@ -27,6 +35,8 @@ class Mapping():
del self.mapping[key]
def get(self, key, default):
+ """ This function return the mapping associated with the given key.
+ """
return self.mapping.get(key, default)
def __getitem__(self, key):
@@ -44,4 +54,3 @@ class Mapping():
""" Implement the keys method from the dictionnary
"""
return self.mapping.keys()
-
diff --git a/interfaces/message.py b/interfaces/message.py
index 23ce2ec..bf05bef 100755
--- a/interfaces/message.py
+++ b/interfaces/message.py
@@ -1,14 +1,31 @@
+"""Messages sent to the user.
+"""
+
from zope import interface
from zope.interface import Attribute
class IMessage(interface.Interface):
+ """Interface for all the user messages.
+ """
content = Attribute("""The text message to log""")
+ level = Attribute("""Level of the message, 0 is high level and 10 is the lower""")
class ISocketMessage(interface.Interface):
+ """Message to sent to the endpoint."""
content = Attribute("""Content to send""")
@interface.implementer(IMessage)
-class Debug(object):
+class Debug():
+ """Send a message with a low level"""
+
+ def __init__(self, message):
+ self.content = message
+ self.level = 10
+
+@interface.implementer(IMessage)
+class Error():
+ """Send a message with a high level"""
def __init__(self, message):
self.content = message
+ self.level = 0
diff --git a/macropad.pyw b/macropad.pyw
index 6e4f922..a175931 100755
--- a/macropad.pyw
+++ b/macropad.pyw
@@ -15,7 +15,7 @@ from PIL import Image
from zope import component
import interfaces
from interfaces import endpoint
-from interfaces.message import IMessage, Debug
+from interfaces.message import IMessage, Debug, Error
import consumer
from configuration import Mapping
@@ -27,8 +27,6 @@ config_file = path.join(script_path, "config.ini")
config = configparser.ConfigParser(delimiters="=")
config.read(config_file)
-mapping = Mapping(config)
-component.provideUtility(mapping, interfaces.configuration.IConfiguration)
#
# Guess the platform and the load the corresponding event listener
@@ -64,6 +62,7 @@ handler.start()
class Icon():
+ """Icon displayed in the notification bar."""
def __init__(self, image):
menu=(
@@ -101,12 +100,15 @@ class Icon():
mapping.reset()
class Application():
+ """ The main application.
+ """
def __init__(self):
# Override the default function called when exception are reported
tk.Tk.report_callback_exception = self.report_callback_exception
self.window = tk.Tk()
self.text = Text(self.window, height=8)
+ self.text.tag_config("error", background="red", foreground="white")
## State of the #pplication
self.running = True
self.visible = False
@@ -137,15 +139,18 @@ class Application():
""" Launch the thread listening events from the desktop
"""
component.handle(Debug(platform))
+ listener = None
if platform == "win32":
import win32
listener = win32.Listener(mapping)
elif platform == 'linux':
import xlib
listener = xlib.Listener(mapping)
- component.handle(Debug("Starting xlib"))
- component.provideUtility(listener, interfaces.desktopEvent.IDesktop)
- listener.start()
+ if listener is not None:
+ component.provideUtility(listener, interfaces.desktopEvent.IDesktop)
+ listener.start()
+ else:
+ component.handle(Error("Unsupported system %s" % platform))
def report_callback_exception(self, exc, val, tb):
""" Handle exception reported inside the Tk application.
@@ -191,6 +196,9 @@ class Application():
self.text.insert("1.0", "\n")
self.text.insert("1.0", message.content)
self.text.delete("200.0", "end")
+ if message.level == 0:
+ self.text.tag_add("error", "1.0", "1.end")
+ self.icon.show_hide.set()
except Exception as e:
print(e)
@@ -212,6 +220,8 @@ if __name__ == '__main__':
# Start the main application, Initializing the message listener before
# listening desktop events
app = Application()
+ mapping = Mapping(config)
+ component.provideUtility(mapping, interfaces.configuration.IConfiguration)
app.connect_desktop()
# Initialize the main loop
@@ -222,4 +232,6 @@ if __name__ == '__main__':
app.running = False
app.window.destroy()
app.icon.quit()
- component.queryUtility(interfaces.desktopEvent.IDesktop).stop()
+ desktop = component.queryUtility(interfaces.desktopEvent.IDesktop)
+ if desktop is not None:
+ desktop.stop()