pytron-kit 0.3.12__py3-none-win_amd64.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.
Files changed (419) hide show
  1. pytron/__init__.py +112 -0
  2. pytron/application.py +562 -0
  3. pytron/apputils/__init__.py +0 -0
  4. pytron/apputils/chrome_ipc.py +203 -0
  5. pytron/apputils/codegen.py +261 -0
  6. pytron/apputils/config.py +303 -0
  7. pytron/apputils/deadmansswitch.py +47 -0
  8. pytron/apputils/extras.py +76 -0
  9. pytron/apputils/native.py +148 -0
  10. pytron/apputils/shell.py +73 -0
  11. pytron/apputils/windows.py +286 -0
  12. pytron/cli.py +384 -0
  13. pytron/commands/__init__.py +0 -0
  14. pytron/commands/android.py +28 -0
  15. pytron/commands/build.py +26 -0
  16. pytron/commands/doctor.py +221 -0
  17. pytron/commands/engine.py +23 -0
  18. pytron/commands/frontend.py +60 -0
  19. pytron/commands/harvest.py +112 -0
  20. pytron/commands/helpers.py +239 -0
  21. pytron/commands/info.py +50 -0
  22. pytron/commands/init.py +521 -0
  23. pytron/commands/install.py +294 -0
  24. pytron/commands/login.py +130 -0
  25. pytron/commands/package.py +228 -0
  26. pytron/commands/plugin.py +442 -0
  27. pytron/commands/run.py +312 -0
  28. pytron/commands/scan.py +210 -0
  29. pytron/commands/show.py +23 -0
  30. pytron/commands/uninstall.py +150 -0
  31. pytron/commands/utils.py +42 -0
  32. pytron/commands/workflow.py +95 -0
  33. pytron/console.py +133 -0
  34. pytron/core.py +18 -0
  35. pytron/dependencies/WebView2Loader.dll +0 -0
  36. pytron/dependencies/__init__.py +1 -0
  37. pytron/dependencies/pytron_native.pyd +0 -0
  38. pytron/engines/chrome/adapter.py +445 -0
  39. pytron/engines/chrome/engine.py +576 -0
  40. pytron/engines/chrome/forge.py +147 -0
  41. pytron/engines/chrome/shell/package.json +8 -0
  42. pytron/engines/chrome/shell/preload.js +12 -0
  43. pytron/engines/chrome/shell/shell.js +534 -0
  44. pytron/exceptions.py +36 -0
  45. pytron/inspector.py +201 -0
  46. pytron/inspector_ui.py +512 -0
  47. pytron/installer/Installation.nsi +236 -0
  48. pytron/installer/header.bmp +0 -0
  49. pytron/installer/pytron.ico +0 -0
  50. pytron/installer/sidebar.bmp +0 -0
  51. pytron/llms.md +98 -0
  52. pytron/manifests/README.md +29 -0
  53. pytron/manifests/windows-utf8.manifest +44 -0
  54. pytron/menu.py +128 -0
  55. pytron/nsis-setup.exe +0 -0
  56. pytron/pack/__init__.py +0 -0
  57. pytron/pack/assets.py +131 -0
  58. pytron/pack/compilers.py +289 -0
  59. pytron/pack/crystal.py +297 -0
  60. pytron/pack/graph.py +377 -0
  61. pytron/pack/inference.py +157 -0
  62. pytron/pack/installers.py +402 -0
  63. pytron/pack/introspect.py +357 -0
  64. pytron/pack/metadata.py +213 -0
  65. pytron/pack/modules.py +618 -0
  66. pytron/pack/nuitka.py +108 -0
  67. pytron/pack/pipeline.py +107 -0
  68. pytron/pack/pyinstaller.py +176 -0
  69. pytron/pack/rust_engine.py +273 -0
  70. pytron/pack/secure.py +309 -0
  71. pytron/pack/secure_loader/bin/pytron_rust_bootloader.exe +0 -0
  72. pytron/pack/secure_loader/icon.ico +0 -0
  73. pytron/pack/utils.py +110 -0
  74. pytron/pack/virtual_root.py +124 -0
  75. pytron/platforms/__init__.py +0 -0
  76. pytron/platforms/android/__init__.py +3 -0
  77. pytron/platforms/android/android.py +103 -0
  78. pytron/platforms/android/builder.py +736 -0
  79. pytron/platforms/android/ops/build.py +79 -0
  80. pytron/platforms/android/ops/init.py +63 -0
  81. pytron/platforms/android/ops/run.py +79 -0
  82. pytron/platforms/android/ops/sync.py +770 -0
  83. pytron/platforms/android/ops/utils.py +8 -0
  84. pytron/platforms/android/shell/README.md +30 -0
  85. pytron/platforms/android/shell/app/build.gradle +64 -0
  86. pytron/platforms/android/shell/app/src/main/AndroidManifest.xml +29 -0
  87. pytron/platforms/android/shell/app/src/main/assets/python/main.py +86 -0
  88. pytron/platforms/android/shell/app/src/main/assets/python/python314.zip +0 -0
  89. pytron/platforms/android/shell/app/src/main/cpp/CMakeLists.txt +25 -0
  90. pytron/platforms/android/shell/app/src/main/cpp/include/Python.h +155 -0
  91. pytron/platforms/android/shell/app/src/main/cpp/include/abstract.h +915 -0
  92. pytron/platforms/android/shell/app/src/main/cpp/include/audit.h +30 -0
  93. pytron/platforms/android/shell/app/src/main/cpp/include/bltinmodule.h +14 -0
  94. pytron/platforms/android/shell/app/src/main/cpp/include/boolobject.h +54 -0
  95. pytron/platforms/android/shell/app/src/main/cpp/include/bytearrayobject.h +44 -0
  96. pytron/platforms/android/shell/app/src/main/cpp/include/bytesobject.h +66 -0
  97. pytron/platforms/android/shell/app/src/main/cpp/include/ceval.h +145 -0
  98. pytron/platforms/android/shell/app/src/main/cpp/include/codecs.h +176 -0
  99. pytron/platforms/android/shell/app/src/main/cpp/include/compile.h +22 -0
  100. pytron/platforms/android/shell/app/src/main/cpp/include/complexobject.h +30 -0
  101. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/abstract.h +104 -0
  102. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/audit.h +8 -0
  103. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/bytearrayobject.h +38 -0
  104. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/bytesobject.h +42 -0
  105. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/cellobject.h +50 -0
  106. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/ceval.h +43 -0
  107. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/classobject.h +71 -0
  108. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/code.h +340 -0
  109. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/compile.h +50 -0
  110. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/complexobject.h +33 -0
  111. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/context.h +107 -0
  112. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/critical_section.h +154 -0
  113. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/descrobject.h +62 -0
  114. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/dictobject.h +105 -0
  115. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/fileobject.h +16 -0
  116. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/fileutils.h +16 -0
  117. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/floatobject.h +27 -0
  118. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/frameobject.h +35 -0
  119. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/funcobject.h +185 -0
  120. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/genobject.h +56 -0
  121. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/import.h +30 -0
  122. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/initconfig.h +334 -0
  123. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/listobject.h +53 -0
  124. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/lock.h +74 -0
  125. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/longintrepr.h +184 -0
  126. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/longobject.h +89 -0
  127. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/memoryobject.h +50 -0
  128. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/methodobject.h +66 -0
  129. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/modsupport.h +26 -0
  130. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/monitoring.h +269 -0
  131. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/object.h +493 -0
  132. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/objimpl.h +104 -0
  133. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/odictobject.h +43 -0
  134. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/picklebufobject.h +31 -0
  135. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pthread_stubs.h +105 -0
  136. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic.h +614 -0
  137. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_gcc.h +615 -0
  138. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_msc.h +1197 -0
  139. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_std.h +1112 -0
  140. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyctype.h +39 -0
  141. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pydebug.h +38 -0
  142. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyerrors.h +132 -0
  143. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyfpe.h +15 -0
  144. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyframe.h +45 -0
  145. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyhash.h +54 -0
  146. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pylifecycle.h +89 -0
  147. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pymem.h +84 -0
  148. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pystate.h +275 -0
  149. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pystats.h +194 -0
  150. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pythonrun.h +96 -0
  151. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pythread.h +43 -0
  152. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pytime.h +27 -0
  153. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/setobject.h +71 -0
  154. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/traceback.h +13 -0
  155. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/tracemalloc.h +32 -0
  156. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/tupleobject.h +40 -0
  157. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/unicodeobject.h +773 -0
  158. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/warnings.h +20 -0
  159. pytron/platforms/android/shell/app/src/main/cpp/include/cpython/weakrefobject.h +66 -0
  160. pytron/platforms/android/shell/app/src/main/cpp/include/critical_section.h +16 -0
  161. pytron/platforms/android/shell/app/src/main/cpp/include/datetime.h +267 -0
  162. pytron/platforms/android/shell/app/src/main/cpp/include/descrobject.h +100 -0
  163. pytron/platforms/android/shell/app/src/main/cpp/include/dictobject.h +108 -0
  164. pytron/platforms/android/shell/app/src/main/cpp/include/dynamic_annotations.h +499 -0
  165. pytron/platforms/android/shell/app/src/main/cpp/include/enumobject.h +17 -0
  166. pytron/platforms/android/shell/app/src/main/cpp/include/errcode.h +45 -0
  167. pytron/platforms/android/shell/app/src/main/cpp/include/exports.h +105 -0
  168. pytron/platforms/android/shell/app/src/main/cpp/include/fileobject.h +41 -0
  169. pytron/platforms/android/shell/app/src/main/cpp/include/fileutils.h +62 -0
  170. pytron/platforms/android/shell/app/src/main/cpp/include/floatobject.h +54 -0
  171. pytron/platforms/android/shell/app/src/main/cpp/include/frameobject.h +20 -0
  172. pytron/platforms/android/shell/app/src/main/cpp/include/genericaliasobject.h +14 -0
  173. pytron/platforms/android/shell/app/src/main/cpp/include/import.h +103 -0
  174. pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/atomic.h +392 -0
  175. pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/internal.h +969 -0
  176. pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/prim.h +329 -0
  177. pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/track.h +147 -0
  178. pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/types.h +721 -0
  179. pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc.h +565 -0
  180. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_abstract.h +61 -0
  181. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_asdl.h +112 -0
  182. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ast.h +945 -0
  183. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ast_state.h +271 -0
  184. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_atexit.h +31 -0
  185. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_audit.h +35 -0
  186. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_backoff.h +133 -0
  187. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bitutils.h +186 -0
  188. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_blocks_output_buffer.h +321 -0
  189. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_brc.h +73 -0
  190. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bytes_methods.h +82 -0
  191. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bytesobject.h +149 -0
  192. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_c_array.h +39 -0
  193. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_call.h +206 -0
  194. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_capsule.h +17 -0
  195. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_cell.h +75 -0
  196. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ceval.h +390 -0
  197. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ceval_state.h +48 -0
  198. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_code.h +671 -0
  199. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_codecs.h +76 -0
  200. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_compile.h +230 -0
  201. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_complexobject.h +34 -0
  202. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_condvar.h +93 -0
  203. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_context.h +59 -0
  204. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_critical_section.h +237 -0
  205. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_crossinterp.h +406 -0
  206. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_crossinterp_data_registry.h +41 -0
  207. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_debug_offsets.h +379 -0
  208. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_descrobject.h +28 -0
  209. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dict.h +410 -0
  210. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dict_state.h +28 -0
  211. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dtoa.h +40 -0
  212. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_emscripten_signal.h +30 -0
  213. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_emscripten_trampoline.h +70 -0
  214. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_exceptions.h +40 -0
  215. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_faulthandler.h +100 -0
  216. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_fileutils.h +320 -0
  217. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_fileutils_windows.h +98 -0
  218. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_floatobject.h +49 -0
  219. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_flowgraph.h +47 -0
  220. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_format.h +27 -0
  221. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_frame.h +61 -0
  222. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_freelist.h +111 -0
  223. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_freelist_state.h +70 -0
  224. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_function.h +53 -0
  225. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_gc.h +378 -0
  226. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_genobject.h +43 -0
  227. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_getopt.h +22 -0
  228. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_gil.h +66 -0
  229. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_objects.h +34 -0
  230. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_objects_fini_generated.h +1592 -0
  231. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_strings.h +854 -0
  232. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_hamt.h +113 -0
  233. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_hashtable.h +150 -0
  234. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_import.h +141 -0
  235. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_importdl.h +139 -0
  236. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_index_pool.h +36 -0
  237. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_initconfig.h +197 -0
  238. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_instruction_sequence.h +83 -0
  239. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_instruments.h +127 -0
  240. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interp.h +109 -0
  241. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interp_structs.h +977 -0
  242. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpframe.h +401 -0
  243. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpframe_structs.h +95 -0
  244. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpolation.h +26 -0
  245. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_intrinsics.h +51 -0
  246. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_jit.h +29 -0
  247. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_list.h +81 -0
  248. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_llist.h +106 -0
  249. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_lock.h +236 -0
  250. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_long.h +319 -0
  251. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_magic_number.h +305 -0
  252. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_memoryobject.h +20 -0
  253. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_mimalloc.h +69 -0
  254. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_modsupport.h +99 -0
  255. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_moduleobject.h +62 -0
  256. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_namespace.h +21 -0
  257. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object.h +1029 -0
  258. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_alloc.h +71 -0
  259. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_deferred.h +32 -0
  260. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_stack.h +95 -0
  261. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_state.h +49 -0
  262. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_obmalloc.h +702 -0
  263. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_obmalloc_init.h +66 -0
  264. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_opcode_metadata.h +2117 -0
  265. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_opcode_utils.h +90 -0
  266. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_optimizer.h +318 -0
  267. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_parking_lot.h +97 -0
  268. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_parser.h +78 -0
  269. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pathconfig.h +26 -0
  270. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyarena.h +68 -0
  271. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyatomic_ft_wrappers.h +174 -0
  272. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pybuffer.h +21 -0
  273. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyerrors.h +213 -0
  274. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyhash.h +91 -0
  275. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pylifecycle.h +136 -0
  276. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymath.h +205 -0
  277. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymem.h +145 -0
  278. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymem_init.h +103 -0
  279. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pystate.h +339 -0
  280. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pystats.h +21 -0
  281. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pythonrun.h +68 -0
  282. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pythread.h +172 -0
  283. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_qsbr.h +172 -0
  284. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_range.h +21 -0
  285. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime.h +63 -0
  286. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_init.h +239 -0
  287. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_init_generated.h +1589 -0
  288. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_structs.h +310 -0
  289. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_semaphore.h +67 -0
  290. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_setobject.h +41 -0
  291. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_signal.h +108 -0
  292. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_sliceobject.h +20 -0
  293. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_stackref.h +791 -0
  294. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_stats.h +97 -0
  295. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_strhex.h +39 -0
  296. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_structs.h +88 -0
  297. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_structseq.h +40 -0
  298. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_symtable.h +201 -0
  299. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_sysmodule.h +32 -0
  300. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_template.h +26 -0
  301. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_time.h +334 -0
  302. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_token.h +110 -0
  303. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_traceback.h +111 -0
  304. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tracemalloc.h +164 -0
  305. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tstate.h +88 -0
  306. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tuple.h +75 -0
  307. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typedefs.h +18 -0
  308. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typeobject.h +155 -0
  309. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typevarobject.h +28 -0
  310. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ucnhash.h +36 -0
  311. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unicodeobject.h +308 -0
  312. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unicodeobject_generated.h +3132 -0
  313. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unionobject.h +26 -0
  314. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uniqueid.h +57 -0
  315. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uop_ids.h +335 -0
  316. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uop_metadata.h +1204 -0
  317. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_warnings.h +21 -0
  318. pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_weakref.h +133 -0
  319. pytron/platforms/android/shell/app/src/main/cpp/include/intrcheck.h +23 -0
  320. pytron/platforms/android/shell/app/src/main/cpp/include/iterobject.h +24 -0
  321. pytron/platforms/android/shell/app/src/main/cpp/include/listobject.h +55 -0
  322. pytron/platforms/android/shell/app/src/main/cpp/include/lock.h +16 -0
  323. pytron/platforms/android/shell/app/src/main/cpp/include/longobject.h +178 -0
  324. pytron/platforms/android/shell/app/src/main/cpp/include/marshal.h +31 -0
  325. pytron/platforms/android/shell/app/src/main/cpp/include/memoryobject.h +34 -0
  326. pytron/platforms/android/shell/app/src/main/cpp/include/methodobject.h +146 -0
  327. pytron/platforms/android/shell/app/src/main/cpp/include/modsupport.h +146 -0
  328. pytron/platforms/android/shell/app/src/main/cpp/include/moduleobject.h +122 -0
  329. pytron/platforms/android/shell/app/src/main/cpp/include/monitoring.h +18 -0
  330. pytron/platforms/android/shell/app/src/main/cpp/include/object.h +828 -0
  331. pytron/platforms/android/shell/app/src/main/cpp/include/objimpl.h +211 -0
  332. pytron/platforms/android/shell/app/src/main/cpp/include/opcode.h +43 -0
  333. pytron/platforms/android/shell/app/src/main/cpp/include/opcode_ids.h +259 -0
  334. pytron/platforms/android/shell/app/src/main/cpp/include/osdefs.h +57 -0
  335. pytron/platforms/android/shell/app/src/main/cpp/include/osmodule.h +17 -0
  336. pytron/platforms/android/shell/app/src/main/cpp/include/patchlevel.h +49 -0
  337. pytron/platforms/android/shell/app/src/main/cpp/include/py_curses.h +117 -0
  338. pytron/platforms/android/shell/app/src/main/cpp/include/pyatomic.h +16 -0
  339. pytron/platforms/android/shell/app/src/main/cpp/include/pybuffer.h +145 -0
  340. pytron/platforms/android/shell/app/src/main/cpp/include/pycapsule.h +58 -0
  341. pytron/platforms/android/shell/app/src/main/cpp/include/pyconfig.h +2088 -0
  342. pytron/platforms/android/shell/app/src/main/cpp/include/pydtrace.h +59 -0
  343. pytron/platforms/android/shell/app/src/main/cpp/include/pyerrors.h +335 -0
  344. pytron/platforms/android/shell/app/src/main/cpp/include/pyexpat.h +62 -0
  345. pytron/platforms/android/shell/app/src/main/cpp/include/pyframe.h +26 -0
  346. pytron/platforms/android/shell/app/src/main/cpp/include/pyhash.h +59 -0
  347. pytron/platforms/android/shell/app/src/main/cpp/include/pylifecycle.h +80 -0
  348. pytron/platforms/android/shell/app/src/main/cpp/include/pymacconfig.h +91 -0
  349. pytron/platforms/android/shell/app/src/main/cpp/include/pymacro.h +243 -0
  350. pytron/platforms/android/shell/app/src/main/cpp/include/pymath.h +65 -0
  351. pytron/platforms/android/shell/app/src/main/cpp/include/pymem.h +110 -0
  352. pytron/platforms/android/shell/app/src/main/cpp/include/pyport.h +710 -0
  353. pytron/platforms/android/shell/app/src/main/cpp/include/pystate.h +132 -0
  354. pytron/platforms/android/shell/app/src/main/cpp/include/pystats.h +28 -0
  355. pytron/platforms/android/shell/app/src/main/cpp/include/pystrcmp.h +23 -0
  356. pytron/platforms/android/shell/app/src/main/cpp/include/pystrtod.h +37 -0
  357. pytron/platforms/android/shell/app/src/main/cpp/include/pythonrun.h +42 -0
  358. pytron/platforms/android/shell/app/src/main/cpp/include/pythread.h +131 -0
  359. pytron/platforms/android/shell/app/src/main/cpp/include/pytypedefs.h +30 -0
  360. pytron/platforms/android/shell/app/src/main/cpp/include/rangeobject.h +27 -0
  361. pytron/platforms/android/shell/app/src/main/cpp/include/refcount.h +555 -0
  362. pytron/platforms/android/shell/app/src/main/cpp/include/setobject.h +49 -0
  363. pytron/platforms/android/shell/app/src/main/cpp/include/sliceobject.h +69 -0
  364. pytron/platforms/android/shell/app/src/main/cpp/include/structmember.h +56 -0
  365. pytron/platforms/android/shell/app/src/main/cpp/include/structseq.h +46 -0
  366. pytron/platforms/android/shell/app/src/main/cpp/include/sysmodule.h +27 -0
  367. pytron/platforms/android/shell/app/src/main/cpp/include/traceback.h +26 -0
  368. pytron/platforms/android/shell/app/src/main/cpp/include/tupleobject.h +46 -0
  369. pytron/platforms/android/shell/app/src/main/cpp/include/typeslots.h +96 -0
  370. pytron/platforms/android/shell/app/src/main/cpp/include/unicodeobject.h +1029 -0
  371. pytron/platforms/android/shell/app/src/main/cpp/include/warnings.h +45 -0
  372. pytron/platforms/android/shell/app/src/main/cpp/include/weakrefobject.h +46 -0
  373. pytron/platforms/android/shell/app/src/main/cpp/pytron_bridge.cpp +224 -0
  374. pytron/platforms/android/shell/app/src/main/java/com/pytron/shell/MainActivity.kt +208 -0
  375. pytron/platforms/android/shell/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  376. pytron/platforms/android/shell/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  377. pytron/platforms/android/shell/build.gradle +11 -0
  378. pytron/platforms/android/shell/gradle/wrapper/gradle-wrapper.jar +0 -0
  379. pytron/platforms/android/shell/gradle/wrapper/gradle-wrapper.properties +5 -0
  380. pytron/platforms/android/shell/gradle.properties +2 -0
  381. pytron/platforms/android/shell/gradlew.bat +85 -0
  382. pytron/platforms/android/shell/settings.gradle +16 -0
  383. pytron/platforms/darwin.py +82 -0
  384. pytron/platforms/darwin_ops/libs.py +31 -0
  385. pytron/platforms/darwin_ops/system.py +182 -0
  386. pytron/platforms/darwin_ops/utils.py +85 -0
  387. pytron/platforms/darwin_ops/webview.py +5 -0
  388. pytron/platforms/darwin_ops/window.py +102 -0
  389. pytron/platforms/interface.py +152 -0
  390. pytron/platforms/linux.py +82 -0
  391. pytron/platforms/linux_ops/libs.py +49 -0
  392. pytron/platforms/linux_ops/system.py +316 -0
  393. pytron/platforms/linux_ops/utils.py +19 -0
  394. pytron/platforms/linux_ops/webview.py +5 -0
  395. pytron/platforms/linux_ops/window.py +115 -0
  396. pytron/platforms/windows.py +136 -0
  397. pytron/platforms/windows_ops/__init__.py +0 -0
  398. pytron/platforms/windows_ops/constants.py +126 -0
  399. pytron/platforms/windows_ops/system.py +518 -0
  400. pytron/platforms/windows_ops/utils.py +3 -0
  401. pytron/platforms/windows_ops/webview.py +5 -0
  402. pytron/platforms/windows_ops/window.py +361 -0
  403. pytron/plugin.py +467 -0
  404. pytron/rcedit-x64.exe +0 -0
  405. pytron/router.py +146 -0
  406. pytron/serializer.py +240 -0
  407. pytron/shortcuts.py +279 -0
  408. pytron/state.py +76 -0
  409. pytron/tray.py +399 -0
  410. pytron/updater.py +181 -0
  411. pytron/utf8_hook.py +112 -0
  412. pytron/utils.py +44 -0
  413. pytron/webview.py +722 -0
  414. pytron_kit-0.3.12.dist-info/METADATA +131 -0
  415. pytron_kit-0.3.12.dist-info/RECORD +419 -0
  416. pytron_kit-0.3.12.dist-info/WHEEL +5 -0
  417. pytron_kit-0.3.12.dist-info/entry_points.txt +2 -0
  418. pytron_kit-0.3.12.dist-info/licenses/LICENSE +201 -0
  419. pytron_kit-0.3.12.dist-info/top_level.txt +1 -0
