pyloid 0.22.1__py3-none-any.whl → 0.23.1__py3-none-any.whl

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.
pyloid/pyloid.py CHANGED
@@ -30,7 +30,12 @@ from PySide6.QtCore import Signal, QObject, Slot
30
30
  import uuid
31
31
  from PySide6.QtCore import QEventLoop
32
32
  import socket
33
- from typing import Any
33
+ from typing import Any, Set
34
+ from platformdirs import PlatformDirs
35
+ from .store import Store
36
+ from .rpc import PyloidRPC
37
+ import threading
38
+ import asyncio
34
39
 
35
40
  # software backend
36
41
  os.environ["QT_QUICK_BACKEND"] = "software"
@@ -74,7 +79,7 @@ qInstallMessageHandler(custom_message_handler)
74
79
 
75
80
  class _WindowController(QObject):
76
81
  create_window_signal = Signal(
77
- QApplication, str, int, int, int, int, bool, bool, bool, list
82
+ QApplication, str, int, int, int, int, bool, bool, bool, PyloidRPC
78
83
  )
79
84
 
80
85
 
@@ -113,7 +118,7 @@ class _Pyloid(QApplication):
113
118
 
114
119
  self.data = data
115
120
 
116
- self.windows_dict = {} # 윈도우 ID를 키로 사용하는 딕셔너리
121
+ self.windows_dict: Dict[str, BrowserWindow] = {} # 윈도우 ID를 키로 사용하는 딕셔너리
117
122
  self.server = None
118
123
 
119
124
  self.app_name = app_name
@@ -154,6 +159,8 @@ class _Pyloid(QApplication):
154
159
  # Add color scheme tracking
155
160
  self.styleHints().colorSchemeChanged.connect(self._handle_color_scheme_change)
156
161
 
162
+ self.dirs = PlatformDirs(self.app_name, appauthor=False)
163
+
157
164
  # def set_theme(self, theme: Literal["system", "dark", "light"]):
158
165
  # """
159
166
  # 시스템의 테마를 설정합니다.
@@ -223,7 +230,7 @@ class _Pyloid(QApplication):
223
230
  frame: bool = True,
224
231
  context_menu: bool = False,
225
232
  dev_tools: bool = False,
226
- js_apis: List[PyloidAPI] = [],
233
+ rpc: Optional[PyloidRPC] = None,
227
234
  ) -> BrowserWindow:
228
235
  """
229
236
  Creates a new browser window.
@@ -246,8 +253,8 @@ class _Pyloid(QApplication):
246
253
  Whether to use the context menu (default is False)
247
254
  dev_tools : bool, optional
248
255
  Whether to use developer tools (default is False)
249
- js_apis : list of PyloidAPI, optional
250
- List of JavaScript APIs to add to the window (default is an empty list)
256
+ rpc : PyloidRPC, optional
257
+ The RPC server instance to be used in the window
251
258
 
252
259
  Returns
253
260
  -------
@@ -270,7 +277,7 @@ class _Pyloid(QApplication):
270
277
  frame,
271
278
  context_menu,
272
279
  dev_tools,
273
- js_apis,
280
+ rpc,
274
281
  )
275
282
  latest_window_id = list(self.windows_dict.keys())[-1]
276
283
  return self.windows_dict[latest_window_id]
@@ -286,7 +293,8 @@ class _Pyloid(QApplication):
286
293
  frame: bool,
287
294
  context_menu: bool,
288
295
  dev_tools: bool,
289
- js_apis: List[PyloidAPI] = [],
296
+ # js_apis: List[PyloidAPI] = [],
297
+ rpc: Optional[PyloidRPC] = None,
290
298
  ) -> BrowserWindow:
291
299
  """Function to create a new browser window."""
292
300
  window = BrowserWindow(
@@ -299,7 +307,7 @@ class _Pyloid(QApplication):
299
307
  frame,
300
308
  context_menu,
301
309
  dev_tools,
302
- js_apis,
310
+ rpc,
303
311
  )
304
312
  self.windows_dict[window._window.id] = window
305
313
  return window
@@ -319,6 +327,19 @@ class _Pyloid(QApplication):
319
327
  app.run()
320
328
  ```
321
329
  """
