pytron-kit 0.3.12__py3-none-macosx_11_0_universal2.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.so +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 +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
pytron/tray.py ADDED
@@ -0,0 +1,399 @@
1
+ import os
2
+ import sys
3
+ import ctypes
4
+ import threading
5
+ import logging
6
+ from typing import Callable, List, Optional
7
+ from .utils import get_resource_path
8
+
9
+ # Platform-specific imports
10
+ if sys.platform == "win32":
11
+ import ctypes.wintypes
12
+ from .platforms.windows_ops.constants import NOTIFYICONDATAW
13
+
14
+ # Windows Constants
15
+ WM_USER = 0x0400
16
+ WM_TRAYICON = WM_USER + 1
17
+ NIM_ADD = 0x00
18
+ NIM_MODIFY = 0x01
19
+ NIM_DELETE = 0x02
20
+ NIF_ICON = 0x01
21
+ NIF_MESSAGE = 0x02
22
+ NIF_TIP = 0x04
23
+ NIF_INFO = 0x10
24
+ WM_LBUTTONUP = 0x0202
25
+ WM_RBUTTONUP = 0x0205
26
+ WM_CONTEXTMENU = 0x007B
27
+ TPM_LEFTALIGN = 0x0000
28
+ TPM_RIGHTBUTTON = 0x0002
29
+ MIIM_ID = 0x0002
30
+ MIIM_TYPE = 0x0010
31
+ MIIM_DATA = 0x0020
32
+ MFT_STRING = 0x0000
33
+ MFT_SEPARATOR = 0x0800
34
+
35
+
36
+ class MenuItem:
37
+ def __init__(
38
+ self,
39
+ label: str,
40
+ callback: Optional[Callable] = None,
41
+ is_separator: bool = False,
42
+ ):
43
+ self.label = label
44
+ self.callback = callback
45
+ self.is_separator = is_separator
46
+ self.id = 0
47
+
48
+
49
+ class SystemTray:
50
+ def __init__(self, title: str, icon_path: Optional[str] = None):
51
+ self.title = title
52
+ self.icon_path = icon_path
53
+ self.menu_items: List[MenuItem] = []
54
+ self.logger = logging.getLogger("Pytron.Tray")
55
+ self._hwnd = None
56
+ self._hicon = None
57
+ self._running = False
58
+ self._next_id = 1000
59
+ self._thread = None
60
+ self._app = None
61
+
62
+ def add_item(self, label: str, callback: Optional[Callable] = None):
63
+ item = MenuItem(label, callback)
64
+ item.id = self._next_id
65
+ self._next_id += 1
66
+ self.menu_items.append(item)
67
+ return self
68
+
69
+ def add_separator(self):
70
+ item = MenuItem("", is_separator=True)
71
+ self.menu_items.append(item)
72
+ return self
73
+
74
+ def add_quit_item(self, label: str = "Quit"):
75
+ """Adds a standard Quit item to the tray menu."""
76
+
77
+ def _quit():
78
+ if self._app:
79
+ # Use app.quit() for graceful exit (triggers cleanup/atexit)
80
+ self._app.quit()
81
+ else:
82
+ os._exit(0)
83
+
84
+ return self.add_item(label, _quit)
85
+
86
+ def start(self, app):
87
+ """Starts the tray icon."""
88
+ self._app = app
89
+ platform = sys.platform
90
+ if platform == "win32":
91
+ self._start_windows(app)
92
+ elif platform == "darwin":
93
+ self._start_darwin(app)
94
+ elif platform == "linux":
95
+ self._start_linux(app)
96
+ else:
97
+ self.logger.warning(f"System tray not implemented for {platform}")
98
+
99
+ def stop(self):
100
+ platform = sys.platform
101
+ if platform == "win32":
102
+ self._stop_windows()
103
+ # Cleanup Icon handle to prevent leaks
104
+ if self._hicon:
105
+ ctypes.windll.user32.DestroyIcon(self._hicon)
106
+ self._hicon = None
107
+
108
+ def _start_darwin(self, app):
109
+ try:
110
+ from AppKit import (
111
+ NSStatusBar,
112
+ NSVariableStatusItemLength,
113
+ NSMenu,
114
+ NSMenuItem,
115
+ NSImage,
116
+ )
117
+
118
+ self._status_item = NSStatusBar.systemStatusBar().statusItemWithLength_(
119
+ NSVariableStatusItemLength
120
+ )
121
+ self._status_item.setToolTip_(self.title)
122
+
123
+ if self.icon_path:
124
+ image = NSImage.alloc().initWithContentsOfFile_(self.icon_path)
125
+ if image:
126
+ image.setTemplate_(True)
127
+ self._status_item.button().setImage_(image)
128
+
129
+ if not self._status_item.button().image():
130
+ self._status_item.setTitle_(self.title[:3])
131
+
132
+ # Create Menu
133
+ menu = NSMenu.alloc().init()
134
+
135
+ class MenuDelegate:
136
+ def __init__(self, callback):
137
+ self.callback = callback
138
+
139
+ def call_(self, sender):
140
+ if self.callback:
141
+ self.callback()
142
+
143
+ self._delegates = []
144
+
145
+ for item in self.menu_items:
146
+ if item.is_separator:
147
+ menu.addItem_(NSMenuItem.separatorItem())
148
+ else:
149
+ d = MenuDelegate(item.callback)
150
+ self._delegates.append(d)
151
+ mi = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
152
+ item.label, "call:", ""
153
+ )
154
+ mi.setTarget_(d)
155
+ menu.addItem_(mi)
156
+
157
+ self._status_item.setMenu_(menu)
158
+ except ImportError:
159
+ self.logger.error("macOS Tray requires 'pyobjc-framework-Cocoa'.")
160
+
161
+ def _start_linux(self, app):
162
+ try:
163
+ import gi
164
+
165
+ gi.require_version("Gtk", "3.0")
166
+ gi.require_version("AppIndicator3", "0.1")
167
+ from gi.repository import Gtk, AppIndicator3
168
+
169
+ ind_id = f"pytron.tray.{id(self)}"
170
+ icon = self.icon_path if self.icon_path else "help-about"
171
+
172
+ indicator = AppIndicator3.Indicator.new(
173
+ ind_id, icon, AppIndicator3.IndicatorCategory.APPLICATION_STATUS
174
+ )
175
+ indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
176
+
177
+ menu = Gtk.Menu()
178
+
179
+ for item in self.menu_items:
180
+ if item.is_separator:
181
+ menu.append(Gtk.SeparatorMenuItem())
182
+ else:
183
+ mi = Gtk.MenuItem(label=item.label)
184
+ if item.callback:
185
+ mi.connect("activate", lambda _: item.callback())
186
+ menu.append(mi)
187
+
188
+ menu.show_all()
189
+ indicator.set_menu(menu)
190
+ self._indicator = indicator
191
+
192
+ except (ImportError, ValueError):
193
+ self.logger.error("Linux Tray requires 'PyGObject' and 'libappindicator3'.")
194
+
195
+ def _start_windows(self, app):
196
+ # Event to sync creation
197
+ ready_event = threading.Event()
198
+
199
+ def run_tray_thread():
200
+ user32 = ctypes.windll.user32
201
+ kernel32 = ctypes.windll.kernel32
202
+ shell32 = ctypes.windll.shell32
203
+
204
+ # --- Definitions ---
205
+ user32.DefWindowProcW.argtypes = [
206
+ ctypes.wintypes.HWND,
207
+ ctypes.wintypes.UINT,
208
+ ctypes.wintypes.WPARAM,
209
+ ctypes.wintypes.LPARAM,
210
+ ]
211
+ user32.DefWindowProcW.restype = ctypes.wintypes.LPARAM
212
+ user32.CreateWindowExW.argtypes = [
213
+ ctypes.c_uint,
214
+ ctypes.c_wchar_p,
215
+ ctypes.c_wchar_p,
216
+ ctypes.c_uint,
217
+ ctypes.c_int,
218
+ ctypes.c_int,
219
+ ctypes.c_int,
220
+ ctypes.c_int,
221
+ ctypes.c_void_p,
222
+ ctypes.c_void_p,
223
+ ctypes.c_void_p,
224
+ ctypes.c_void_p,
225
+ ]
226
+ user32.CreateWindowExW.restype = ctypes.c_void_p
227
+ kernel32.GetModuleHandleW.restype = ctypes.c_void_p
228
+
229
+ # Ensure we use the shared NOTIFYICONDATAW definition
230
+ shell32.Shell_NotifyIconW.argtypes = [
231
+ ctypes.c_ulong,
232
+ ctypes.POINTER(NOTIFYICONDATAW),
233
+ ]
234
+ shell32.Shell_NotifyIconW.restype = ctypes.wintypes.BOOL
235
+
236
+ def window_proc(hwnd, msg, wparam, lparam):
237
+ if msg == WM_TRAYICON:
238
+ if lparam == WM_LBUTTONUP:
239
+ app.show()
240
+ elif lparam == WM_RBUTTONUP:
241
+ self._show_menu(hwnd)
242
+ elif msg == 0x0111: # WM_COMMAND
243
+ item_id = wparam & 0xFFFF
244
+ for item in self.menu_items:
245
+ if item.id == item_id and item.callback:
246
+ try:
247
+ item.callback()
248
+ except Exception as e:
249
+ self.logger.error(f"Menu callback failed: {e}")
250
+ break
251
+ return user32.DefWindowProcW(hwnd, msg, wparam, lparam)
252
+
253
+ WNDPROC = ctypes.WINFUNCTYPE(
254
+ ctypes.wintypes.LPARAM,
255
+ ctypes.wintypes.HWND,
256
+ ctypes.wintypes.UINT,
257
+ ctypes.wintypes.WPARAM,
258
+ ctypes.wintypes.LPARAM,
259
+ )
260
+ self._wndproc = WNDPROC(window_proc) # Keep ref to prevent GC
261
+
262
+ class WNDCLASSW(ctypes.Structure):
263
+ _fields_ = [
264
+ ("style", ctypes.c_uint),
265
+ ("lpfnWndProc", WNDPROC),
266
+ ("cbClsExtra", ctypes.c_int),
267
+ ("cbWndExtra", ctypes.c_int),
268
+ ("hInstance", ctypes.c_void_p),
269
+ ("hIcon", ctypes.c_void_p),
270
+ ("hCursor", ctypes.c_void_p),
271
+ ("hbrBackground", ctypes.c_void_p),
272
+ ("lpszMenuName", ctypes.c_wchar_p),
273
+ ("lpszClassName", ctypes.c_wchar_p),
274
+ ]
275
+
276
+ wc = WNDCLASSW()
277
+ wc.lpfnWndProc = self._wndproc
278
+ wc.lpszClassName = f"PytronTray_{id(self)}"
279
+ wc.hInstance = kernel32.GetModuleHandleW(None)
280
+ user32.RegisterClassW(ctypes.byref(wc))
281
+
282
+ # 2. Create Window INSIDE this thread
283
+ self._hwnd = user32.CreateWindowExW(
284
+ 0, wc.lpszClassName, self.title, 0, 0, 0, 0, 0, 0, 0, wc.hInstance, 0
285
+ )
286
+
287
+ # 3. Create Icon
288
+ if self.icon_path:
289
+ IMAGE_ICON = 1
290
+ LR_LOADFROMFILE = 0x00000010
291
+ r_path = get_resource_path(self.icon_path)
292
+ self.logger.debug(f"Attempting to load icon from: {r_path}")
293
+
294
+ # Load 16x16 for logic
295
+ self._hicon = user32.LoadImageW(
296
+ None, str(r_path), IMAGE_ICON, 16, 16, LR_LOADFROMFILE
297
+ )
298
+
299
+ if not self._hicon:
300
+ err = ctypes.GetLastError()
301
+ self.logger.warning(
302
+ f"Failed to load 16x16 icon. Error: {err}. Retrying with default size."
303
+ )
304
+ # Retry with default size
305
+ self._hicon = user32.LoadImageW(
306
+ None, str(r_path), IMAGE_ICON, 0, 0, LR_LOADFROMFILE
307
+ )
308
+ if not self._hicon:
309
+ self.logger.error(
310
+ f"Failed to load default size icon. Error: {ctypes.GetLastError()}"
311
+ )
312
+
313
+ if not self._hicon:
314
+ self.logger.warning("Fallback to system application icon")
315
+ self._hicon = user32.LoadIconW(0, ctypes.c_void_p(32512))
316
+
317
+ # 4. Add to Tray
318
+ nid = NOTIFYICONDATAW()
319
+ nid.cbSize = ctypes.sizeof(NOTIFYICONDATAW)
320
+ nid.hWnd = self._hwnd
321
+ nid.uID = 1
322
+ nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP
323
+ nid.uCallbackMessage = WM_TRAYICON
324
+ nid.hIcon = self._hicon
325
+ nid.szTip = self.title[:127]
326
+
327
+ shell32.Shell_NotifyIconW(NIM_ADD, ctypes.byref(nid))
328
+
329
+ # Signal that we are ready!
330
+ ready_event.set()
331
+
332
+ # 5. Pump Messages (Blocking)
333
+ msg = ctypes.wintypes.MSG()
334
+ while self._running:
335
+ # GetMessage blocks until a message arrives
336
+ res = user32.GetMessageW(ctypes.byref(msg), 0, 0, 0)
337
+ if res <= 0:
338
+ break
339
+ user32.TranslateMessage(ctypes.byref(msg))
340
+ user32.DispatchMessageW(ctypes.byref(msg))
341
+
342
+ # Cleanup when loop exits
343
+ if self._hwnd:
344
+ user32.DestroyWindow(self._hwnd)
345
+
346
+ self._running = True
347
+ self._thread = threading.Thread(target=run_tray_thread, daemon=True)
348
+ self._thread.start()
349
+
350
+ # Wait for tray to appear before returning (prevents race conditions)
351
+ ready_event.wait(timeout=2.0)
352
+
353
+ def _show_menu(self, hwnd):
354
+ hmenu = ctypes.windll.user32.CreatePopupMenu()
355
+
356
+ for item in self.menu_items:
357
+ if item.is_separator:
358
+ ctypes.windll.user32.AppendMenuW(hmenu, MFT_SEPARATOR, 0, None)
359
+ else:
360
+ ctypes.windll.user32.AppendMenuW(hmenu, MFT_STRING, item.id, item.label)
361
+
362
+ pos = ctypes.wintypes.POINT()
363
+ ctypes.windll.user32.GetCursorPos(ctypes.byref(pos))
364
+
365
+ ctypes.windll.user32.SetForegroundWindow(hwnd)
366
+ ctypes.windll.user32.TrackPopupMenu(
367
+ hmenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, 0, hwnd, None
368
+ )
369
+ ctypes.windll.user32.PostMessageW(hwnd, 0, 0, 0)
370
+
371
+ def _stop_windows(self):
372
+ self._running = False
373
+ if self._hwnd:
374
+ # Force wake up the message loop to exit?
375
+ # GetMessage is blocking. We need to post a dummy message or WM_NULL/WM_CLOSE
376
+ ctypes.windll.user32.PostMessageW(self._hwnd, 0x0010, 0, 0) # WM_CLOSE
377
+
378
+ # Wait for thread to finish to prevent zombies
379
+ if self._thread and self._thread.is_alive():
380
+ self._thread.join(timeout=2.0)
381
+ if self._thread.is_alive():
382
+ self.logger.warning("Tray thread did not exit cleanly.")
383
+
384
+ # Also delete icon
385
+ if self._hwnd:
386
+ nid = NOTIFYICONDATAW()
387
+ nid.cbSize = ctypes.sizeof(NOTIFYICONDATAW)
388
+ nid.hWnd = self._hwnd
389
+ nid.uID = 1
390
+
391
+ shell32 = ctypes.windll.shell32
392
+ # Use strict argtypes with shared structure
393
+ shell32.Shell_NotifyIconW.argtypes = [
394
+ ctypes.c_ulong,
395
+ ctypes.POINTER(NOTIFYICONDATAW),
396
+ ]
397
+
398
+ shell32.Shell_NotifyIconW(NIM_DELETE, ctypes.byref(nid))
399
+ self._hwnd = None
pytron/updater.py ADDED
@@ -0,0 +1,181 @@
1
+ import os
2
+ import sys
3
+ import json
4
+ import urllib.request
5
+ import urllib.error
6
+ import subprocess
7
+ import tempfile
8
+ import logging
9
+ from pathlib import Path
10
+ from packaging.version import parse as parse_version
11
+ import stat
12
+
13
+
14
+ class Updater:
15
+ def __init__(self, current_version=None):
16
+ self.logger = logging.getLogger("Pytron.Updater")
17
+ # Try to infer version if not provided
18
+ self.current_version = current_version
19
+ if not self.current_version:
20
+ try:
21
+ # If running from source/pytron structure
22
+ from . import __version__
23
+
24
+ self.current_version = __version__
25
+ except ImportError:
26
+ self.current_version = "0.0.0"
27
+
28
+ # In a real app, the developer sets the version in settings.json or passes it.
29
+ # We will try to find the app's version from settings.json if it exists nearby
30
+ try:
31
+ settings_path = Path("settings.json")
32
+ if settings_path.exists():
33
+ data = json.loads(settings_path.read_text())
34
+ if "version" in data:
35
+ self.current_version = data["version"]
36
+ except:
37
+ pass
38
+
39
+ def check(self, url: str) -> dict | None:
40
+ """
41
+ Checks for updates at the given URL.
42
+ """
43
+ if not getattr(sys, "frozen", False):
44
+ self.logger.debug("Skipping update check in development mode.")
45
+ return None
46
+ self.logger.info(f"Checking for updates at {url}...")
47
+ try:
48
+ if not url.startswith("https://"):
49
+ raise ValueError("Updater only supports HTTPS")
50
+
51
+ # nosemgrep
52
+ with urllib.request.urlopen(url, timeout=5) as response: # nosec B310
53
+ data = json.loads(response.read().decode())
54
+ remote_version = data.get("version")
55
+
56
+ if not remote_version:
57
+ self.logger.error("Invalid update manifest: missing 'version'")
58
+ return None
59
+
60
+ # Compare versions
61
+ if parse_version(remote_version) > parse_version(self.current_version):
62
+ self.logger.info(
63
+ f"Update available: {remote_version} (Current: {self.current_version})"
64
+ )
65
+ return data
66
+ else:
67
+ self.logger.info("App is up to date.")
68
+ return None
69
+
70
+ except urllib.error.URLError as e:
71
+ self.logger.error(f"Failed to check for updates: {e}")
72
+ return None
73
+ except Exception as e:
74
+ self.logger.error(f"Error checking updates: {e}")
75
+ return None
76
+
77
+ def download_and_install(self, update_info: dict, on_progress=None):
78
+ """
79
+ Downloads the update.
80
+ In Secure Builds, it prefers the 'patch_url' to download a tiny evolution patch.
81
+ Otherwise, it downloads the full installer.
82
+ """
83
+ patch_url = update_info.get("patch_url")
84
+ full_url = update_info.get("url")
85
+
86
+ # Detect if we are in a Secure Build (app.pytron exists next to EXE)
87
+ is_secure = False
88
+ if getattr(sys, "frozen", False):
89
+ # Real app root is parent of _internal or where exe is
90
+ exe_dir = Path(sys.executable).parent
91
+ payload_path = exe_dir / "app.pytron"
92
+ if payload_path.exists():
93
+ is_secure = True
94
+ self.logger.info("Secure Build detected. Ready for binary evolution.")
95
+
96
+ # If secure and patch exists, use patch
97
+ if is_secure and patch_url:
98
+ self.logger.info(f"Preferring evolution patch: {patch_url}")
99
+ return self._handle_patch_download(patch_url, on_progress)
100
+
101
+ if not full_url:
102
+ self.logger.error("No download URL provided in update info.")
103
+ return False
104
+
105
+ return self._handle_full_download(full_url, on_progress)
106
+
107
+ def _handle_patch_download(self, url, on_progress):
108
+ try:
109
+ exe_dir = Path(sys.executable).parent
110
+ patch_dest = exe_dir / "app.pytron_patch"
111
+
112
+ self.logger.info(f"Downloading patch to {patch_dest}...")
113
+
114
+ def progress(block_num, block_size, total_size):
115
+ if on_progress:
116
+ downloaded = block_num * block_size
117
+ percent = min(100, int((downloaded / total_size) * 100))
118
+ on_progress(percent)
119
+
120
+ # nosemgrep
121
+ urllib.request.urlretrieve(
122
+ url, patch_dest, reporthook=progress
123
+ ) # nosec B310
124
+ self.logger.info("Evolution patch downloaded successfully.")
125
+
126
+ # Since the Rust loader handles patching on launch, we just need to restart
127
+ self.logger.info("Restarting to apply evolution...")
128
+
129
+ if sys.platform == "win32":
130
+ subprocess.Popen(
131
+ [sys.executable], shell=False, creationflags=0x00000008
132
+ ) # DETACHED_PROCESS # nosec B603
133
+ else:
134
+ subprocess.Popen([sys.executable]) # nosec B603
135
+
136
+ sys.exit(0)
137
+ return True
138
+ except Exception as e:
139
+ self.logger.error(f"Failed to download patch: {e}")
140
+ return False
141
+
142
+ def _handle_full_download(self, url, on_progress):
143
+ filename = url.split("/")[-1]
144
+ if not filename.endswith(
145
+ (".exe", ".msi", ".dmg", ".pkg", ".deb", ".rpm", ".AppImage")
146
+ ):
147
+ filename = (
148
+ "update_installer.exe"
149
+ if sys.platform == "win32"
150
+ else "update_installer"
151
+ )
152
+
153
+ download_path = Path(tempfile.gettempdir()) / filename
154
+ try:
155
+
156
+ def progress(block_num, block_size, total_size):
157
+ if on_progress:
158
+ percent = min(100, int((block_num * block_size / total_size) * 100))
159
+ on_progress(percent)
160
+
161
+ # nosemgrep
162
+ urllib.request.urlretrieve(
163
+ url, download_path, reporthook=progress
164
+ ) # nosec B310
165
+ self.logger.info(f"Download complete: {download_path}")
166
+
167
+ if sys.platform == "win32":
168
+ subprocess.Popen(
169
+ [str(download_path)], shell=False, creationflags=0x00000008
170
+ )
171
+ elif sys.platform == "darwin":
172
+ subprocess.Popen(["open", str(download_path)])
173
+ else:
174
+ os.chmod(download_path, stat.S_IRWXU)
175
+ subprocess.Popen([str(download_path)])
176
+
177
+ sys.exit(0)
178
+ return True
179
+ except Exception as e:
180
+ self.logger.error(f"Failed to install full update: {e}")
181
+ return False
pytron/utf8_hook.py ADDED
@@ -0,0 +1,112 @@
1
+ """Runtime hook for Pytron.
2
+
3
+ This hook attempts to make a frozen Pytron app robust when printing or logging
4
+ modern Unicode (emoji, CJK, astral-plane characters) on Windows and other
5
+ platforms. It is best-effort and will not crash the application if any step
6
+ fails.
7
+ """
8
+
9
+ import os
10
+ import sys
11
+ import io
12
+ import locale
13
+ import logging
14
+
15
+
16
+ def _set_utf8_mode():
17
+ # Best-effort environment hints for subprocesses and libraries
18
+ try:
19
+ os.environ.setdefault("PYTHONUTF8", "1")
20
+ os.environ.setdefault("PYTHONIOENCODING", "utf-8")
21
+ os.environ.setdefault("LANG", "en_US.UTF-8")
22
+ except Exception:
23
+ pass
24
+
25
+ # Prefer the user's locale if possible (no-op on failure)
26
+ try:
27
+ locale.setlocale(locale.LC_ALL, "")
28
+ except Exception:
29
+ pass
30
+
31
+ # Override locale.getpreferredencoding() to return utf-8 so libraries
32
+ # that consult it will prefer UTF-8.
33
+ try:
34
+ import locale as _locale
35
+
36
+ _locale.getpreferredencoding = lambda do_setlocale=False: "utf-8"
37
+ except Exception:
38
+ pass
39
+
40
+ # On Windows try to set the console code page to UTF-8 (65001).
41
+ if sys.platform.startswith("win"):
42
+ try:
43
+ import ctypes
44
+
45
+ kernel32 = ctypes.windll.kernel32
46
+
47
+ # Harden: Explicitly define signatures for robustness
48
+ kernel32.SetConsoleOutputCP.argtypes = [ctypes.c_uint]
49
+ kernel32.SetConsoleOutputCP.restype = ctypes.c_int
50
+
51
+ kernel32.SetConsoleCP.argtypes = [ctypes.c_uint]
52
+ kernel32.SetConsoleCP.restype = ctypes.c_int
53
+
54
+ # Check return values (Non-zero is success)
55
+ if kernel32.SetConsoleOutputCP(65001) == 0:
56
+ # logging.warning(f"Failed to SetConsoleOutputCP: {err}")
57
+ pass
58
+
59
+ if kernel32.SetConsoleCP(65001) == 0:
60
+ pass
61
+
62
+ except Exception:
63
+ pass
64
+
65
+ # Wrap or reconfigure stdio streams to UTF-8 with surrogatepass to avoid
66
+ # raising UnicodeEncodeError when printing characters that the system
67
+ # code page cannot represent.
68
+ def wrap_stream(stream):
69
+ try:
70
+ buf = getattr(stream, "buffer", None)
71
+ if buf is not None:
72
+ return io.TextIOWrapper(
73
+ buf, encoding="utf-8", errors="surrogatepass", line_buffering=True
74
+ )
75
+ # Fallback: try reconfigure (Python 3.7+)
76
+ try:
77
+ stream.reconfigure(encoding="utf-8", errors="surrogatepass")
78
+ except Exception:
79
+ pass
80
+ except Exception:
81
+ pass
82
+ return stream
83
+
84
+ try:
85
+ if sys.stdin is not None:
86
+ sys.stdin = wrap_stream(sys.stdin)
87
+ if sys.stdout is not None:
88
+ sys.stdout = wrap_stream(sys.stdout)
89
+ if sys.stderr is not None:
90
+ sys.stderr = wrap_stream(sys.stderr)
91
+ except Exception:
92
+ pass
93
+
94
+ # Patch logging.StreamHandler so that handlers created after this hook will
95
+ # get their stream wrapped as well.
96
+ try:
97
+ _orig_init = logging.StreamHandler.__init__
98
+
99
+ def _patched_init(self, stream=None):
100
+ _orig_init(self, stream=stream)
101
+ try:
102
+ if getattr(self, "stream", None) is not None:
103
+ self.stream = wrap_stream(self.stream)
104
+ except Exception:
105
+ pass
106
+
107
+ logging.StreamHandler.__init__ = _patched_init
108
+ except Exception:
109
+ pass
110
+
111
+
112
+ _set_utf8_mode()