pyloid 0.16.12__py3-none-any.whl → 0.17.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
pyloid/browser_window.py CHANGED
@@ -36,26 +36,36 @@ if TYPE_CHECKING:
36
36
  class CustomWebPage(QWebEnginePage):
37
37
  def __init__(self, profile=None):
38
38
  super().__init__(profile)
39
- # 권한 요청 시그널 연결
40
39
  self.featurePermissionRequested.connect(self._handlePermissionRequest)
40
+ self.desktopMediaRequested.connect(self._handleDesktopMediaRequest)
41
41
  self._permission_handlers = {}
42
+ self._desktop_media_handler = None
42
43
 
43
44
  def _handlePermissionRequest(self, origin: QUrl, feature: QWebEnginePage.Feature):
44
- """기본 권한 요청 핸들러"""
45
+ print(origin, feature)
46
+
47
+ """Default permission request handler"""
45
48
  if feature in self._permission_handlers:
46
- # 등록된 핸들러가 있으면 실행
49
+ # Execute if a handler is registered
47
50
  handler = self._permission_handlers[feature]
48
51
  handler(origin, feature)
49
52
  else:
50
- # 기본적으로 모든 권한 허용
53
+ # Allow all permissions by default
51
54
  self.setFeaturePermission(
52
55
  origin, feature, QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
53
56
  )
54
57
 
55
58
  def setPermissionHandler(self, feature: QWebEnginePage.Feature, handler):
56
- """특정 권한에 대한 핸들러 등록"""
59
+ """Register a handler for a specific permission"""
57
60
  self._permission_handlers[feature] = handler
58
61
 
62
+ def _handleDesktopMediaRequest(self, *args, **kwargs):
63
+ print("Desktop media request received:", args, kwargs)
64
+
65
+ # def setDesktopMediaHandler(self, handler):
66
+ # """desktop media handler"""
67
+ # self._desktop_media_handler = handler
68
+
59
69
 
60
70
  class CustomWebEngineView(QWebEngineView):
61
71
  def __init__(self, parent: "BrowserWindow" = None):
@@ -291,6 +301,21 @@ class BrowserWindow:
291
301
  self.web_view.settings().setUnknownUrlSchemePolicy(
292
302
  QWebEngineSettings.UnknownUrlSchemePolicy.AllowAllUnknownUrlSchemes
293
303
  )
304
+ self.web_view.settings().setAttribute(
305
+ QWebEngineSettings.WebAttribute.AllowRunningInsecureContent, True
306
+ )
307
+ self.web_view.settings().setAttribute(
308
+ QWebEngineSettings.WebAttribute.AllowGeolocationOnInsecureOrigins, True
309
+ )
310
+ self.web_view.settings().setAttribute(
311
+ QWebEngineSettings.WebAttribute.AllowWindowActivationFromJavaScript, True
312
+ )
313
+ self.web_view.settings().setAttribute(
314
+ QWebEngineSettings.WebAttribute.JavascriptCanPaste, True
315
+ )
316
+ self.web_view.settings().setAttribute(
317
+ QWebEngineSettings.WebAttribute.WebRTCPublicInterfacesOnly, False
318
+ )
294
319
 
295
320
  # Set icon
296
321
  if self.app.icon:
@@ -1805,3 +1830,33 @@ class BrowserWindow:
1805
1830
  )
1806
1831
 
1807
1832
  self.set_permission_handler(feature, auto_deny)
1833
+
1834
+ def set_desktop_media_handler(self, handler):
1835
+ """
1836
+ 데스크톱 미디어(화면/윈도우) 선택 핸들러를 설정합니다.
1837
+
1838
+ Parameters
1839
+ ----------
1840
+ handler : callable
1841
+ 요청을 처리할 핸들러 함수. QWebEngineDesktopMediaRequest를 인자로 받습니다.
1842
+
1843
+ Examples
1844
+ --------
1845
+ ```python
1846
+ def custom_media_handler(request):
1847
+ # 사용 가능한 화면 목록 출력
1848
+ for screen in request.screenList():
1849
+ print(f"Screen: {screen.name}")
1850
+
1851
+ # 사용 가능한 윈도우 목록 출력
1852
+ for window in request.windowList():
1853
+ print(f"Window: {window.name}")
1854
+
1855
+ # 첫 번째 화면 선택
1856
+ if request.screenList():
1857
+ request.selectScreen(request.screenList()[0])
1858
+
1859
+ window.set_desktop_media_handler(custom_media_handler)
1860
+ ```
1861
+ """
1862
+ self.web_view.custom_page.setDesktopMediaHandler(handler)
@@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Optional
2
2
 