330
+
331
+ # Collect and deduplicate RPC servers
332
+ rpc_servers: Set[PyloidRPC] = set()
333
+ for window in self.windows_dict.values():
334
+ if window._window.rpc is not None:
335
+ rpc_servers.add(window._window.rpc)
336
+
337
+ # 고유한 RPC 서버만 시작
338
+ for rpc in rpc_servers:
339
+ server_thread = threading.Thread(target=rpc.start, daemon=True)
340
+ server_thread.start()
341
+
342
+
322
343
  if is_production():
323
344
  sys.exit(self.exec())
324
345
  else:
@@ -347,20 +368,20 @@ class _Pyloid(QApplication):
347
368
  ###########################################################################################
348
369
  def get_windows(self) -> Dict[str, BrowserWindow]:
349
370
  """
350
- Returns a list of all browser windows.
371
+ Returns a dictionary of all browser windows.
351
372
 
352
373
  Returns
353
374
  -------
354
- List[BrowserWindow]
355
- List of all browser windows
375
+ Dict[str, BrowserWindow]
376
+ Dictionary with window IDs as keys and BrowserWindow objects as values
356
377
 
357
378
  Examples
358
379
  --------
359
380
  ```python
360
381
  app = Pyloid(app_name="Pyloid-App")
361
382
  windows = app.get_windows()
362
- for window in windows:
363
- print(window.get_id())
383
+ for window_id, window in windows.items():
384
+ print(f"Window ID: {window_id}")
364
385
  ```
365
386
  """
366
387
  return self.windows_dict
@@ -1422,6 +1443,208 @@ class _Pyloid(QApplication):
1422
1443
  Qt.GlobalColor.black if self.theme == "dark" else Qt.GlobalColor.white
1423
1444
  )
1424
1445
 
