Skip to content

Commit 12c8ea3

Browse files
committed
Functions wrapped in @in_separate_thread now return the created Thread; The logging system has been redesigned, the global logger is now configured; EVENT_ROUTING_MAP is filled automatically; Requirements updated;
1 parent b622025 commit 12c8ea3

File tree

13 files changed

+133
-159
lines changed

13 files changed

+133
-159
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ or
4646
pip install streamdeck_sdk
4747
```
4848

49+
## Features
50+
51+
* Easy use. You can quickly create your own plugin without having to understand how websockets and other complicated
52+
things work.
53+
* Fully typed, using [pydantic](https://github.com/pydantic/pydantic).
54+
* Includes image to base64 converters for easy installation of icons on keys.
55+
* Includes a decorator for functions and methods to run on a separate thread.
56+
* Exception logging and easy logging configuration.
57+
4958
## Examples
5059

5160
[LoremFlickr](https://github.com/gri-gus/loremflickr-streamdeck-plugin) - Plugin for installing images from LoremFlickr

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import setuptools
22

3-
VERSION = "0.2.1"
3+
VERSION = "0.3.0"
44
PACKAGE_DIR = "src"
55
REQUIREMENTS_FILE = PACKAGE_DIR + "/requirements.txt"
66
README = "README.md"

src/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
decohints>=1.0.7
2-
pydantic>=1.10.5
1+
decohints>=1.0.9
2+
pydantic>=1.10.7
33
typing_extensions>=4.5.0
44
websocket-client>=1.5.1

src/streamdeck_sdk/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
from . import events_received_objs
2-
from . import events_sent_objs
31
from . import mixins
4-
from . import registration_objs
2+
from .sd_objs import events_received_objs, events_sent_objs, registration_objs
53
from .logger import logger, log_errors
64
from .sdk import StreamDeck, Action
75
from .utils import image_file_to_base64, image_bytes_to_base64, in_separate_thread

src/streamdeck_sdk/event_routings.py

Lines changed: 53 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,59 @@
1-
from dataclasses import dataclass
2-
from typing import Type, Dict
1+
from enum import Enum
2+
from typing import Type, Dict, get_type_hints
33

4-
import pydantic
4+
from pydantic import BaseModel
55

6-
from . import events_received_objs
6+
from . import mixins
77

88

9-
@dataclass
10-
class EventRoutingObj:
11-
handler_name: str
12-
obj: Type[pydantic.BaseModel]
13-
9+
class EventRoutingObjTypes(Enum):
10+
ACTION = "ACTION"
11+
PLUGIN = "PLUGIN"
1412

15-
ACTION_EVENT_ROUTING_MAP: Dict[str, EventRoutingObj] = {
16-
"didReceiveSettings": EventRoutingObj(
17-
obj=events_received_objs.DidReceiveSettings,
18-
handler_name="on_did_receive_settings",
19-
),
20-
"keyDown": EventRoutingObj(
21-
obj=events_received_objs.KeyDown,
22-
handler_name="on_key_down",
23-
),
24-
"keyUp": EventRoutingObj(
25-
obj=events_received_objs.KeyUp,
26-
handler_name="on_key_up",
27-
),
28-
"touchTap": EventRoutingObj(
29-
obj=events_received_objs.TouchTap,
30-
handler_name="on_touch_tap",
31-
),
32-
"dialDown": EventRoutingObj(
33-
obj=events_received_objs.DialDown,
34-
handler_name="on_dial_down",
35-
),
36-
"dialUp": EventRoutingObj(
37-
obj=events_received_objs.DialUp,
38-
handler_name="on_dial_up",
39-
),
40-
"dialPress": EventRoutingObj(
41-
obj=events_received_objs.DialPress,
42-
handler_name="on_dial_press",
43-
),
44-
"dialRotate": EventRoutingObj(
45-
obj=events_received_objs.DialRotate,
46-
handler_name="on_dial_rotate",
47-
),
48-
"willAppear": EventRoutingObj(
49-
obj=events_received_objs.WillAppear,
50-
handler_name="on_will_appear",
51-
),
52-
"willDisappear": EventRoutingObj(
53-
obj=events_received_objs.WillDisappear,
54-
handler_name="on_will_disappear",
55-
),
56-
"titleParametersDidChange": EventRoutingObj(
57-
obj=events_received_objs.TitleParametersDidChange,
58-
handler_name="on_title_parameters_did_change",
59-
),
60-
"propertyInspectorDidAppear": EventRoutingObj(
61-
obj=events_received_objs.PropertyInspectorDidAppear,
62-
handler_name="on_property_inspector_did_appear",
63-
),
64-
"propertyInspectorDidDisappear": EventRoutingObj(
65-
obj=events_received_objs.PropertyInspectorDidDisappear,
66-
handler_name="on_property_inspector_did_disappear",
67-
),
68-
"sendToPlugin": EventRoutingObj(
69-
obj=events_received_objs.SendToPlugin,
70-
handler_name="on_send_to_plugin",
71-
),
72-
"sendToPropertyInspector": EventRoutingObj(
73-
obj=events_received_objs.SendToPropertyInspector,
74-
handler_name="on_send_to_property_inspector",
75-
),
76-
}
7713

78-
PLUGIN_EVENT_ROUTING_MAP: Dict[str, EventRoutingObj] = {
79-
"didReceiveGlobalSettings": EventRoutingObj(
80-
obj=events_received_objs.DidReceiveGlobalSettings,
81-
handler_name="on_did_receive_global_settings",
82-
),
83-
"deviceDidConnect": EventRoutingObj(
84-
obj=events_received_objs.DeviceDidConnect,
85-
handler_name="on_device_did_connect",
86-
),
87-
"deviceDidDisconnect": EventRoutingObj(
88-
obj=events_received_objs.DeviceDidDisconnect,
89-
handler_name="on_device_did_disconnect",
90-
),
91-
"applicationDidLaunch": EventRoutingObj(
92-
obj=events_received_objs.ApplicationDidLaunch,
93-
handler_name="on_application_did_launch",
94-
),
95-
"applicationDidTerminate": EventRoutingObj(
96-
obj=events_received_objs.ApplicationDidTerminate,
97-
handler_name="on_application_did_terminate",
98-
),
99-
"systemDidWakeUp": EventRoutingObj(
100-
obj=events_received_objs.SystemDidWakeUp,
101-
handler_name="on_system_did_wake_up",
102-
),
103-
}
104-
105-
EVENT_ROUTING_MAP: Dict[str, EventRoutingObj] = {
106-
**ACTION_EVENT_ROUTING_MAP,
107-
**PLUGIN_EVENT_ROUTING_MAP,
108-
}
14+
class EventRoutingObj(BaseModel):
15+
handler_name: str
16+
obj_type: Type[BaseModel]
17+
type: EventRoutingObjTypes
18+
19+
20+
EVENT_ROUTING_MAP: Dict[str, EventRoutingObj] = {}
21+
22+
23+
def fill_routing_map(
24+
routing_map: Dict[str, EventRoutingObj],
25+
event_handler_mixin: mixins.BaseEventHandlerMixin,
26+
event_routing_obj_type: EventRoutingObjTypes,
27+
) -> None:
28+
event_handler_mixin_dict = dict(event_handler_mixin.__dict__)
29+
for attr, value in event_handler_mixin_dict.items():
30+
attr: str
31+
if not attr.startswith("on_"):
32+
continue
33+
assert callable(value)
34+
35+
handler_type_hints = get_type_hints(value)
36+
obj_type = handler_type_hints["obj"]
37+
obj = obj_type.construct()
38+
event_name = obj.event
39+
handler_name = value.__name__
40+
routing_map[event_name] = EventRoutingObj(
41+
handler_name=handler_name,
42+
obj_type=obj_type,
43+
type=event_routing_obj_type,
44+
)
45+
46+
47+
def fill_event_routing_map() -> None:
48+
for event_handler_mixin, event_routing_obj_type in (
49+
(mixins.ActionEventHandlersMixin, EventRoutingObjTypes.ACTION),
50+
(mixins.PluginEventHandlersMixin, EventRoutingObjTypes.PLUGIN),
51+
):
52+
fill_routing_map(
53+
routing_map=EVENT_ROUTING_MAP,
54+
event_handler_mixin=event_handler_mixin,
55+
event_routing_obj_type=event_routing_obj_type,
56+
)
57+
58+
59+
fill_event_routing_map()

src/streamdeck_sdk/logger.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55

66
from decohints import decohints
77

8-
logger: logging.Logger = logging.getLogger('default')
8+
_root_logger: logging.Logger = logging.getLogger()
9+
_log_errors_decorator_logger = logging.getLogger("log_errors_decorator")
10+
logger = logging.getLogger("streamdeck_plugin")
911

1012

11-
def init_logger(
13+
def init_root_logger(
1214
log_file: Path,
1315
log_level: int = logging.DEBUG,
1416
log_max_bytes: int = 3 * 1024 * 1024,
1517
log_backup_count: int = 2,
1618
) -> None:
17-
logger.setLevel(log_level)
19+
_root_logger.setLevel(log_level)
1820
logs_dir: Path = log_file.parent
1921
logs_dir.mkdir(parents=True, exist_ok=True)
2022
rfh = RotatingFileHandler(
@@ -30,7 +32,7 @@ def init_logger(
3032
"%(asctime)s - [%(levelname)s] - %(name)s - (%(filename)s).%(funcName)s(%(lineno)d): %(message)s"
3133
)
3234
rfh.setFormatter(formatter)
33-
logger.addHandler(rfh)
35+
_root_logger.addHandler(rfh)
3436

3537

3638
@decohints
@@ -44,8 +46,12 @@ def wrapper(*args, **kwargs):
4446
try:
4547
result = func(*args, **kwargs)
4648
except BaseException as err:
47-
logger.error(str(err), exc_info=True)
49+
_log_errors_decorator_logger.error(str(err), exc_info=True)
4850
return
4951
return result
5052

5153
return wrapper
54+
55+
56+
def rename_plugin_logger(name: str):
57+
logger.name = name

src/streamdeck_sdk/mixins.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
import websocket
66
from websocket import ABNF
77

8-
from . import events_received_objs
9-
from . import events_sent_objs
8+
from .sd_objs import events_received_objs, events_sent_objs
109
from .logger import log_errors
1110

1211

@@ -26,7 +25,11 @@ def send(
2625
self.ws.send(data, opcode)
2726

2827

29-
class PluginEventsSentMixin(SendMixin):
28+
class BaseEventSendMixin(SendMixin):
29+
pass
30+
31+
32+
class PluginEventsSendMixin(BaseEventSendMixin):
3033
plugin_uuid: str
3134

3235
def set_global_settings(self, payload: dict) -> None:
@@ -73,7 +76,7 @@ def switch_to_profile(
7376
self.send(message)
7477

7578

76-
class ActionEventsSentMixin(SendMixin):
79+
class ActionEventsSendMixin(BaseEventSendMixin):
7780
def set_settings(
7881
self,
7982
context: str,
@@ -185,7 +188,11 @@ def send_to_property_inspector(
185188
self.send(message)
186189

187190

188-
class ActionEventHandlersMixin:
191+
class BaseEventHandlerMixin:
192+
pass
193+
194+
195+
class ActionEventHandlersMixin(BaseEventHandlerMixin):
189196
def on_did_receive_settings(self, obj: events_received_objs.DidReceiveSettings) -> None:
190197
pass
191198

@@ -232,7 +239,7 @@ def on_send_to_property_inspector(self, obj: events_received_objs.SendToProperty
232239
pass
233240

234241

235-
class PluginEventHandlersMixin:
242+
class PluginEventHandlersMixin(BaseEventHandlerMixin):
236243
def on_did_receive_global_settings(self, obj: events_received_objs.DidReceiveGlobalSettings) -> None:
237244
pass
238245

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import events_received_objs
2+
from . import events_sent_objs
3+
from . import registration_objs

0 commit comments

Comments
 (0)