@@ -0,0 +1,303 @@
1
+ import os
2
+ import sys
3
+ import json
4
+ import logging
5
+ from ..utils import get_resource_path
6
+ from ..exceptions import ConfigError
7
+
8
+
9
+ class ConfigMixin:
10
+ def _setup_logging(self):
11
+ # If we use basicConfig, it might interfere with user's settings.
12
+ # But for a simple CLI tool, it's often preferred.
13
+ # Let's check if the root logger has any handlers already.
14
+ if not logging.root.handlers:
15
+ logging.basicConfig(
16
+ level=logging.INFO,
17
+ format="[Pytron] %(asctime)s - %(levelname)s - %(message)s",
18
+ datefmt="%H:%M:%S",
19
+ )
20
+ self.logger = logging.getLogger("Pytron")
21
+
22
+ def _check_deep_link(self):
23
+ self.state.launch_url = None
24
+ # Scan all args for a possible deep link (some OS pass it at different positions)
25
+ # or it might be preceded by flags.
26
+ for arg in sys.argv[1:]:
27
+ if arg.startswith("pytron:") or "://" in arg:
28
+ # Basic validation: ensure it's not a local file path with :// (unlikely on Win)
29
+ if ":" in arg and not os.path.exists(arg):
30
+ self.logger.info(f"App launched via Deep Link: {arg}")
31
+ self.state.launch_url = arg
32
+ break
33
+ # Defer dispatch to run-time if needed, but since plugins/handlers
34
+ # might be registered AFTER init, we might need to handle this carefully.
35
+ # However, for now, we'll store it. The handlers usually aren't registered
36
+ # until the user script runs.
37
+ # So we should probably dispatch in app.run().
38
+
39
+ def _load_config(self, config_file):
40
+ self.config = {}
41
+ path = get_resource_path(config_file)
42
+ self.logger.debug(f"Resolved settings path: {path}")
43
+
44
+ if not os.path.exists(path):
45
+ path = os.path.abspath(config_file)
46
+
47
+ if os.path.exists(path):
48
+ try:
49
+ with open(path, "r") as f:
50
+ self.config = json.load(f)
51
+
52
+ if self.config.get("debug", False):
53
+ self.logger.setLevel(logging.DEBUG)
54
+ for handler in logging.root.handlers:
55
+ handler.setLevel(logging.DEBUG)
56
+ self.logger.debug("Debug mode enabled.")
57
+
58
+ dev_url = os.environ.get("PYTRON_DEV_URL")
59
+ if dev_url:
60
+ self.config["url"] = dev_url
61
+ self.logger.info(f"Dev mode: Overriding URL to {dev_url}")
62
+
63
+ config_version = self.config.get("pytron_version")
64
+ if config_version:
65
+ try:
66
+ from .. import __version__
67
+
68
+ if config_version != __version__:
69
+ self.logger.warning(
70
+ f"Version mismatch: Settings({config_version}) vs Installed({__version__})"
71
+ )
72
+ except ImportError:
73
+ pass
74
+ except json.JSONDecodeError as e:
75
+ self.logger.error(f"Failed to parse settings.json: {e}")
76
+ raise ConfigError(f"Invalid JSON in settings file: {path}") from e
77
+ except Exception as e:
78
+ self.logger.error(f"Failed to load settings: {e}")
79
+ raise ConfigError(f"Could not load settings from {path}") from e
80
+ else:
81
+ self.logger.warning(
82
+ f"Settings file not found at {path}. Using default configuration."
83
+ )
84
+
85
+ def _setup_identity(self):
86
+ title = self.config.get("title", "Pytron App")
87
+ safe_title = "".join(
88
+ c if c.isalnum() or c in ("-", "_") else "_" for c in title
89
+ ).strip("_")
90
+ app_id = self._register_app_id(title, safe_title)
91
+
92
+ # Single Instance Guard
93
+ if self.config.get("single_instance", True):
94
+ self._setup_single_instance(app_id)
95
+
96
+ return title, safe_title
97
+
98
+ def _register_app_id(self, title, safe_title):
99
+ author = self.config.get("author", "PytronUser")
100
+ if not safe_title:
101
+ safe_title = (
102
+ "".join([c for c in (title or "Pytron") if c.isalnum()]) or "PytronApp"
103
+ )
104
+ app_id = f"{author}.{safe_title}.App"
105
+
106
+ if sys.platform == "win32" and getattr(sys, "frozen", False):
107
+ try:
108
+ from ..platforms.windows import WindowsImplementation
109
+
110
+ WindowsImplementation().set_app_id(app_id)
111
+ self.logger.debug(f"Set Windows AppUserModelID: {app_id}")
112
+ except Exception as e:
113
+ self.logger.debug(f"Failed to set App ID: {e}")
114
+ elif sys.platform == "linux":
115
+ try:
116
+ from ..platforms.linux import LinuxImplementation
117
+
118
+ LinuxImplementation().set_app_id(safe_title)
119
+ except Exception as e:
120
+ self.logger.debug(f"Failed to set Linux App ID: {e}")
121
+ elif sys.platform == "darwin":
122
+ try:
123
+ from ..platforms.darwin import DarwinImplementation
124
+
125
+ DarwinImplementation().set_app_id(title)
126
+ except Exception as e:
127
+ self.logger.debug(f"Failed to set Darwin App ID: {e}")
128
+ return app_id
129
+
130
+ def _setup_single_instance(self, app_id):
131
+ import socket
132
+ import hashlib
133
+ import threading
134
+ import os
135
+
136
+ # Skip during tests and development as they often require flexibility
137
+ if "PYTEST_CURRENT_TEST" in os.environ or not getattr(sys, "frozen", False):
138
+ return
139
+
140
+ # Generate a stable port between 10000-60000 based on app_id
141
+ # B324: Use SHA256 instead of MD5 for port generation stability
142
+ port = 10000 + (int(hashlib.sha256(app_id.encode()).hexdigest(), 16) % 50000)
143
+ self._instance_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
144
+
145
+ try:
146
+ self._instance_socket.bind(("127.0.0.1", port))
147
+ self._instance_socket.listen(1)
148
+
149
+ def _listen_for_other_instances():
150
+ while True:
151
+ try:
152
+ conn, _ = self._instance_socket.accept()
153
+ data = conn.recv(1024).decode("utf-8")
154
+ if data:
155
+ msg = json.loads(data)
156
+ url = msg.get("url")
157
+ if url:
158
+ self.logger.info(
159
+ f"Received deep link from another instance: {url}"
160
+ )
161
+ # Update launch URL and show windows
162
+ self.state.launch_url = url
163
+ self.router.dispatch(url)
164
+ for window in self.windows:
165
+ window.show()
166
+ window.emit("pytron:deep-link", {"url": url})
167
+ conn.close()
168
+ except Exception:
169
+ break
170
+
171
+ t = threading.Thread(target=_listen_for_other_instances, daemon=True)
172
+ t.start()
173
+
174
+ @self.on_exit
175
+ def _close_instance_socket():
176
+ try:
177
+ self._instance_socket.close()
178
+ except Exception as e:
179
+ self.logger.debug(f"Error closing instance socket: {e}")
180
+
181
+ except socket.error:
182
+ # Instance already running!
183
+ self.logger.info(
184
+ "Another instance is already running. Forwarding launch URL and exiting."
185
+ )
186
+ try:
187
+ client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
188
+ client.connect(("127.0.0.1", port))
189
+ client.send(json.dumps({"url": self.state.launch_url}).encode("utf-8"))
190
+ client.close()
191
+ except Exception:
192
+ pass
193
+ # Critical: Use os._exit(0) instead of sys.exit(0)
194
+ # sys.exit() raises SystemExit, which can be caught by the bootstrap wrapper
195
+ # or Cython, leading to a false positive "Shield Error".
196
+ # os._exit() terminates immediately at the OS level, which is safe here
197
+ # because we want to vanish instantly after forwarding the intent.
198
+ os._exit(0)
199
+
200
+ def _setup_storage(self, safe_title):
201
+ if sys.platform == "win32":
202
+ base_path = os.environ.get("LOCALAPPDATA", os.path.expanduser("~"))
203
+ elif os.environ.get("PYTHON_PLATFORM") == "android":
204
+ python_home = os.environ.get("PYTHONHOME")
205
+ if python_home:
206
+ base_path = os.path.dirname(python_home)
207
+ else:
208
+ base_path = os.path.expanduser("~")
209
+ else:
210
+ base_path = os.path.expanduser("~/.config")
211
+
212
+ self.storage_path = os.path.join(base_path, safe_title)
213
+
214
+ if getattr(sys, "frozen", False):
215
+ self.app_root = os.path.dirname(os.path.abspath(sys.executable))
216
+ else:
217
+ # Better way to find app root than os.getcwd() which depends on where user ran Python
218
+ main_module = sys.modules.get("__main__")
219
+ if main_module and hasattr(main_module, "__file__"):
220
+ self.app_root = os.path.dirname(os.path.abspath(main_module.__file__))
221
+ else:
222
+ self.app_root = os.path.abspath(
223
+ sys.path[0] if sys.path and sys.path[0] else os.getcwd()
224
+ )
225
+
226
+ try:
227
+ os.makedirs(self.storage_path, exist_ok=True)
228
+ if getattr(sys, "frozen", False):
229
+ os.chdir(self.storage_path)
230
+ self.logger.info(f"Changed Working Directory to: {self.storage_path}")
231
+ else:
232
+ self.logger.debug(
233
+ f"Dev Mode: Storage directory ready at {self.storage_path}"
234
+ )
235
+ except Exception as e:
236
+ self.logger.warning(
237
+ f"Could not create storage directory at {self.storage_path}: {e}"
238
+ )
239
+
240
+ def _resolve_resources(self):
241
+ def resolve_resource(path):
242
+ if (
243
+ not path
244
+ or path.startswith(("http:", "https:", "file:"))
245
+ or os.path.isabs(path)
246
+ ):
247
+ return path
248
+
249
+ internal = os.path.join(self.app_root, "_internal", path)
250
+ if os.path.exists(internal):
251
+ return internal
252
+
253
+ candidate = os.path.join(self.app_root, path)
254
+ if os.path.exists(candidate):
255
+ return candidate
256
+
257
+ return get_resource_path(path)
258
+
259
+ if "url" in self.config:
260
+ self.config["url"] = resolve_resource(self.config["url"])
261
+
262
+ if "icon" in self.config:
263
+ orig_icon = self.config["icon"]
264
+ resolved_icon = resolve_resource(orig_icon)
265
+ if os.path.exists(resolved_icon):
266
+ self.config["icon"] = resolved_icon
267
+ self.logger.info(f"Resolved icon to: {resolved_icon}")
268
+ else:
269
+ self.logger.warning(f"Could not find icon at: {orig_icon}")
270
+
271
+ def _setup_key_value_store(self):
272
+ self._store_file = os.path.join(self.storage_path, "store.json")
273
+ self._kv_store = {}
274
+ if os.path.exists(self._store_file):
275
+ try:
276
+ with open(self._store_file, "r") as f:
277
+ self._kv_store = json.load(f)
278
+ except Exception as e:
279
+ self.logger.warning(f"Failed to load persistent store: {e}")
280
+
281
+ def store_set(self, key, value):
282
+ """Sets a value in the persistent store."""
283
+ self._kv_store[key] = value
284
+ self._save_store()
285
+
286
+ def store_get(self, key, default=None):
287
+ """Gets a value from the persistent store."""
288
+ return self._kv_store.get(key, default)
289
+
290
+ def store_delete(self, key):
291
+ """Removes a key from the persistent store."""
292
+ if key in self._kv_store:
293
+ del self._kv_store[key]
294
+ self._save_store()
295
+ return True
296
+ return False
297
+
298
+ def _save_store(self):
299
+ try:
300
+ with open(self._store_file, "w") as f:
301
+ json.dump(self._kv_store, f)
302
+ except Exception as e:
303
+ self.logger.error(f"Failed to save persistent store: {e}")
@@ -0,0 +1,47 @@
1
+ import time
2
+ import os
3
+ import threading
4
+ import logging
5
+
6
+
7
+ class DeadMansSwitch:
8
+ """
9
+ Ensures that if the UI process (Child) dies, the Backend (Parent) commits seppuku immediately.
10
+ Preventing zombie python processes in the background.
11
+ """
12
+
13
+ def __init__(self, ui_process):
14
+ """
15
+ ui_process: The subprocess.Popen object of electron.exe or webview
16
+ """
17
+ self.proc = ui_process
18
+ self.running = True
19
+ self.logger = logging.getLogger("Pytron.DeadMansSwitch")
20
+ self._thread = threading.Thread(target=self._monitor, daemon=True)
21
+ self._thread.start()
22
+
23
+ def _monitor(self):
24
+ while self.running:
25
+ try:
26
+ # 1. Check if Child (UI) is alive
27
+ if self.proc.poll() is not None:
28
+ self.logger.warning(
29
+ f"UI Process {self.proc.pid} died. Exiting backend..."
30
+ )
31
+ self.kill_backend()
32
+
33
+ # 2. Check if Parent (Launcher) is alive
34
+ # (Only needed if Pytron itself is launched by another tool)
35
+ # if os.getppid() == 1: # On Linux, adopted by init
36
+ # self.kill_backend()
37
+
38
+ time.sleep(1) # Low overhead polling
39
+ except Exception:
40
+ # If we can't poll, something is wrong
41
+ self.kill_backend()
42
+
43
+ def kill_backend(self):
44
+ self.running = False
45
+ self.logger.critical("Dead Man's Switch Triggered.")
46
+ # Hard exit to ensure we don't hang on cleanup
47
+ os._exit(0)
@@ -0,0 +1,76 @@
1
+ import os
2
+ from ..tray import SystemTray
3
+
4
+
5
+ class ExtrasMixin:
6
+ def load_plugin(self, manifest_path):
7
+ from ..plugin import Plugin, PluginError
8
+
9
+ try:
10
+ plugin = Plugin(manifest_path)
11
+ plugin.check_dependencies()
12
+ plugin.load(self)
13
+ self.plugins.append(plugin)
14
+ self.logger.info(f"Loaded plugin: {plugin.name} v{plugin.version}")
15
+ except PluginError as e:
16
+ self.logger.error(f"Failed to load plugin from {manifest_path}: {e}")
17
+ except Exception as e:
18
+ self.logger.error(
19
+ f"Unexpected error loading plugin from {manifest_path}: {e}"
20
+ )
21
+
22
+ def setup_tray(self, title=None, icon=None):
23
+ if not title:
24
+ title = self.config.get("title", "Pytron")
25
+ if not icon and "icon" in self.config:
26
+ icon = self.config["icon"]
27
+ if icon and not os.path.isabs(icon):
28
+ icon = os.path.join(self.app_root, icon)
29
+ self.tray = SystemTray(title, icon)
30
+ return self.tray
31
+
32
+ def setup_tray_standard(self, title=None, icon=None):
33
+ # Native Engine Check
34
+ if hasattr(self, "engine") and self.engine == "native":
35
+ # We assume window 0 is main.
36
+ # If windows aren't created yet, we can't create tray on native easily unless we cache it.
37
+ # But setup_tray is usually called before run().
38
+ # The native tray requires the event loop (which starts in run()).
39
+ # So we should queue this creation?
40
+ # Or we leverage the fact that user calls `app.setup_tray` then `app.run`.
41
+ # `app.run` calls `self.windows[0].start()`.
42
+ # `webview.py` start connects bindings.
43
+
44
+ # The best way is to let `webview.create_tray` happen AFTER run starts?
45
+ # No, `create_tray` sends an event. If loop not started, event is lost or queued?
46
+ # `EventLoopProxy` can send events before run? Yes, usually.
47
+
48
+ if not title:
49
+ title = self.config.get("title", "Pytron")
50
+ if not icon:
51
+ icon = self.config.get("icon")
52
+ if icon and not os.path.isabs(icon):
53
+ icon = os.path.join(self.app_root, icon)
54
+
55
+ # We defer this to the first window's initialization if possible, or sets a config?
56
+ # Actually, if we just call it on the window instance, and the window exists...
57
+ # app.windows is empty at setup time usually?
58
+ # In `app.py`: `app = App(...)`, `app.create_window(...)`, `app.setup_tray...`
59
+ # If create_window already added to self.windows, then yes.
60
+
61
+ if self.windows:
62
+ try:
63
+ self.windows[0].create_tray(icon, title)
64
+ self.logger.info("Used Native Tray integration.")
65
+ # Enable Close-to-Tray for standard tray setup
66
+ self.windows[0].config["close_to_tray"] = True
67
+ return None
68
+ except Exception as e:
69
+ self.logger.warning(f"Native Tray failed, falling back: {e}")
70
+
71
+ tray = self.setup_tray(title, icon)
72
+ tray.add_item("Show App", self.show)
73
+ tray.add_item("Hide App", self.hide)
74
+ tray.add_separator()
75
+ tray.add_item("Quit", self.quit)
76
+ return tray
@@ -0,0 +1,148 @@
1
+ import sys
2
+ import os
3
+ from typing import Optional
4
+
5
+
6
+ class NativeMixin:
7
+ """
8
+ Mixin class to handle native system interactions.
9
+ """
10
+
11
+ def set_start_on_boot(self, enable=True):
12
+ """
13
+ Enables or disables automatic application startup on system boot.
14
+ """
15
+ app_name = self.config.get("title", "PytronApp")
16
+ # Sanitize for registry key
17
+ safe_name = "".join(c if c.isalnum() else "_" for c in app_name)
18
+
19
+ if not getattr(sys, "frozen", False):
20
+ self.logger.info("Skipping Start-on-Boot registration in Development Mode.")
21
+ return False
22
+
23
+ exe_path = f'"{sys.executable}"' # Quote for safety
24
+
25
+ # We need a platform instance.
26
+ # Since App doesn't hold it, we instantiate temporarily or grab from first window
27
+ if self.windows:
28
+ # Best effort
29
+ try:
30
+ return self.windows[0]._platform.set_launch_on_boot(
31
+ safe_name, exe_path, enable
32
+ )
33
+ except Exception as e:
34
+ self.logger.debug(f"Failed to set start on boot via window: {e}")
35
+
36
+ # Fallback if no window yet or needed
37
+ try:
38
+ import platform
39
+
40
+ sys_plat = platform.system()
41
+ impl = None
42
+ if sys_plat == "Windows":
43
+ from ..platforms.windows import WindowsImplementation
44
+
45
+ impl = WindowsImplementation()
46
+ elif sys_plat == "Linux":
47
+ from ..platforms.linux import LinuxImplementation
48
+
49
+ impl = LinuxImplementation()
50
+ elif sys_plat == "Darwin":
51
+ from ..platforms.darwin import DarwinImplementation
52
+
53
+ impl = DarwinImplementation()
54
+
55
+ if impl:
56
+ return impl.set_launch_on_boot(safe_name, exe_path, enable)
57
+ except Exception as e:
58
+ self.logger.warning(f"Could not set start on boot: {e}")
59
+
60
+ def message_box(self, title, message, style=0):
61
+ """
62
+ Shows a native message box.
63
+ Styles: 0=OK, 1=OK/Cancel, 2=Abort/Retry/Ignore, 3=Yes/No/Cancel, 4=Yes/No, 5=Retry/Cancel
64
+ Returns: 1=OK, 2=Cancel, 6=Yes, 7=No
65
+ """
66
+ if self.windows:
67
+ return self.windows[0].message_box(title, message, style)
68
+ return 0
69
+
70
+ def dialog_save_file(
71
+ self, title="Save File", default_path=None, default_name=None, file_types=None
72
+ ):
73
+ """Opens a native save file dialog. Returns the selected path or None."""
74
+ if self.windows:
75
+ return self.windows[0].dialog_save_file(
76
+ title, default_path, default_name, file_types
77
+ )
78
+ return None
79
+
80
+ def dialog_open_file(self, title="Open File", default_path=None, file_types=None):
81
+ """Opens a native file selection dialog. Returns the selected path or None."""
82
+ if self.windows:
83
+ return self.windows[0].dialog_open_file(title, default_path, file_types)
84
+ return None
85
+
86
+ def dialog_open_folder(self, title="Select Folder", default_path=None):
87
+ """Opens a native folder selection dialog. Returns the selected path or None."""
88
+ if self.windows:
89
+ return self.windows[0].dialog_open_folder(title, default_path)
90
+ return None
91
+
92
+ def system_notification(self, title: Optional[str] = None, message: str = ""):
93
+ """Sends a system-level (tray/toast) notification via the OS."""
94
+ if not title:
95
+ title = self.config.get("author", self.config.get("title", "Pytron"))
96
+
97
+ icon = self.config.get("icon")
98
+
99
+ if self.windows:
100
+ for window in self.windows:
101
+ try:
102
+ window.system_notification(title, message, icon=icon)
103
+ break
104
+ except Exception as e:
105
+ self.logger.debug(
106
+ f"Failed to send notification via window {window}: {e}"
107
+ )
108
+
109
+ def copy_to_clipboard(self, text: str):
110
+ """Copies text to the system clipboard."""
111
+ if self.windows:
112
+ return self.windows[0]._platform.set_clipboard_text(text)
113
+ return False
114
+
115
+ def get_clipboard_text(self):
116
+ """Returns text from the system clipboard."""
117
+ if self.windows:
118
+ return self.windows[0]._platform.get_clipboard_text()
119
+ return None
120
+
121
+ def get_system_info(self):
122
+ """Returns hardware and OS information."""
123
+ if self.windows:
124
+ return self.windows[0]._platform.get_system_info()
125
+
126
+ # Fallback if no window
127
+ import platform
128
+
129
+ return {"os": platform.system(), "arch": platform.machine()}
130
+
131
+ def store_set(self, key: str, value):
132
+ """Persists a value to the app's local storage."""
133
+ # Fix recursion: This was incorrectly calling self.store_set instead of the ConfigMixin implementation
134
+ if hasattr(super(), "store_set"):
135
+ return super().store_set(key, value)
136
+ return False
137
+
138
+ def store_get(self, key: str, default=None):
139
+ """Retrieves a persisted value from the app's local storage."""
140
+ if hasattr(super(), "store_get"):
141
+ return super().store_get(key, default)
142
+ return default
143
+
144
+ def store_delete(self, key: str):
145
+ """Removes a persisted value."""
146
+ if hasattr(super(), "store_delete"):
147
+ return super().store_delete(key)
148
+ return False
@@ -0,0 +1,73 @@
1
+ import os
2
+ import subprocess
3
+ import platform
4
+
5
+ import shutil
6
+
7
+
8
+ class Shell:
9
+ """
10
+ Native OS Shell utilities for Pytron.
11
+ """
12
+
13
+ @staticmethod
14
+ def _resolve_bin(bin_name):
15
+ return shutil.which(bin_name) or bin_name
16
+
17
+ @staticmethod
18
+ def open_external(url: str):
19
+ """
20
+ Opens a URL or file path in the default system browser/handler.
21
+ """
22
+ if platform.system() == "Windows":
23
+ os.startfile(url)
24
+ elif platform.system() == "Darwin":
25
+ bin_path = Shell._resolve_bin("open")
26
+ subprocess.run([bin_path, url])
27
+ else:
28
+ bin_path = Shell._resolve_bin("xdg-open")
29
+ subprocess.run([bin_path, url])
30
+
31
+ @staticmethod
32
+ def show_item_in_folder(path: str):
33
+ """
34
+ Opens the folder containing the file and selects it.
35
+ """
36
+ path = os.path.abspath(path)
37
+ if platform.system() == "Windows":
38
+ bin_path = Shell._resolve_bin("explorer")
39
+ subprocess.run([bin_path, "/select,", path])
40
+ elif platform.system() == "Darwin":
41
+ bin_path = Shell._resolve_bin("open")
42
+ subprocess.run([bin_path, "-R", path])
43
+ else:
44
+ # Linux doesn't have a universal 'select' but we can open the dir
45
+ bin_path = Shell._resolve_bin("xdg-open")
46
+ subprocess.run([bin_path, os.path.dirname(path)])
47
+
48
+ @staticmethod
49
+ def trash_item(path: str):
50
+ """
51
+ Moves a file to the system trash/recycle bin.
52
+ Requires 'send2trash' library if available, else fails.
53
+ """
54
+ try:
55
+ import logging
56
+
57
+ logger = logging.getLogger("Pytron.Shell")
58
+ from send2trash import send2trash
59
+
60
+ send2trash(path)
61
+ return True
62
+ except ImportError:
63
+ import logging
64
+
65
+ logging.getLogger("Pytron.Shell").warning(
66
+ "send2trash is not installed. File cannot be moved to trash."
67
+ )
68
+ return False
69
+ except Exception as e:
70
+ import logging
71
+
72
+ logging.getLogger("Pytron.Shell").error(f"Failed to trash item: {e}")
73
+ return False