1446
+ ###########################################################################################
1447
+ # platformdirs
1448
+ ###########################################################################################
1449
+
1450
+ def user_data_dir(self) -> str:
1451
+ """
1452
+ Returns the user data directory path.
1453
+
1454
+ Returns
1455
+ -------
1456
+ str
1457
+ User data directory path
1458
+
1459
+ Examples
1460
+ --------
1461
+ >>> app = Pyloid(app_name="Pyloid-App")
1462
+ >>> data_dir = app.user_data_dir()
1463
+ >>> print(data_dir)
1464
+ '/Users/user/Library/Application Support/Pyloid-App' # Example for macOS
1465
+ """
1466
+ return self.dirs.user_data_dir
1467
+
1468
+ def site_data_dir(self) -> str:
1469
+ """
1470
+ Returns the site data directory path.
1471
+
1472
+ Returns
1473
+ -------
1474
+ str
1475
+ Site data directory path
1476
+
1477
+ Examples
1478
+ --------
1479
+ >>> app = Pyloid(app_name="Pyloid-App")
1480
+ >>> site_data_dir = app.site_data_dir()
1481
+ >>> print(site_data_dir)
1482
+ '/Library/Application Support/Pyloid-App' # Example for macOS
1483
+ """
1484
+ return self.dirs.site_data_dir
1485
+
1486
+ def user_cache_dir(self) -> str:
1487
+ """
1488
+ Returns the user cache directory path.
1489
+
1490
+ Returns
1491
+ -------
1492
+ str
1493
+ User cache directory path
1494
+
1495
+ Examples
1496
+ --------
1497
+ >>> app = Pyloid(app_name="Pyloid-App")
1498
+ >>> cache_dir = app.user_cache_dir()
1499
+ >>> print(cache_dir)
1500
+ '/Users/user/Library/Caches/Pyloid-App' # Example for macOS
1501
+ """
1502
+ return self.dirs.user_cache_dir
1503
+
1504
+ def user_log_dir(self) -> str:
1505
+ """
1506
+ Returns the user log directory path.
1507
+
1508
+ Returns
1509
+ -------
1510
+ str
1511
+ User log directory path
1512
+
1513
+ Examples
1514
+ --------
1515
+ >>> app = Pyloid(app_name="Pyloid-App")
1516
+ >>> log_dir = app.user_log_dir()
1517
+ >>> print(log_dir)
1518
+ '/Users/user/Library/Logs/Pyloid-App' # Example for macOS
1519
+ """
1520
+ return self.dirs.user_log_dir
1521
+
1522
+ def user_documents_dir(self) -> str:
1523
+ """
1524
+ Returns the user documents directory path.
1525
+
1526
+ Returns
1527
+ -------
1528
+ str
1529
+ User documents directory path
1530
+
1531
+ Examples
1532
+ --------
1533
+ >>> app = Pyloid(app_name="Pyloid-App")
1534
+ >>> documents_dir = app.user_documents_dir()
1535
+ >>> print(documents_dir)
1536
+ '/Users/user/Documents' # Example for macOS
1537
+ """
1538
+ return self.dirs.user_documents_dir
1539
+
1540
+ def user_downloads_dir(self) -> str:
1541
+ """
1542
+ Returns the user downloads directory path.
1543
+
1544
+ Returns
1545
+ -------
1546
+ str
1547
+ User downloads directory path
1548
+
1549
+ Examples
1550
+ --------
1551
+ >>> app = Pyloid(app_name="Pyloid-App")
1552
+ >>> downloads_dir = app.user_downloads_dir()
1553
+ >>> print(downloads_dir)
1554
+ '/Users/user/Downloads' # Example for macOS
1555
+ """
1556
+ return self.dirs.user_downloads_dir
1557
+
1558
+ def user_pictures_dir(self) -> str:
1559
+ """
1560
+ Returns the user pictures directory path.
1561
+
1562
+ Returns
1563
+ -------
1564
+ str
1565
+ User pictures directory path
1566
+
1567
+ Examples
1568
+ --------
1569
+ >>> app = Pyloid(app_name="Pyloid-App")
1570
+ >>> pictures_dir = app.user_pictures_dir()
1571
+ >>> print(pictures_dir)
1572
+ '/Users/user/Pictures' # Example for macOS
1573
+ """
1574
+ return self.dirs.user_pictures_dir
1575
+
1576
+ def user_videos_dir(self) -> str:
1577
+ """
1578
+ Returns the user videos directory path.
1579
+
1580
+ Returns
1581
+ -------
1582
+ str
1583
+ User videos directory path
1584
+
1585
+ Examples
1586
+ --------
1587
+ >>> app = Pyloid(app_name="Pyloid-App")
1588
+ >>> videos_dir = app.user_videos_dir()
1589
+ >>> print(videos_dir)
1590
+ '/Users/user/Movies' # Example for macOS
1591
+ """
1592
+ return self.dirs.user_videos_dir
1593
+
1594
+ def user_music_dir(self) -> str:
1595
+ """
1596
+ Returns the user music directory path.
1597
+
1598
+ Returns
1599
+ -------
1600
+ str
1601
+ User music directory path
1602
+
1603
+ Examples
1604
+ --------
1605
+ >>> app = Pyloid(app_name="Pyloid-App")
1606
+ >>> music_dir = app.user_music_dir()
1607
+ >>> print(music_dir)
1608
+ '/Users/user/Music' # Example for macOS
1609
+ """
1610
+ return self.dirs.user_music_dir
1611
+
1612
+ def user_desktop_dir(self) -> str:
1613
+ """
1614
+ Returns the user desktop directory path.
1615
+
1616
+ Returns
1617
+ -------
1618
+ str
1619
+ User desktop directory path
1620
+
1621
+ Examples
1622
+ --------
1623
+ >>> app = Pyloid(app_name="Pyloid-App")
1624
+ >>> desktop_dir = app.user_desktop_dir()
1625
+ >>> print(desktop_dir)
1626
+ '/Users/user/Desktop' # Example for macOS
1627
+ """
1628
+ return self.dirs.user_desktop_dir
1629
+
1630
+ def user_runtime_dir(self) -> str:
1631
+ """
1632
+ Returns the user runtime directory path.
1633
+
1634
+ Returns
1635
+ -------
1636
+ str
1637
+ User runtime directory path
1638
+
1639
+ Examples
1640
+ --------
1641
+ >>> app = Pyloid(app_name="Pyloid-App")
1642
+ >>> runtime_dir = app.user_runtime_dir()
1643
+ >>> print(runtime_dir)
1644
+ '/Users/user/Library/Caches/TemporaryItems/Pyloid-App' # Example for macOS
1645
+ """
1646
+ return self.dirs.user_runtime_dir
1647
+
1425
1648
 