3
3
  from ..api import PyloidAPI, Bridge
4
4
  from PySide6.QtCore import QByteArray, QBuffer, QIODeviceBase
5
+ import base64
5
6
 
6
7
  if TYPE_CHECKING:
7
8
  from ..pyloid import Pyloid
@@ -244,3 +245,11 @@ class WindowAPI(PyloidAPI):
244
245
  base64_data = byte_array.toBase64().data().decode()
245
246
  return f"data:image/png;base64,{base64_data}"
246
247
  return ""
248
+
249
+ ###########################################################################################
250
+ # Quit
251
+ ###########################################################################################
252
+ @Bridge()
253
+ def quit(self):
254
+ """Quits the application."""
255
+ self.app.quit()
pyloid/pyloid.py CHANGED
@@ -26,6 +26,9 @@ import logging
26
26
  from .browser_window import BrowserWindow
27
27
  from .tray import TrayEvent
28
28
  from PySide6.QtCore import QCoreApplication
29
+ from PySide6.QtCore import QRunnable, QThreadPool, Signal, QObject
30
+ import time
31
+ from .thread_pool import PyloidThreadPool
29
32
 
30
33
  # for linux debug
31
34
  os.environ["QTWEBENGINE_DICTIONARIES_PATH"] = "/"
@@ -431,10 +434,16 @@ class Pyloid(QApplication):
431
434
  app.quit()
