camera-ui-common 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. camera_ui_common-1.0.0/LICENSE.txt +22 -0
  2. camera_ui_common-1.0.0/PKG-INFO +196 -0
  3. camera_ui_common-1.0.0/README.md +169 -0
  4. camera_ui_common-1.0.0/camera_ui_common/__init__.py +28 -0
  5. camera_ui_common-1.0.0/camera_ui_common/camera_utils/__init__.py +5 -0
  6. camera_ui_common-1.0.0/camera_ui_common/camera_utils/utils.py +75 -0
  7. camera_ui_common-1.0.0/camera_ui_common/common_utils/__init__.py +22 -0
  8. camera_ui_common-1.0.0/camera_ui_common/common_utils/object_path.py +211 -0
  9. camera_ui_common-1.0.0/camera_ui_common/common_utils/promise.py +41 -0
  10. camera_ui_common-1.0.0/camera_ui_common/common_utils/reactive.py +47 -0
  11. camera_ui_common-1.0.0/camera_ui_common/common_utils/signal_handler.py +100 -0
  12. camera_ui_common-1.0.0/camera_ui_common/common_utils/subscribed.py +34 -0
  13. camera_ui_common-1.0.0/camera_ui_common/common_utils/task.py +45 -0
  14. camera_ui_common-1.0.0/camera_ui_common/common_utils/thread.py +18 -0
  15. camera_ui_common-1.0.0/camera_ui_common/common_utils/utils.py +99 -0
  16. camera_ui_common-1.0.0/camera_ui_common/logger_service/__init__.py +0 -0
  17. camera_ui_common-1.0.0/camera_ui_common/logger_service/ansicolor.py +62 -0
  18. camera_ui_common-1.0.0/camera_ui_common/logger_service/logger.py +316 -0
  19. camera_ui_common-1.0.0/camera_ui_common/py.typed +0 -0
  20. camera_ui_common-1.0.0/camera_ui_common.egg-info/PKG-INFO +196 -0
  21. camera_ui_common-1.0.0/camera_ui_common.egg-info/SOURCES.txt +24 -0
  22. camera_ui_common-1.0.0/camera_ui_common.egg-info/dependency_links.txt +1 -0
  23. camera_ui_common-1.0.0/camera_ui_common.egg-info/requires.txt +3 -0
  24. camera_ui_common-1.0.0/camera_ui_common.egg-info/top_level.txt +1 -0
  25. camera_ui_common-1.0.0/pyproject.toml +38 -0
  26. camera_ui_common-1.0.0/setup.cfg +4 -0
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020-2024 seydx <dev@seydx.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: camera-ui-common
3
+ Version: 1.0.0
4
+ Summary: camera.ui python utilities
5
+ Author-email: seydx <dev@seydx.com>
6
+ Maintainer-email: seydx <dev@seydx.com>
7
+ Project-URL: Homepage, https://github.com/seydx/camera.ui
8
+ Project-URL: Documentation, https://github.com/seydx/camera.ui
9
+ Project-URL: Repository, https://github.com/seydx/camera.ui
10
+ Project-URL: Bug Tracker, https://github.com/seydx/camera.ui/issues
11
+ Project-URL: Changelog, https://github.com/seydx/camera.ui/blob/master/CHANGELOG.md
12
+ Keywords: camera.ui,python,utilities
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE.txt
23
+ Requires-Dist: typing_extensions>=4.12.2
24
+ Requires-Dist: reactivex>=4.0.4
25
+ Requires-Dist: camera-ui-sdk>=1.0.0
26
+ Dynamic: license-file
27
+
28
+ # camera-ui-python-common
29
+
30
+ Shared utilities for Python-based camera.ui plugins including logging, reactive programming, and common helpers.
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install camera-ui-python-common
36
+ ```
37
+
38
+ ## Core Features
39
+
40
+ - **Logging** - Colored, structured logging
41
+ - **Reactive Programming** - Observable properties
42
+ - **Signal Handling** - Graceful shutdown
43
+ - **Object Utilities** - Deep object manipulation
44
+ - **Async Helpers** - Task and thread management
45
+
46
+ ## Logging
47
+
48
+ ```python
49
+ from camera_ui_python_common import LoggerService
50
+
51
+ logger = LoggerService({
52
+ "prefix": "MyPlugin",
53
+ "debug_enabled": True
54
+ })
55
+
56
+ logger.log("Plugin started")
57
+ logger.error("Something went wrong")
58
+ logger.success("Operation completed")
59
+ logger.debug("Debug information")
60
+ ```
61
+
62
+ ## Reactive Programming
63
+
64
+ ```python
65
+ from camera_ui_python_common import ReactiveProperty
66
+
67
+ # Create reactive state
68
+ state = ReactiveProperty({"count": 0, "active": True})
69
+
70
+ # Subscribe to changes
71
+ state.observable.subscribe(lambda value: print(f"State: {value}"))
72
+
73
+ # Update state
74
+ state.next({"count": 1, "active": True})
75
+ ```
76
+
77
+ ## Signal Handling
78
+
79
+ ```python
80
+ from camera_ui_python_common import SignalHandler
81
+
82
+ async def cleanup():
83
+ print("Cleaning up...")
84
+
85
+ signal_handler = SignalHandler({
86
+ "display_name": "MyPlugin",
87
+ "logger": logger,
88
+ "close_function": cleanup
89
+ })
90
+
91
+ signal_handler.setup_handlers()
92
+ ```
93
+
94
+ ## Object Path Operations
95
+
96
+ ```python
97
+ from camera_ui_python_common import ObjectPath
98
+
99
+ data = {"camera": {"settings": {"resolution": "1080p"}}}
100
+
101
+ # Get nested values
102
+ resolution = ObjectPath.get(data, "camera.settings.resolution")
103
+
104
+ # Set nested values
105
+ ObjectPath.set(data, "camera.settings.bitrate", 5000)
106
+
107
+ # Check if path exists
108
+ has_setting = ObjectPath.has(data, "camera.settings.fps")
109
+ ```
110
+
111
+ ## Async Utilities
112
+
113
+ ### Task Management
114
+ ```python
115
+ from camera_ui_python_common import TaskSet
116
+
117
+ tasks = TaskSet("MyTasks")
118
+ tasks.add(my_async_function())
119
+ await tasks
120
+ ```
121
+
122
+ ### Thread Operations
123
+ ```python
124
+ from camera_ui_python_common import to_thread
125
+
126
+ # Run blocking operation in thread
127
+ result = await to_thread(blocking_function)
128
+ ```
129
+
130
+ ### Sync/Async Bridge
131
+ ```python
132
+ from camera_ui_python_common import make_sync
133
+
134
+ # Convert async function to sync
135
+ sync_version = make_sync(async_function)
136
+ result = sync_version(args)
137
+ ```
138
+
139
+ ## RTSP Utilities
140
+
141
+ ```python
142
+ from camera_ui_python_common import build_target_url
143
+
144
+ url = build_target_url("rtsp://camera.local/stream", {
145
+ "video": True,
146
+ "audio": ["pcma", "opus"],
147
+ "timeout": 30
148
+ })
149
+ ```
150
+
151
+ ## Complete Example
152
+
153
+ ```python
154
+ import asyncio
155
+ from camera_ui_python_common import LoggerService, ReactiveProperty, SignalHandler
156
+
157
+ class MyPlugin:
158
+ def __init__(self):
159
+ self.logger = LoggerService({"prefix": "MyPlugin"})
160
+ self.state = ReactiveProperty({"active": False})
161
+
162
+ self.signal_handler = SignalHandler({
163
+ "display_name": "MyPlugin",
164
+ "logger": self.logger,
165
+ "close_function": self.cleanup
166
+ })
167
+
168
+ async def start(self):
169
+ self.logger.log("Starting plugin...")
170
+ self.signal_handler.setup_handlers()
171
+
172
+ # Update state
173
+ self.state.next({"active": True})
174
+
175
+ # Keep running
176
+ await asyncio.Future()
177
+
178
+ async def cleanup(self):
179
+ self.logger.log("Stopping plugin...")
180
+
181
+ # Usage
182
+ plugin = MyPlugin()
183
+ asyncio.run(plugin.start())
184
+ ```
185
+
186
+ ## Contributing
187
+
188
+ Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
189
+
190
+ ## License
191
+
192
+ MIT
193
+
194
+ ---
195
+
196
+ *Part of the camera.ui ecosystem - A comprehensive camera management solution.*
@@ -0,0 +1,169 @@
1
+ # camera-ui-python-common
2
+
3
+ Shared utilities for Python-based camera.ui plugins including logging, reactive programming, and common helpers.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install camera-ui-python-common
9
+ ```
10
+
11
+ ## Core Features
12
+
13
+ - **Logging** - Colored, structured logging
14
+ - **Reactive Programming** - Observable properties
15
+ - **Signal Handling** - Graceful shutdown
16
+ - **Object Utilities** - Deep object manipulation
17
+ - **Async Helpers** - Task and thread management
18
+
19
+ ## Logging
20
+
21
+ ```python
22
+ from camera_ui_python_common import LoggerService
23
+
24
+ logger = LoggerService({
25
+ "prefix": "MyPlugin",
26
+ "debug_enabled": True
27
+ })
28
+
29
+ logger.log("Plugin started")
30
+ logger.error("Something went wrong")
31
+ logger.success("Operation completed")
32
+ logger.debug("Debug information")
33
+ ```
34
+
35
+ ## Reactive Programming
36
+
37
+ ```python
38
+ from camera_ui_python_common import ReactiveProperty
39
+
40
+ # Create reactive state
41
+ state = ReactiveProperty({"count": 0, "active": True})
42
+
43
+ # Subscribe to changes
44
+ state.observable.subscribe(lambda value: print(f"State: {value}"))
45
+
46
+ # Update state
47
+ state.next({"count": 1, "active": True})
48
+ ```
49
+
50
+ ## Signal Handling
51
+
52
+ ```python
53
+ from camera_ui_python_common import SignalHandler
54
+
55
+ async def cleanup():
56
+ print("Cleaning up...")
57
+
58
+ signal_handler = SignalHandler({
59
+ "display_name": "MyPlugin",
60
+ "logger": logger,
61
+ "close_function": cleanup
62
+ })
63
+
64
+ signal_handler.setup_handlers()
65
+ ```
66
+
67
+ ## Object Path Operations
68
+
69
+ ```python
70
+ from camera_ui_python_common import ObjectPath
71
+
72
+ data = {"camera": {"settings": {"resolution": "1080p"}}}
73
+
74
+ # Get nested values
75
+ resolution = ObjectPath.get(data, "camera.settings.resolution")
76
+
77
+ # Set nested values
78
+ ObjectPath.set(data, "camera.settings.bitrate", 5000)
79
+
80
+ # Check if path exists
81
+ has_setting = ObjectPath.has(data, "camera.settings.fps")
82
+ ```
83
+
84
+ ## Async Utilities
85
+
86
+ ### Task Management
87
+ ```python
88
+ from camera_ui_python_common import TaskSet
89
+
90
+ tasks = TaskSet("MyTasks")
91
+ tasks.add(my_async_function())
92
+ await tasks
93
+ ```
94
+
95
+ ### Thread Operations
96
+ ```python
97
+ from camera_ui_python_common import to_thread
98
+
99
+ # Run blocking operation in thread
100
+ result = await to_thread(blocking_function)
101
+ ```
102
+
103
+ ### Sync/Async Bridge
104
+ ```python
105
+ from camera_ui_python_common import make_sync
106
+
107
+ # Convert async function to sync
108
+ sync_version = make_sync(async_function)
109
+ result = sync_version(args)
110
+ ```
111
+
112
+ ## RTSP Utilities
113
+
114
+ ```python
115
+ from camera_ui_python_common import build_target_url
116
+
117
+ url = build_target_url("rtsp://camera.local/stream", {
118
+ "video": True,
119
+ "audio": ["pcma", "opus"],
120
+ "timeout": 30
121
+ })
122
+ ```
123
+
124
+ ## Complete Example
125
+
126
+ ```python
127
+ import asyncio
128
+ from camera_ui_python_common import LoggerService, ReactiveProperty, SignalHandler
129
+
130
+ class MyPlugin:
131
+ def __init__(self):
132
+ self.logger = LoggerService({"prefix": "MyPlugin"})
133
+ self.state = ReactiveProperty({"active": False})
134
+
135
+ self.signal_handler = SignalHandler({
136
+ "display_name": "MyPlugin",
137
+ "logger": self.logger,
138
+ "close_function": self.cleanup
139
+ })
140
+
141
+ async def start(self):
142
+ self.logger.log("Starting plugin...")
143
+ self.signal_handler.setup_handlers()
144
+
145
+ # Update state
146
+ self.state.next({"active": True})
147
+
148
+ # Keep running
149
+ await asyncio.Future()
150
+
151
+ async def cleanup(self):
152
+ self.logger.log("Stopping plugin...")
153
+
154
+ # Usage
155
+ plugin = MyPlugin()
156
+ asyncio.run(plugin.start())
157
+ ```
158
+
159
+ ## Contributing
160
+
161
+ Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
162
+
163
+ ## License
164
+
165
+ MIT
166
+
167
+ ---
168
+
169
+ *Part of the camera.ui ecosystem - A comprehensive camera management solution.*
@@ -0,0 +1,28 @@
1
+ from .common_utils.object_path import ObjectPath, Path
2
+ from .common_utils.promise import Deferred
3
+ from .common_utils.reactive import ReactiveProperty
4
+ from .common_utils.signal_handler import SignalHandler, SignalHandlerOptions
5
+ from .common_utils.subscribed import Subscribed
6
+ from .common_utils.task import TaskSet
7
+ from .common_utils.thread import to_thread
8
+ from .common_utils.utils import make_sync, merge, merge_with
9
+ from .logger_service.ansicolor import Ansicolor
10
+ from .logger_service.logger import LoggerOptions, LoggerService
11
+
12
+ __all__ = [
13
+ "Deferred",
14
+ "ObjectPath",
15
+ "Path",
16
+ "SignalHandler",
17
+ "SignalHandlerOptions",
18
+ "Subscribed",
19
+ "TaskSet",
20
+ "to_thread",
21
+ "make_sync",
22
+ "merge",
23
+ "merge_with",
24
+ "ReactiveProperty",
25
+ "Ansicolor",
26
+ "LoggerOptions",
27
+ "LoggerService",
28
+ ]
@@ -0,0 +1,5 @@
1
+ """Camera utilities module."""
2
+
3
+ from .utils import build_target_url
4
+
5
+ __all__ = ["build_target_url"]
@@ -0,0 +1,75 @@
1
+ """Camera utility functions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from urllib.parse import urlparse
6
+
7
+ from camera_ui_python_types import RTSPUrlOptions
8
+
9
+
10
+ def build_target_url(rtsp_url: str, options: RTSPUrlOptions | None = None) -> str:
11
+ """
12
+ Build a target URL with streaming options.
13
+
14
+ Args:
15
+ rtsp_url: The base RTSP URL
16
+ options: Optional streaming options
17
+
18
+ Returns:
19
+ The constructed URL with query parameters
20
+ """
21
+ if options is None:
22
+ options = {}
23
+
24
+ parsed = urlparse(rtsp_url)
25
+ base_url = f"{parsed.scheme}://{parsed.netloc}{parsed.path}"
26
+
27
+ # Extract options with defaults
28
+ video = options.get("video", True)
29
+ audio = options.get("audio", True)
30
+ audio_single_track = options.get("audioSingleTrack", True)
31
+ backchannel = options.get("backchannel", False)
32
+ timeout = options.get("timeout", 15)
33
+ gop = options.get("gop", True)
34
+ prebuffer = options.get("prebuffer", False)
35
+
36
+ # Validate timeout (5-30 seconds)
37
+ validated_timeout = min(max(5, timeout), 30)
38
+
39
+ params: list[str] = []
40
+
41
+ # Video parameter
42
+ if video:
43
+ params.append("video")
44
+
45
+ # Audio parameter
46
+ if audio:
47
+ if isinstance(audio, bool):
48
+ params.append("audio")
49
+ elif isinstance(audio, list):
50
+ if audio_single_track:
51
+ # Single track with multiple codecs
52
+ params.append(f"audio={','.join(audio)}")
53
+ else:
54
+ # Multiple tracks
55
+ for codec in audio:
56
+ params.append(f"audio={codec}")
57
+ else:
58
+ params.append(f"audio={audio}")
59
+
60
+ # Backchannel parameter
61
+ if backchannel:
62
+ params.append("backchannel=1")
63
+
64
+ # GOP parameter
65
+ if gop:
66
+ params.append("gop=1")
67
+
68
+ # Prebuffer parameter
69
+ if prebuffer:
70
+ params.append("prebuffer=5")
71
+
72
+ # Timeout parameter
73
+ params.append(f"timeout={validated_timeout}")
74
+
75
+ return f"{base_url}?{'&'.join(params)}"
@@ -0,0 +1,22 @@
1
+ from .object_path import ObjectPath, Path
2
+ from .promise import Deferred
3
+ from .reactive import ReactiveProperty
4
+ from .signal_handler import SignalHandler
5
+ from .subscribed import Subscribed
6
+ from .task import TaskSet
7
+ from .thread import to_thread
8
+ from .utils import make_sync, merge, merge_with
9
+
10
+ __all__ = [
11
+ "Deferred",
12
+ "make_sync",
13
+ "merge",
14
+ "merge_with",
15
+ "ObjectPath",
16
+ "Path",
17
+ "ReactiveProperty",
18
+ "SignalHandler",
19
+ "Subscribed",
20
+ "TaskSet",
21
+ "to_thread",
22
+ ]