1426
1649
  class Pyloid(QObject):
1427
1650
  command_signal = Signal(str, str, object)
@@ -1431,7 +1654,7 @@ class Pyloid(QObject):
1431
1654
  self,
1432
1655
  app_name: str,
1433
1656
  single_instance: bool = True,
1434
- data: Optional[Dict[str, Any]] = None,
1657
+ # data: Optional[Dict[str, Any]] = None,
1435
1658
  ):
1436
1659
  """
1437
1660
  Initialize the Pyloid application.
@@ -1446,8 +1669,6 @@ class Pyloid(QObject):
1446
1669
  The name of the application.
1447
1670
  single_instance : bool, optional
1448
1671
  Determines whether to run as a single instance. (Default is True)
1449
- data : dict, optional
1450
- Data to be transmitted to the frontend web engine via IPC
1451
1672
 
1452
1673
  Notes
1453
1674
  -----
@@ -1456,7 +1677,7 @@ class Pyloid(QObject):
1456
1677
  """
1457
1678
  super().__init__()
1458
1679
 
1459
- self.data = data
1680
+ self.data = None # 나중에 데이터 필요 시 수정
1460
1681
 
1461
1682
  self.app = _Pyloid(app_name, single_instance, self.data)
1462
1683
 
@@ -1479,6 +1700,7 @@ class Pyloid(QObject):
1479
1700
  frame=params.get("frame", True),
1480
1701
  context_menu=params.get("context_menu", False),
1481
1702
  dev_tools=params.get("dev_tools", False),
1703
+ rpc=params.get("rpc", None),
1482
1704
  )
1483
1705
  result = window
1484
1706
 
@@ -1653,6 +1875,7 @@ class Pyloid(QObject):
1653
1875
  frame: bool = True,
1654
1876
  context_menu: bool = False,
1655
1877
  dev_tools: bool = False,
1878
+ rpc: Optional[PyloidRPC] = None,
1656
1879
  ) -> BrowserWindow:
1657
1880
  """
1658
1881
  Creates a new browser window.
@@ -1675,6 +1898,8 @@ class Pyloid(QObject):
1675
1898
  Whether to use the context menu (default is False)
1676
1899
  dev_tools : bool, optional
1677
1900
  Whether to use developer tools (default is False)
1901
+ rpc : PyloidRPC, optional
1902
+ The RPC server instance to be used in the window
1678
1903
 
1679
1904
  Returns
1680
1905
  -------
@@ -1695,6 +1920,7 @@ class Pyloid(QObject):
1695
1920
  "frame": frame,
1696
1921
  "context_menu": context_menu,
1697
1922
  "dev_tools": dev_tools,
1923
+ "rpc": rpc,
1698
1924
  }
1699
1925
  return self.execute_command("create_window", params)
1700
1926
 
@@ -2210,6 +2436,7 @@ class Pyloid(QObject):
2210
2436
  --------
2211
2437
  >>> def on_file_change(file_path):
2212
2438
  >>> print(f"File changed: {file_path}")
2439
+ >>>
2213
2440
  >>> app = Pyloid(app_name="Pyloid-App")
2214
2441
  >>> app.set_file_change_callback(on_file_change)
2215
2442
  """
@@ -2228,6 +2455,7 @@ class Pyloid(QObject):
2228
2455
  --------
2229
2456
  >>> def on_directory_change(dir_path):
2230
2457
  >>> print(f"Directory changed: {dir_path}")
2458
+ >>>
2231
2459
  >>> app = Pyloid(app_name="Pyloid-App")