432
435
  ```
433
436
  """
437
+ # 먼저 스레드 풀 정리
438
+ thread_pool = self.get_thread_pool()
439
+ thread_pool.clear() # 대기 중인 작업 제거
440
+
441
+ # 윈도우 정리
434
442
  for window in self.windows:
435
443
  window._window.close()
436
444
  window.web_page.deleteLater()
437
445
  window.web_view.deleteLater()
446
+
438
447
  QApplication.quit()
439
448
 
440
449
  ###########################################################################################
@@ -1395,4 +1404,4 @@ class Pyloid(QApplication):
1395
1404
  window.web_view.page().runJavaScript(js_code)
1396
1405
  window.web_view.page().setBackgroundColor(
1397
1406
  Qt.GlobalColor.black if self.theme == "dark" else Qt.GlobalColor.white
1398
- )
1407
+ )
pyloid/thread_pool.py ADDED
@@ -0,0 +1,501 @@
1
+ from PySide6.QtCore import QRunnable, QThreadPool, QDeadlineTimer, QObject, Signal
2
+ from typing import Callable, Optional, Union
3
+
4
+ class PyloidRunnable(QRunnable):
5
+ """
6
+ A runnable task class that extends QRunnable from Qt.
7
+
8
+ Defines a unit of work that can be executed in a thread pool.
9
+ """
10
+
11
+ def __init__(self):
12
+ """
13
+ Initializes a PyloidRunnable instance.
14
+
15
+ By default, auto-delete is enabled.
16
+ """
17
+ super().__init__()
18
+ self.setAutoDelete(True)
19
+
20
+ def get_auto_delete(self) -> bool:
21
+ """
22
+ Returns whether the task is automatically deleted after completion in the thread pool.
23
+
24
+ The default value is True.
25
+
26
+ Returns
27
+ -------
28
+ bool
29
+ True if the task is automatically deleted after completion, False if manual deletion is required
30
+
31
+ Examples
32
+ --------
33
+ ```python
34
+ from pyloid.thread_pool import PyloidRunnable
35
+ import time
36
+
37
+ class Worker(PyloidRunnable):
38
+ def run(self):
39
+ time.sleep(1)
40
+ print("Task executed")
41
+
42
+ worker = Worker()
43
+ print(worker.get_auto_delete())
44
+ ```
45
+ """
46
+ return self.autoDelete()
47
+
48
+ def set_auto_delete(self, value: bool) -> None:
49
+ """
50
+ Sets whether the task is automatically deleted after completion in the thread pool.
51
+
52
+ Parameters
53
+ ----------
54
+ value : bool
55
+ True to enable auto-delete after task completion,
56
+ False to require manual deletion
57
+
58
+ Examples
59
+ --------
60
+ ```python
61
+ from pyloid.thread_pool import PyloidRunnable
62
+ import time
63
+
64
+ class Worker(PyloidRunnable):
65
+ def run(self):
66
+ time.sleep(1)
67
+ print("Task executed")
68
+
69
+ worker = Worker()
70
+ worker.set_auto_delete(False)
71
+ ```
72
+ """
73
+ self.setAutoDelete(value)
74
+
75
+ def run(self) -> None:
76
+ """
77
+ Defines the actual work to be executed in the thread pool.
78
+
79
+ This method must be implemented in subclasses.
80
+
81
+ Examples
82
+ --------
83
+ ```python
84
+ from pyloid.thread_pool import PyloidRunnable, PyloidThreadPool
85
+ import time
86
+
87
+ class Worker(PyloidRunnable):
88
+ def run(self):
89
+ time.sleep(1)
90
+ print("Task executed")
91
+
92
+ worker = Worker()
93
+ thread_pool = PyloidThreadPool()
94
+ thread_pool.start(worker)
95
+ ```
96
+ """
97
+ pass
98
+
99
+ class PyloidDefaultSignals(QObject):
100
+ """
101
+ Default signal class.
102
+
103
+ Defines signals used for task start, completion, and error occurrence in the thread pool.
104
+
105
+ Attributes
106
+ ----------
107
+ started : Signal
108
+ Signal emitted when a task starts
109
+ finished : Signal
110
+ Signal emitted when a task completes
111
+ error : Signal(str)
112
+ Signal emitted when an error occurs
113
+ progress : Signal(int)
114
+ Signal emitted when progress changes
115
+
116
+ Examples
117
+ --------
118
+ ```python
119
+ from pyloid.thread_pool import PyloidRunnable, PyloidThreadPool, PyloidDefaultSignals
120
+ import time
121
+
122
+ class Worker(PyloidRunnable):
123
+ def __init__(self):
124
+ super().__init__()
125
+ self.signals = PyloidDefaultSignals()
126
+
127
+ def run(self):
128
+ for i in range(101):
129
+ self.signals.progress.emit(i)
130
+ time.sleep(0.1)
131
+
132
+ worker = Worker()
133
+
134
+ worker.signals.finished.connect(lambda: print("Task completed."))
135
+ worker.signals.error.connect(lambda error: print(f"Error occurred: {error}"))
136
+ worker.signals.progress.connect(lambda progress: print(f"Progress: {progress}%"))
137
+
138
+ thread_pool = PyloidThreadPool()
139
+ thread_pool.start(worker)
140
+ ```
141
+ """
142
+ started = Signal()
143
+ finished = Signal()
144
+ error = Signal(str)
145
+ progress = Signal(int)
146
+
147
+
148
+ class PyloidThreadPool:
149
+ def __init__(self):
150
+ self.thread_pool = QThreadPool.globalInstance()
151
+
152
+ def start(self, runnable: Union[PyloidRunnable, Callable], priority: int = ...) -> None:
153
+ """
154
+ Adds a task to the thread pool and executes it.
155
+
156
+ Parameters
157
+ ----------
158
+ runnable : Union[PyloidRunnable, Callable]
159
+ Task to be executed
160
+ priority : int
161
+ Task priority
162
+
163
+ Examples
164
+ --------
165
+ ```python
166
+ from pyloid.thread_pool import PyloidRunnable, PyloidThreadPool
167
+ import time
168
+
169
+ class Worker(PyloidRunnable):
170
+ def run(self):
171
+ time.sleep(1)
172
+ print("Task executed")
173
+
174
+ worker = Worker()
175
+ thread_pool = PyloidThreadPool()
176
+ thread_pool.start(worker)
177
+ ```
178
+ """
179
+ self.thread_pool.start(runnable, priority)
180
+
181
+ def active_thread_count(self) -> int:
182
+ """
183
+ Returns the number of currently active threads.
184
+
185
+ Returns
186
+ -------
187
+ int
188
+ Number of currently active threads
189
+
190
+ Examples
191
+ --------
192
+ ```python
193
+ from pyloid.thread_pool import PyloidThreadPool
194
+
195
+ thread_pool = PyloidThreadPool()
196
+ print(thread_pool.active_thread_count())
197
+ ```
198
+ """
199
+ return self.thread_pool.activeThreadCount()
200
+
201
+ def max_thread_count(self) -> int:
202
+ """
203
+ Returns the maximum number of threads that can run simultaneously in the thread pool.
204
+
205
+ Returns
206
+ -------
207
+ int
208
+ Maximum number of threads
209
+
210
+ Examples
211
+ --------
212
+ ```python
213
+ from pyloid.thread_pool import PyloidThreadPool
214
+
215
+ thread_pool = PyloidThreadPool()
216
+ print(thread_pool.max_thread_count())
217
+ ```
218
+ """
219
+ return self.thread_pool.maxThreadCount()
220
+
221
+ def set_max_thread_count(self, max_thread_count: int) -> None:
222
+ """
223
+ Sets the maximum number of threads that can run simultaneously in the thread pool.
224
+
225
+ Parameters
226
+ ----------
227
+ max_thread_count : int
228
+ Maximum number of threads
229
+
230
+ Examples
231
+ --------
232
+ ```python
233
+ from pyloid.thread_pool import PyloidThreadPool
234
+
235
+ thread_pool = PyloidThreadPool()
236
+ thread_pool.set_max_thread_count(10)
237
+ ```
238
+ """
239
+ self.thread_pool.setMaxThreadCount(max_thread_count)
240
+
241
+ def reserve_thread(self) -> None:
242
+ """
243
+ Reserves a thread in the thread pool.
244
+
245
+ Examples
246
+ --------
247
+ ```python
248
+ from pyloid.thread_pool import PyloidThreadPool, PyloidRunnable
249
+ import time
250
+
251
+ class Worker(PyloidRunnable):
252
+ def run(self):
253
+ time.sleep(1)
254
+ print("Task executed on reserved thread")
255
+
256
+ # Create thread pool
257
+ thread_pool = PyloidThreadPool()
258
+
259
+ # Reserve thread
260
+ thread_pool.reserve_thread()
261
+
262
+ try:
263
+ # Execute task on reserved thread
264
+ worker = Worker()
265
+ thread_pool.start_on_reserved_thread(worker)
266
+
267
+ # Wait for task completion
268
+ thread_pool.wait_for_done()
269
+ finally:
270
+ # Important: Reserved threads must be released
271
+ thread_pool.release_thread()
272
+ ```
273
+ """
274
+ self.thread_pool.reserveThread()
275
+
276
+ def release_thread(self) -> None:
277
+ """
278
+ Releases a reserved thread in the thread pool.
279
+
280
+ Examples
281
+ --------
282
+ ```python
283
+ from pyloid.thread_pool import PyloidThreadPool
284
+
285
+ thread_pool = PyloidThreadPool()
286
+ thread_pool.release_thread()
287
+ ```
288
+ """
289
+ self.thread_pool.releaseThread()
290
+
291
+ def clear(self) -> None:
292
+ """
293
+ Removes all pending tasks from the thread pool.
294
+
295
+ Examples
296
+ --------
297
+ ```python
298
+ from pyloid.thread_pool import PyloidThreadPool
299
+
300
+ thread_pool = PyloidThreadPool()
301
+ thread_pool.clear()
302
+ ```
303
+ """
304
+ self.thread_pool.clear()
305
+
306
+ # def contains(self, thread: QThread) -> bool:
307
+ # return self.thread_pool.contains(thread)
308
+
309
+ def get_expiry_timeout(self) -> int:
310
+ """
311
+ Returns the thread expiry timeout in the thread pool.
312
+
313
+ Returns
314
+ -------
315
+ int
316
+ Thread expiry timeout
317
+
318
+ Examples
319
+ --------
320
+ ```python
321
+ from pyloid.thread_pool import PyloidThreadPool
322
+
323
+ thread_pool = PyloidThreadPool()
324
+ print(thread_pool.get_expiry_timeout())
325
+ ```
326
+ """
327
+ return self.thread_pool.expiryTimeout()
328
+
329
+ def set_expiry_timeout(self, expiry_timeout: int) -> None:
330
+ """
331
+ Sets the thread expiry timeout in the thread pool.
332
+
333
+ Parameters
334
+ ----------
335
+ expiry_timeout : int
336
+ Thread expiry timeout
337
+
338
+ Examples
339
+ --------
340
+ ```python
341
+ from pyloid.thread_pool import PyloidThreadPool
342
+
343
+ thread_pool = PyloidThreadPool()
344
+ thread_pool.set_expiry_timeout(1000)
345
+ ```
346
+ """
347
+ self.thread_pool.setExpiryTimeout(expiry_timeout)
348
+
349
+ # def set_stack_size(self, stack_size: int) -> None:
350
+ # self.thread_pool.setStackSize(stack_size)
351
+
352
+ # def stack_size(self) -> int:
353
+ # return self.thread_pool.stackSize()
354
+
355
+ # def set_thread_priority(self, priority: QThread.Priority) -> None:
356
+ # self.thread_pool.setThreadPriority(priority)
357
+
358
+ # def thread_priority(self) -> QThread.Priority:
359
+ # return self.thread_pool.threadPriority()
360
+
361
+ def start_on_reserved_thread(self, runnable: QRunnable) -> None:
362
+ """
363
+ Executes a task on a reserved thread.
364
+
365
+ Parameters
366
+ ----------
367
+ runnable : QRunnable
368
+ Task to be executed
369
+
370
+ Examples
371
+ --------
372
+ ```python
373
+ from pyloid.thread_pool import PyloidThreadPool, PyloidRunnable
374
+ import time
375
+
376
+ class Worker(PyloidRunnable):
377
+ def run(self):
378
+ time.sleep(1)
379
+ print("Task executed on reserved thread")
380
+
381
+ worker = Worker()
382
+ thread_pool = PyloidThreadPool()
383
+ thread_pool.reserve_thread()
384
+ thread_pool.start_on_reserved_thread(worker)
385
+ thread_pool.wait_for_done()
386
+ thread_pool.release_thread()
387
+ ```
388
+ """
389
+ self.thread_pool.startOnReservedThread(runnable)
390
+
391
+ def try_start(self, runnable: Union[QRunnable, Callable]) -> bool:
392
+ """
393
+ Adds a new task to the thread pool and attempts to execute it immediately.
394
+
395
+ Only executes the task if the thread pool has available capacity.
396
+ Operates in a non-blocking manner and does not start the task if the thread pool is full.
397
+
398
+ Parameters
399
+ ----------
400
+ runnable : Union[QRunnable, Callable]
401
+ Task to be executed
402
+
403
+ Returns
404
+ -------
405
+ bool
406
+ True: Task successfully started
407
+ False: Task could not be started because the thread pool is full
408
+
409
+ Examples
410
+ --------
411
+ ```python
412
+ from pyloid.thread_pool import PyloidThreadPool, PyloidRunnable
413
+
414
+ class Worker(PyloidRunnable):
415
+ def run(self):
416
+ print("Task executed")
417
+
418
+ thread_pool = PyloidThreadPool()
419
+ worker = Worker()
420
+
421
+ if thread_pool.try_start(worker):
422
+ print("Task started")
423
+ else:
424
+ print("Task could not be started because the thread pool is full")
425
+ ```
426
+ """
427
+ return self.thread_pool.tryStart(runnable)
428
+
429
+ def try_take(self, runnable: QRunnable) -> bool:
430
+ """
431
+ Attempts to remove a specific task from the thread pool queue.
432
+
433
+ Only removes tasks that have not yet been executed. Tasks that are already running cannot be removed.
434
+ Used when task cancellation is needed.
435
+
436
+ Parameters
437
+ ----------
438
+ runnable : QRunnable
439
+ Task to be removed from the queue
440
+
441
+ Returns
442
+ -------
443
+ bool
444
+ True: Task successfully removed from the queue
445
+ False: Task could not be removed (already running or not found)
446
+
447
+ Examples
448
+ --------
449
+ ```python
450
+ from pyloid.thread_pool import PyloidThreadPool, PyloidRunnable
451
+
452
+ class Worker(PyloidRunnable):
453
+ def run(self):
454
+ print("Task executed")
455
+
456
+ thread_pool = PyloidThreadPool()
457
+ worker = Worker()
458
+
459
+ # Add task
460
+ thread_pool.start(worker)
461
+
462
+ # Attempt to remove task
463
+ if thread_pool.try_take(worker):
464
+ print("Task removed from queue")
465
+ else:
466
+ print("Task could not be removed (already running or not found)")
467
+ ```
468
+ """
469
+ return self.thread_pool.tryTake(runnable)
470
+
471
+ def wait_for_done(self, timeout: Optional[int] = None) -> bool:
472
+ """
473
+ Waits for tasks to complete.
474
+
475
+ If no timeout is specified, waits indefinitely until completion.
476
+
477
+ Parameters
478
+ ----------
479
+ timeout : Optional[int]
480
+ Wait time
481
+
482
+ Returns
483
+ -------
484
+ bool
485
+ True if tasks completed, False otherwise
486
+
487
+ Examples
488
+ --------
489
+ ```python
490
+ from pyloid.thread_pool import PyloidThreadPool
491
+
492
+ thread_pool = PyloidThreadPool()
493
+ thread_pool.wait_for_done()
494
+
495
+ print("Tasks completed.")
496
+ ```
497
+ """
498
+ if timeout is None:
499
+ return self.thread_pool.waitForDone(-1)
500
+ else:
501
+ return self.thread_pool.waitForDone(timeout)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyloid
3
- Version: 0.16.12
3
+ Version: 0.17.0
4
4
  Summary:
5
5
  Author: aesthetics-of-record
6
6
  Author-email: 111675679+aesthetics-of-record@users.noreply.github.com
@@ -10,8 +10,7 @@ Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
- Requires-Dist: mss (>=9.0.2,<10.0.0)
14
- Requires-Dist: pyside6 (>=6.7.3,<7.0.0)
13
+ Requires-Dist: pyside6 (>=6.8.0.2,<7.0.0.0)
15
14
  Description-Content-Type: text/markdown
16
15
 
17
16
  # Pyloid 👋
@@ -1,17 +1,18 @@
1
1
  pyloid/__init__.py,sha256=OOPhOKNQVmAM8hnfTeE7lHzxb8LsFNcgegBAvDrA-vY,293
2
2
  pyloid/api.py,sha256=np0pFVUlen_GpN0svY0A3awY_ZjVFk-RpHQZZKFUMuo,2157
3
3
  pyloid/autostart.py,sha256=K7DQYl4LHItvPp0bt1V9WwaaZmVSTeGvadkcwG-KKrI,3899
4
- pyloid/browser_window.py,sha256=xSf1tR1kazAIpqbrTEx0YgcMXqcHOzPpmdzU3agTqw0,58691
4
+ pyloid/browser_window.py,sha256=YoScOpHQjxZBGZsYZ_TrDjyoyvwhBsc74ySVNzw5g1g,60873
5
5
  pyloid/custom/titlebar.py,sha256=itzK9pJbZMQ7BKca9kdbuHMffurrw15UijR6OU03Xsk,3894
6
6
  pyloid/filewatcher.py,sha256=3M5zWVUf1OhlkWJcDFC8ZA9agO4Q-U8WdgGpy6kaVz0,4601
7
7
  pyloid/js_api/event_api.py,sha256=_52yyBonqecmMvJpFW7OMNi_jX8Nrteqw_kI6r-DGG0,951
8
- pyloid/js_api/window_api.py,sha256=_EAZ0GG0oa0EeIIyWnys03InLQuQfv4ZPezMouOJEGc,8155
8
+ pyloid/js_api/window_api.py,sha256=QutXXAOZkpYmytOYSenpzVSCl15-OFEjDDr75fHfLvk,8481
9
9
  pyloid/monitor.py,sha256=1mXvHm5deohnNlTLcRx4sT4x-stnOIb0dUQnnxN50Uo,28295
10
- pyloid/pyloid.py,sha256=ar-3yP8IqB6HCWwuxJmjJZ9kekn7LhHqnNOTH-qhxpM,43925
10
+ pyloid/pyloid.py,sha256=klY6-O7rEZZYfhayq9RTwvO9f8KCXWxIo7G8BDFy2hg,44236
11
+ pyloid/thread_pool.py,sha256=fKOBb8jMfZn_7crA_fJCno8dObBRZE31EIWaNQ759aw,14616
11
12
  pyloid/timer.py,sha256=RqMsChFUd93cxMVgkHWiIKrci0QDTBgJSTULnAtYT8M,8712
12
13
  pyloid/tray.py,sha256=D12opVEc2wc2T4tK9epaN1oOdeziScsIVNM2uCN7C-A,1710
13
14
  pyloid/utils.py,sha256=VGZE2liY8_AElEqxVe1YLbk3fWlcAevpRc6oOTTgi-U,1927
14
- pyloid-0.16.12.dist-info/LICENSE,sha256=F96EzotgWhhpnQTW2TcdoqrMDir1jyEo6H915tGQ-QE,11524
15
- pyloid-0.16.12.dist-info/METADATA,sha256=V0I3qXPqcx0dSLUOO0_03tgqO4wn6UBZwDl5VoqLxug,3088
16
- pyloid-0.16.12.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
17
- pyloid-0.16.12.dist-info/RECORD,,
15
+ pyloid-0.17.0.dist-info/LICENSE,sha256=F96EzotgWhhpnQTW2TcdoqrMDir1jyEo6H915tGQ-QE,11524
16
+ pyloid-0.17.0.dist-info/METADATA,sha256=iuLvJxvORyzQNX-ZDgkOJ8TP6onbfIcFUc5OQZSuPHs,3054
17
+ pyloid-0.17.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
18
+ pyloid-0.17.0.dist-info/RECORD,,