2232
2460
  >>> app.set_directory_change_callback(on_directory_change)
2233
2461
  """
@@ -2305,3 +2533,234 @@ class Pyloid(QObject):
2305
2533
  >>> directory_path = app.select_directory_dialog(dir="/home/user")
2306
2534
  """
2307
2535
  return self.execute_command("select_directory_dialog", {"dir": dir})
2536
+
2537
+ # --- Add platformdirs wrapper functions ---
2538
+
2539
+ def user_data_dir(self) -> str:
2540
+ """
2541
+ Returns the user data directory path.
2542
+
2543
+ Returns
2544
+ -------
2545
+ str
2546
+ User data directory path
2547
+
2548
+ Examples
2549
+ --------
2550
+ >>> app = Pyloid(app_name="Pyloid-App")
2551
+ >>> data_dir = app.user_data_dir()
2552
+ >>> print(data_dir)
2553
+ '/Users/user/Library/Application Support/Pyloid-App' # Example for macOS
2554
+ """
2555
+ return self.app.user_data_dir()
2556
+
2557
+ def site_data_dir(self) -> str:
2558
+ """
2559
+ Returns the site data directory path.
2560
+
2561
+ Returns
2562
+ -------
2563
+ str
2564
+ Site data directory path
2565
+
2566
+ Examples
2567
+ --------
2568
+ >>> app = Pyloid(app_name="Pyloid-App")
2569
+ >>> site_data_dir = app.site_data_dir()
2570
+ >>> print(site_data_dir)
2571
+ '/Library/Application Support/Pyloid-App' # Example for macOS
2572
+ """
2573
+ return self.app.site_data_dir()
2574
+
2575
+ def user_cache_dir(self) -> str:
2576
+ """
2577
+ Returns the user cache directory path.
2578
+
2579
+ Returns
2580
+ -------
2581
+ str
2582
+ User cache directory path
2583
+
2584
+ Examples
2585
+ --------
2586
+ >>> app = Pyloid(app_name="Pyloid-App")
2587
+ >>> cache_dir = app.user_cache_dir()
2588
+ >>> print(cache_dir)
2589
+ '/Users/user/Library/Caches/Pyloid-App' # Example for macOS
2590
+ """
2591
+ return self.app.user_cache_dir()
2592
+
2593
+ def user_log_dir(self) -> str:
2594
+ """
2595
+ Returns the user log directory path.
2596
+
2597
+ Returns
2598
+ -------
2599
+ str
2600
+ User log directory path
2601
+
2602
+ Examples
2603
+ --------
2604
+ >>> app = Pyloid(app_name="Pyloid-App")
2605
+ >>> log_dir = app.user_log_dir()
2606
+ >>> print(log_dir)
2607
+ '/Users/user/Library/Logs/Pyloid-App' # Example for macOS
2608
+ """
2609
+ return self.app.user_log_dir()
2610
+
2611
+ def user_documents_dir(self) -> str:
2612
+ """
2613
+ Returns the user documents directory path.
2614
+
2615
+ Returns
2616
+ -------
2617
+ str
2618
+ User documents directory path
2619
+
2620
+ Examples
2621
+ --------
2622
+ >>> app = Pyloid(app_name="Pyloid-App")
2623
+ >>> documents_dir = app.user_documents_dir()
2624
+ >>> print(documents_dir)
2625
+ '/Users/user/Documents' # Example for macOS
2626
+ """
2627
+ return self.app.user_documents_dir()
2628
+
2629
+ def user_downloads_dir(self) -> str:
2630
+ """
2631
+ Returns the user downloads directory path.
2632
+
2633
+ Returns
2634
+ -------
2635
+ str
2636
+ User downloads directory path
2637
+
2638
+ Examples
2639
+ --------
2640
+ >>> app = Pyloid(app_name="Pyloid-App")
2641
+ >>> downloads_dir = app.user_downloads_dir()
2642
+ >>> print(downloads_dir)
2643
+ '/Users/user/Downloads' # Example for macOS
2644
+ """
2645
+ return self.app.user_downloads_dir()
2646
+
2647
+ def user_pictures_dir(self) -> str:
2648
+ """
2649
+ Returns the user pictures directory path.
2650
+
2651
+ Returns
2652
+ -------
2653
+ str
2654
+ User pictures directory path
2655
+
2656
+ Examples
2657
+ --------
2658
+ >>> app = Pyloid(app_name="Pyloid-App")
2659
+ >>> pictures_dir = app.user_pictures_dir()
2660
+ >>> print(pictures_dir)
2661
+ '/Users/user/Pictures' # Example for macOS
2662
+ """
2663
+ return self.app.user_pictures_dir()
2664
+
2665
+ def user_videos_dir(self) -> str:
2666
+ """
2667
+ Returns the user videos directory path.
2668
+
2669
+ Returns
2670
+ -------
2671
+ str
2672
+ User videos directory path
2673
+
2674
+ Examples
2675
+ --------
2676
+ >>> app = Pyloid(app_name="Pyloid-App")
2677
+ >>> videos_dir = app.user_videos_dir()
2678
+ >>> print(videos_dir)
2679
+ '/Users/user/Movies' # Example for macOS
2680
+ """
2681
+ return self.app.user_videos_dir()
2682
+
2683
+ def user_music_dir(self) -> str:
2684
+ """
2685
+ Returns the user music directory path.
2686
+
2687
+ Returns
2688
+ -------
2689
+ str
2690
+ User music directory path
2691
+
2692
+ Examples
2693
+ --------
2694
+ >>> app = Pyloid(app_name="Pyloid-App")
2695
+ >>> music_dir = app.user_music_dir()
2696
+ >>> print(music_dir)
2697
+ '/Users/user/Music' # Example for macOS
2698
+ """
2699
+ return self.app.user_music_dir()
2700
+
2701
+ def user_desktop_dir(self) -> str:
2702
+ """
2703
+ Returns the user desktop directory path.
2704
+
2705
+ Returns
2706
+ -------
2707
+ str
2708
+ User desktop directory path
2709
+
2710
+ Examples
2711
+ --------
2712
+ >>> app = Pyloid(app_name="Pyloid-App")
2713
+ >>> desktop_dir = app.user_desktop_dir()
2714
+ >>> print(desktop_dir)
2715
+ '/Users/user/Desktop' # Example for macOS
2716
+ """
2717
+ return self.app.user_desktop_dir()
2718
+
2719
+ def user_runtime_dir(self) -> str:
2720
+ """
2721
+ Returns the user runtime directory path.
2722
+
2723
+ Returns
2724
+ -------
2725
+ str
2726
+ User runtime directory path
2727
+
2728
+ Examples
2729
+ --------
2730
+ >>> app = Pyloid(app_name="Pyloid-App")
2731
+ >>> runtime_dir = app.user_runtime_dir()
2732
+ >>> print(runtime_dir)
2733
+ '/Users/user/Library/Caches/TemporaryItems/Pyloid-App' # Example for macOS
2734
+ """
2735
+ return self.app.user_runtime_dir()
2736
+
2737
+ # --- Add store wrapper functions ---
2738
+
2739
+ def store(self, path: str, user_data_dir: bool = True) -> Store:
2740
+ """
2741
+ Returns a Store instance for the given path.
2742
+
2743
+ Parameters
2744
+ ----------
2745
+ path : str
2746
+ The path to the store file
2747
+ user_data_dir : bool, optional
2748
+ If True, the store will be created in the user data directory
2749
+
2750
+ Returns
2751
+ -------
2752
+ Store
2753
+ A Store instance for the given path
2754
+
2755
+ Examples
2756
+ --------
2757
+ >>> app = Pyloid(app_name="Pyloid-App")
2758
+ >>> store = app.store("store.json")
2759
+ >>> store.set("key", "value")
2760
+ True
2761
+ >>> print(store.get("key"))
2762
+ 'value'
2763
+ """
2764
+ if user_data_dir:
2765
+ path = os.path.join(self.app.user_data_dir(), path)
2766
+ return Store(path)