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.
- pytron/__init__.py +112 -0
- pytron/application.py +562 -0
- pytron/apputils/__init__.py +0 -0
- pytron/apputils/chrome_ipc.py +203 -0
- pytron/apputils/codegen.py +261 -0
- pytron/apputils/config.py +303 -0
- pytron/apputils/deadmansswitch.py +47 -0
- pytron/apputils/extras.py +76 -0
- pytron/apputils/native.py +148 -0
- pytron/apputils/shell.py +73 -0
- pytron/apputils/windows.py +286 -0
- pytron/cli.py +384 -0
- pytron/commands/__init__.py +0 -0
- pytron/commands/android.py +28 -0
- pytron/commands/build.py +26 -0
- pytron/commands/doctor.py +221 -0
- pytron/commands/engine.py +23 -0
- pytron/commands/frontend.py +60 -0
- pytron/commands/harvest.py +112 -0
- pytron/commands/helpers.py +239 -0
- pytron/commands/info.py +50 -0
- pytron/commands/init.py +521 -0
- pytron/commands/install.py +294 -0
- pytron/commands/login.py +130 -0
- pytron/commands/package.py +228 -0
- pytron/commands/plugin.py +442 -0
- pytron/commands/run.py +312 -0
- pytron/commands/scan.py +210 -0
- pytron/commands/show.py +23 -0
- pytron/commands/uninstall.py +150 -0
- pytron/commands/utils.py +42 -0
- pytron/commands/workflow.py +95 -0
- pytron/console.py +133 -0
- pytron/core.py +18 -0
- pytron/dependencies/WebView2Loader.dll +0 -0
- pytron/dependencies/__init__.py +1 -0
- pytron/dependencies/pytron_native.so +0 -0
- pytron/engines/chrome/adapter.py +445 -0
- pytron/engines/chrome/engine.py +576 -0
- pytron/engines/chrome/forge.py +147 -0
- pytron/engines/chrome/shell/package.json +8 -0
- pytron/engines/chrome/shell/preload.js +12 -0
- pytron/engines/chrome/shell/shell.js +534 -0
- pytron/exceptions.py +36 -0
- pytron/inspector.py +201 -0
- pytron/inspector_ui.py +512 -0
- pytron/installer/Installation.nsi +236 -0
- pytron/installer/header.bmp +0 -0
- pytron/installer/pytron.ico +0 -0
- pytron/installer/sidebar.bmp +0 -0
- pytron/llms.md +98 -0
- pytron/manifests/README.md +29 -0
- pytron/manifests/windows-utf8.manifest +44 -0
- pytron/menu.py +128 -0
- pytron/nsis-setup.exe +0 -0
- pytron/pack/__init__.py +0 -0
- pytron/pack/assets.py +131 -0
- pytron/pack/compilers.py +289 -0
- pytron/pack/crystal.py +297 -0
- pytron/pack/graph.py +377 -0
- pytron/pack/inference.py +157 -0
- pytron/pack/installers.py +402 -0
- pytron/pack/introspect.py +357 -0
- pytron/pack/metadata.py +213 -0
- pytron/pack/modules.py +618 -0
- pytron/pack/nuitka.py +108 -0
- pytron/pack/pipeline.py +107 -0
- pytron/pack/pyinstaller.py +176 -0
- pytron/pack/rust_engine.py +273 -0
- pytron/pack/secure.py +309 -0
- pytron/pack/secure_loader/bin/pytron_rust_bootloader +0 -0
- pytron/pack/secure_loader/icon.ico +0 -0
- pytron/pack/utils.py +110 -0
- pytron/pack/virtual_root.py +124 -0
- pytron/platforms/__init__.py +0 -0
- pytron/platforms/android/__init__.py +3 -0
- pytron/platforms/android/android.py +103 -0
- pytron/platforms/android/builder.py +736 -0
- pytron/platforms/android/ops/build.py +79 -0
- pytron/platforms/android/ops/init.py +63 -0
- pytron/platforms/android/ops/run.py +79 -0
- pytron/platforms/android/ops/sync.py +770 -0
- pytron/platforms/android/ops/utils.py +8 -0
- pytron/platforms/android/shell/README.md +30 -0
- pytron/platforms/android/shell/app/build.gradle +64 -0
- pytron/platforms/android/shell/app/src/main/AndroidManifest.xml +29 -0
- pytron/platforms/android/shell/app/src/main/assets/python/main.py +86 -0
- pytron/platforms/android/shell/app/src/main/assets/python/python314.zip +0 -0
- pytron/platforms/android/shell/app/src/main/cpp/CMakeLists.txt +25 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/Python.h +155 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/abstract.h +915 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/audit.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/bltinmodule.h +14 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/boolobject.h +54 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/bytearrayobject.h +44 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/bytesobject.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/ceval.h +145 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/codecs.h +176 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/compile.h +22 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/complexobject.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/abstract.h +104 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/audit.h +8 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/bytearrayobject.h +38 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/bytesobject.h +42 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/cellobject.h +50 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/ceval.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/classobject.h +71 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/code.h +340 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/compile.h +50 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/complexobject.h +33 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/context.h +107 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/critical_section.h +154 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/descrobject.h +62 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/dictobject.h +105 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/fileobject.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/fileutils.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/floatobject.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/frameobject.h +35 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/funcobject.h +185 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/genobject.h +56 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/import.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/initconfig.h +334 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/listobject.h +53 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/lock.h +74 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/longintrepr.h +184 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/longobject.h +89 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/memoryobject.h +50 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/methodobject.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/modsupport.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/monitoring.h +269 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/object.h +493 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/objimpl.h +104 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/odictobject.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/picklebufobject.h +31 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pthread_stubs.h +105 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic.h +614 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_gcc.h +615 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_msc.h +1197 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyatomic_std.h +1112 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyctype.h +39 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pydebug.h +38 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyerrors.h +132 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyfpe.h +15 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyframe.h +45 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pyhash.h +54 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pylifecycle.h +89 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pymem.h +84 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pystate.h +275 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pystats.h +194 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pythonrun.h +96 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pythread.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/pytime.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/setobject.h +71 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/traceback.h +13 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/tracemalloc.h +32 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/tupleobject.h +40 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/unicodeobject.h +773 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/warnings.h +20 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/cpython/weakrefobject.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/critical_section.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/datetime.h +267 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/descrobject.h +100 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/dictobject.h +108 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/dynamic_annotations.h +499 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/enumobject.h +17 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/errcode.h +45 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/exports.h +105 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/fileobject.h +41 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/fileutils.h +62 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/floatobject.h +54 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/frameobject.h +20 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/genericaliasobject.h +14 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/import.h +103 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/atomic.h +392 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/internal.h +969 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/prim.h +329 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/track.h +147 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc/types.h +721 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/mimalloc/mimalloc.h +565 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_abstract.h +61 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_asdl.h +112 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ast.h +945 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ast_state.h +271 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_atexit.h +31 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_audit.h +35 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_backoff.h +133 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bitutils.h +186 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_blocks_output_buffer.h +321 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_brc.h +73 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bytes_methods.h +82 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_bytesobject.h +149 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_c_array.h +39 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_call.h +206 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_capsule.h +17 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_cell.h +75 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ceval.h +390 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ceval_state.h +48 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_code.h +671 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_codecs.h +76 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_compile.h +230 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_complexobject.h +34 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_condvar.h +93 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_context.h +59 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_critical_section.h +237 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_crossinterp.h +406 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_crossinterp_data_registry.h +41 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_debug_offsets.h +379 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_descrobject.h +28 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dict.h +410 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dict_state.h +28 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_dtoa.h +40 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_emscripten_signal.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_emscripten_trampoline.h +70 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_exceptions.h +40 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_faulthandler.h +100 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_fileutils.h +320 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_fileutils_windows.h +98 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_floatobject.h +49 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_flowgraph.h +47 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_format.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_frame.h +61 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_freelist.h +111 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_freelist_state.h +70 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_function.h +53 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_gc.h +378 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_genobject.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_getopt.h +22 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_gil.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_objects.h +34 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_objects_fini_generated.h +1592 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_global_strings.h +854 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_hamt.h +113 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_hashtable.h +150 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_import.h +141 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_importdl.h +139 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_index_pool.h +36 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_initconfig.h +197 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_instruction_sequence.h +83 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_instruments.h +127 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interp.h +109 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interp_structs.h +977 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpframe.h +401 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpframe_structs.h +95 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_interpolation.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_intrinsics.h +51 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_jit.h +29 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_list.h +81 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_llist.h +106 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_lock.h +236 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_long.h +319 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_magic_number.h +305 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_memoryobject.h +20 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_mimalloc.h +69 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_modsupport.h +99 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_moduleobject.h +62 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_namespace.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object.h +1029 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_alloc.h +71 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_deferred.h +32 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_stack.h +95 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_object_state.h +49 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_obmalloc.h +702 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_obmalloc_init.h +66 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_opcode_metadata.h +2117 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_opcode_utils.h +90 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_optimizer.h +318 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_parking_lot.h +97 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_parser.h +78 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pathconfig.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyarena.h +68 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyatomic_ft_wrappers.h +174 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pybuffer.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyerrors.h +213 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pyhash.h +91 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pylifecycle.h +136 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymath.h +205 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymem.h +145 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pymem_init.h +103 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pystate.h +339 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pystats.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pythonrun.h +68 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_pythread.h +172 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_qsbr.h +172 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_range.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime.h +63 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_init.h +239 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_init_generated.h +1589 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_runtime_structs.h +310 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_semaphore.h +67 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_setobject.h +41 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_signal.h +108 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_sliceobject.h +20 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_stackref.h +791 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_stats.h +97 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_strhex.h +39 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_structs.h +88 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_structseq.h +40 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_symtable.h +201 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_sysmodule.h +32 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_template.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_time.h +334 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_token.h +110 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_traceback.h +111 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tracemalloc.h +164 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tstate.h +88 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_tuple.h +75 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typedefs.h +18 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typeobject.h +155 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_typevarobject.h +28 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_ucnhash.h +36 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unicodeobject.h +308 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unicodeobject_generated.h +3132 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_unionobject.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uniqueid.h +57 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uop_ids.h +335 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_uop_metadata.h +1204 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_warnings.h +21 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/internal/pycore_weakref.h +133 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/intrcheck.h +23 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/iterobject.h +24 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/listobject.h +55 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/lock.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/longobject.h +178 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/marshal.h +31 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/memoryobject.h +34 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/methodobject.h +146 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/modsupport.h +146 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/moduleobject.h +122 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/monitoring.h +18 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/object.h +828 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/objimpl.h +211 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/opcode.h +43 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/opcode_ids.h +259 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/osdefs.h +57 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/osmodule.h +17 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/patchlevel.h +49 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/py_curses.h +117 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyatomic.h +16 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pybuffer.h +145 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pycapsule.h +58 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyconfig.h +2088 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pydtrace.h +59 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyerrors.h +335 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyexpat.h +62 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyframe.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyhash.h +59 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pylifecycle.h +80 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pymacconfig.h +91 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pymacro.h +243 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pymath.h +65 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pymem.h +110 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pyport.h +710 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pystate.h +132 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pystats.h +28 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pystrcmp.h +23 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pystrtod.h +37 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pythonrun.h +42 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pythread.h +131 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/pytypedefs.h +30 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/rangeobject.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/refcount.h +555 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/setobject.h +49 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/sliceobject.h +69 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/structmember.h +56 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/structseq.h +46 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/sysmodule.h +27 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/traceback.h +26 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/tupleobject.h +46 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/typeslots.h +96 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/unicodeobject.h +1029 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/warnings.h +45 -0
- pytron/platforms/android/shell/app/src/main/cpp/include/weakrefobject.h +46 -0
- pytron/platforms/android/shell/app/src/main/cpp/pytron_bridge.cpp +224 -0
- pytron/platforms/android/shell/app/src/main/java/com/pytron/shell/MainActivity.kt +208 -0
- pytron/platforms/android/shell/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- pytron/platforms/android/shell/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- pytron/platforms/android/shell/build.gradle +11 -0
- pytron/platforms/android/shell/gradle/wrapper/gradle-wrapper.jar +0 -0
- pytron/platforms/android/shell/gradle/wrapper/gradle-wrapper.properties +5 -0
- pytron/platforms/android/shell/gradle.properties +2 -0
- pytron/platforms/android/shell/gradlew.bat +85 -0
- pytron/platforms/android/shell/settings.gradle +16 -0
- pytron/platforms/darwin.py +82 -0
- pytron/platforms/darwin_ops/libs.py +31 -0
- pytron/platforms/darwin_ops/system.py +182 -0
- pytron/platforms/darwin_ops/utils.py +85 -0
- pytron/platforms/darwin_ops/webview.py +5 -0
- pytron/platforms/darwin_ops/window.py +102 -0
- pytron/platforms/interface.py +152 -0
- pytron/platforms/linux.py +82 -0
- pytron/platforms/linux_ops/libs.py +49 -0
- pytron/platforms/linux_ops/system.py +316 -0
- pytron/platforms/linux_ops/utils.py +19 -0
- pytron/platforms/linux_ops/webview.py +5 -0
- pytron/platforms/linux_ops/window.py +115 -0
- pytron/platforms/windows.py +136 -0
- pytron/platforms/windows_ops/__init__.py +0 -0
- pytron/platforms/windows_ops/constants.py +126 -0
- pytron/platforms/windows_ops/system.py +518 -0
- pytron/platforms/windows_ops/utils.py +3 -0
- pytron/platforms/windows_ops/webview.py +5 -0
- pytron/platforms/windows_ops/window.py +361 -0
- pytron/plugin.py +467 -0
- pytron/rcedit-x64.exe +0 -0
- pytron/router.py +146 -0
- pytron/serializer.py +240 -0
- pytron/shortcuts.py +279 -0
- pytron/state.py +76 -0
- pytron/tray.py +399 -0
- pytron/updater.py +181 -0
- pytron/utf8_hook.py +112 -0
- pytron/utils.py +44 -0
- pytron/webview.py +722 -0
- pytron_kit-0.3.12.dist-info/METADATA +131 -0
- pytron_kit-0.3.12.dist-info/RECORD +419 -0
- pytron_kit-0.3.12.dist-info/WHEEL +5 -0
- pytron_kit-0.3.12.dist-info/entry_points.txt +2 -0
- pytron_kit-0.3.12.dist-info/licenses/LICENSE +201 -0
- pytron_kit-0.3.12.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import glob
|
|
4
|
+
import zipfile
|
|
5
|
+
import importlib.metadata
|
|
6
|
+
import json
|
|
7
|
+
import subprocess
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from rich.markup import escape
|
|
10
|
+
from ....console import log, console
|
|
11
|
+
from ....commands.helpers import get_config
|
|
12
|
+
from ..builder import AndroidBuilder
|
|
13
|
+
|
|
14
|
+
import time
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def sync_android_project(project_root: str, native: bool = False) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Sync the current project assets to the Android project.
|
|
20
|
+
"""
|
|
21
|
+
target_android_dir = os.path.join(project_root, "android")
|
|
22
|
+
|
|
23
|
+
if not os.path.exists(target_android_dir):
|
|
24
|
+
log(
|
|
25
|
+
"Android project not found. Run 'pytron android init' first.",
|
|
26
|
+
style="error",
|
|
27
|
+
)
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
assets_dir = os.path.join(target_android_dir, "app", "src", "main", "assets")
|
|
31
|
+
python_dir = os.path.join(assets_dir, "python")
|
|
32
|
+
www_dir = os.path.join(assets_dir, "www")
|
|
33
|
+
site_packages_dir = os.path.join(python_dir, "site-packages")
|
|
34
|
+
os.makedirs(site_packages_dir, exist_ok=True)
|
|
35
|
+
|
|
36
|
+
log(f"Syncing to {assets_dir}...")
|
|
37
|
+
|
|
38
|
+
# 0. Build Frontend
|
|
39
|
+
frontend_dir = os.path.join(project_root, "frontend")
|
|
40
|
+
if os.path.exists(frontend_dir) and os.path.exists(
|
|
41
|
+
os.path.join(frontend_dir, "package.json")
|
|
42
|
+
):
|
|
43
|
+
console.print(" [Frontend] Building frontend...", style="dim")
|
|
44
|
+
try:
|
|
45
|
+
# Check for node_modules
|
|
46
|
+
if not os.path.exists(os.path.join(frontend_dir, "node_modules")):
|
|
47
|
+
config = get_config()
|
|
48
|
+
provider = config.get("frontend_provider", "npm")
|
|
49
|
+
provider_bin = shutil.which(provider) or provider
|
|
50
|
+
console.print(
|
|
51
|
+
f" [Frontend] Installing dependencies using {provider}...",
|
|
52
|
+
style="dim",
|
|
53
|
+
)
|
|
54
|
+
subprocess.run(
|
|
55
|
+
[provider_bin, "install"], shell=False, cwd=frontend_dir, check=True
|
|
56
|
+
) # nosec B603
|
|
57
|
+
|
|
58
|
+
config = get_config()
|
|
59
|
+
provider = config.get("frontend_provider", "npm")
|
|
60
|
+
provider_bin = shutil.which(provider) or provider
|
|
61
|
+
subprocess.run(
|
|
62
|
+
[provider_bin, "run", "build"],
|
|
63
|
+
shell=False,
|
|
64
|
+
cwd=frontend_dir,
|
|
65
|
+
check=True,
|
|
66
|
+
) # nosec B603
|
|
67
|
+
console.print(" [Frontend] Build successful.", style="success")
|
|
68
|
+
except subprocess.CalledProcessError as e:
|
|
69
|
+
console.print(f" [Frontend] Build failed: {e}", style="error")
|
|
70
|
+
|
|
71
|
+
# 1. Frontend (www)
|
|
72
|
+
# Search for standard build output locations
|
|
73
|
+
frontend_candidates = [
|
|
74
|
+
os.path.join(project_root, "frontend", "dist"),
|
|
75
|
+
os.path.join(project_root, "frontend", "build"),
|
|
76
|
+
os.path.join(project_root, "dist"),
|
|
77
|
+
os.path.join(project_root, "build"),
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
frontend_src = None
|
|
81
|
+
for cand in frontend_candidates:
|
|
82
|
+
if os.path.exists(cand) and os.path.isdir(cand):
|
|
83
|
+
frontend_src = cand
|
|
84
|
+
break
|
|
85
|
+
|
|
86
|
+
# Clean existing www
|
|
87
|
+
if os.path.exists(www_dir):
|
|
88
|
+
shutil.rmtree(www_dir)
|
|
89
|
+
|
|
90
|
+
if frontend_src:
|
|
91
|
+
console.print(
|
|
92
|
+
f" [Frontend] Found at {escape(os.path.relpath(frontend_src, project_root))}",
|
|
93
|
+
style="dim",
|
|
94
|
+
)
|
|
95
|
+
console.print(f" [Frontend] Copying to assets/www...", style="dim")
|
|
96
|
+
shutil.copytree(frontend_src, www_dir)
|
|
97
|
+
else:
|
|
98
|
+
console.print(
|
|
99
|
+
" [Frontend] No built frontend found (checked frontend/dist, dist, etc). Creating empty www.",
|
|
100
|
+
style="warning",
|
|
101
|
+
)
|
|
102
|
+
os.makedirs(www_dir, exist_ok=True)
|
|
103
|
+
with open(os.path.join(www_dir, "index.html"), "w") as f:
|
|
104
|
+
f.write(
|
|
105
|
+
"<html><body><h1>Pytron App</h1><p>Frontend not found. Run build!</p></body></html>"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# 2. Python Backend
|
|
109
|
+
# Copy essentially the whole current folder except excluded items
|
|
110
|
+
console.print(" [Backend] Copying Python backend...", style="dim")
|
|
111
|
+
|
|
112
|
+
# Items to IGNORE in the root
|
|
113
|
+
ignore_list = [
|
|
114
|
+
"android",
|
|
115
|
+
"node_modules",
|
|
116
|
+
".git",
|
|
117
|
+
"__pycache__",
|
|
118
|
+
"dist",
|
|
119
|
+
"build",
|
|
120
|
+
"frontend",
|
|
121
|
+
".idea",
|
|
122
|
+
".vscode",
|
|
123
|
+
"venv",
|
|
124
|
+
"env",
|
|
125
|
+
".gradle",
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
for item in os.listdir(project_root):
|
|
129
|
+
if item in ignore_list or item.startswith("."):
|
|
130
|
+
continue
|
|
131
|
+
|
|
132
|
+
src = os.path.join(project_root, item)
|
|
133
|
+
dst = os.path.join(python_dir, item)
|
|
134
|
+
|
|
135
|
+
# Skip if it is the target android dir itself (redundancy check)
|
|
136
|
+
if os.path.abspath(src) == os.path.abspath(target_android_dir):
|
|
137
|
+
continue
|
|
138
|
+
|
|
139
|
+
if os.path.isfile(src):
|
|
140
|
+
# Only copy python-related files or config
|
|
141
|
+
if src.endswith((".py", ".json", ".yaml", ".toml", ".env")):
|
|
142
|
+
shutil.copy2(src, dst)
|
|
143
|
+
elif os.path.isdir(src):
|
|
144
|
+
# Recursive copy for submodules/packages
|
|
145
|
+
if os.path.exists(dst):
|
|
146
|
+
shutil.rmtree(dst)
|
|
147
|
+
shutil.copytree(
|
|
148
|
+
src, dst, ignore=shutil.ignore_patterns("__pycache__", "*.pyc")
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# 2b. Vendor Dependencies (venv site-packages)
|
|
152
|
+
# We need to copy packages from the local env to android
|
|
153
|
+
# Try to find 'env' or 'venv'
|
|
154
|
+
venv_dir = None
|
|
155
|
+
for vname in ["env", "venv", ".venv"]:
|
|
156
|
+
vpath = os.path.join(project_root, vname)
|
|
157
|
+
if os.path.exists(vpath) and os.path.isdir(vpath):
|
|
158
|
+
venv_dir = vpath
|
|
159
|
+
break
|
|
160
|
+
|
|
161
|
+
if venv_dir:
|
|
162
|
+
# Find site-packages
|
|
163
|
+
# Windows: env/Lib/site-packages
|
|
164
|
+
# Unix: env/lib/pythonX.Y/site-packages
|
|
165
|
+
sp_candidates = [
|
|
166
|
+
os.path.join(venv_dir, "Lib", "site-packages"),
|
|
167
|
+
]
|
|
168
|
+
# Unix check
|
|
169
|
+
lib_unix = os.path.join(venv_dir, "lib")
|
|
170
|
+
if os.path.exists(lib_unix):
|
|
171
|
+
for d in os.listdir(lib_unix):
|
|
172
|
+
if d.startswith("python"):
|
|
173
|
+
sp_candidates.append(os.path.join(lib_unix, d, "site-packages"))
|
|
174
|
+
|
|
175
|
+
source_sp = None
|
|
176
|
+
for cand in sp_candidates:
|
|
177
|
+
if os.path.exists(cand):
|
|
178
|
+
source_sp = cand
|
|
179
|
+
break
|
|
180
|
+
|
|
181
|
+
if source_sp:
|
|
182
|
+
console.print(
|
|
183
|
+
f" [Deps] Copying dependencies from {escape(os.path.relpath(source_sp, project_root))}...",
|
|
184
|
+
style="dim",
|
|
185
|
+
)
|
|
186
|
+
# Copy everything except pip, setuptools, wheel, pkg_resources, __pycache__
|
|
187
|
+
# And pytron (we handle it specifically later)
|
|
188
|
+
ignore_deps = [
|
|
189
|
+
"pip",
|
|
190
|
+
"setuptools",
|
|
191
|
+
"wheel",
|
|
192
|
+
"pkg_resources",
|
|
193
|
+
"pytron",
|
|
194
|
+
"_distutils_hack",
|
|
195
|
+
]
|
|
196
|
+
|
|
197
|
+
for item in os.listdir(source_sp):
|
|
198
|
+
if item.startswith(".") or item == "__pycache__":
|
|
199
|
+
continue
|
|
200
|
+
if item in ignore_deps:
|
|
201
|
+
continue
|
|
202
|
+
if item.endswith(".dist-info"):
|
|
203
|
+
continue # Skip metadata for now to save space/time? Actually needed for importlib.metadata
|
|
204
|
+
|
|
205
|
+
# Actually we NEED dist-info for importlib.metadata to work in step 5!
|
|
206
|
+
# So let's keep it.
|
|
207
|
+
|
|
208
|
+
if any(item.startswith(x) for x in ignore_deps):
|
|
209
|
+
continue
|
|
210
|
+
|
|
211
|
+
src = os.path.join(source_sp, item)
|
|
212
|
+
dst = os.path.join(
|
|
213
|
+
site_packages_dir, item
|
|
214
|
+
) # assets/python/site-packages
|
|
215
|
+
|
|
216
|
+
if os.path.isdir(src):
|
|
217
|
+
if os.path.exists(dst):
|
|
218
|
+
shutil.rmtree(dst)
|
|
219
|
+
shutil.copytree(
|
|
220
|
+
src,
|
|
221
|
+
dst,
|
|
222
|
+
ignore=shutil.ignore_patterns("__pycache__", "*.pyc"),
|
|
223
|
+
)
|
|
224
|
+
else:
|
|
225
|
+
shutil.copy2(src, dst)
|
|
226
|
+
else:
|
|
227
|
+
console.print(
|
|
228
|
+
" [Deps] No virtual environment found (checked env, venv). Skipping dependency copy.",
|
|
229
|
+
style="warning",
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# 3. Vendor Pytron Library
|
|
233
|
+
# Check if we are running in Dev Mode (project_root contains pytron package source)
|
|
234
|
+
local_pytron_source = None
|
|
235
|
+
|
|
236
|
+
# Candidate 1: Inside current project? (unlikely but possible)
|
|
237
|
+
cand1 = os.path.join(project_root, "pytron")
|
|
238
|
+
|
|
239
|
+
# Candidate 2: Sibling directory? (d:\playground\test-android -> d:\playground\pytron)
|
|
240
|
+
# This is the Repo Root
|
|
241
|
+
cand2_repo = os.path.join(os.path.dirname(project_root), "pytron")
|
|
242
|
+
# This is the Package Root
|
|
243
|
+
cand2_pkg = os.path.join(cand2_repo, "pytron")
|
|
244
|
+
|
|
245
|
+
# Candidate 3: The root of the running code
|
|
246
|
+
# pytron/platforms/android/ops/sync.py -> pytron/
|
|
247
|
+
pytron_root = Path(__file__).resolve().parent.parent.parent.parent
|
|
248
|
+
|
|
249
|
+
if os.path.exists(cand1) and os.path.exists(os.path.join(cand1, "__init__.py")):
|
|
250
|
+
local_pytron_source = cand1
|
|
251
|
+
elif os.path.exists(cand2_pkg) and os.path.exists(
|
|
252
|
+
os.path.join(cand2_pkg, "__init__.py")
|
|
253
|
+
):
|
|
254
|
+
local_pytron_source = cand2_pkg
|
|
255
|
+
elif os.path.exists(os.path.join(pytron_root, "__init__.py")):
|
|
256
|
+
# Fallback to the code running this command (might be installed or local)
|
|
257
|
+
local_pytron_source = str(pytron_root)
|
|
258
|
+
|
|
259
|
+
# Decide source
|
|
260
|
+
# We check if local_pytron_source is NOT the system site-packages to label it "LOCAL"
|
|
261
|
+
|
|
262
|
+
is_dev = False
|
|
263
|
+
if local_pytron_source:
|
|
264
|
+
if local_pytron_source == cand1 or local_pytron_source == cand2_pkg:
|
|
265
|
+
is_dev = True
|
|
266
|
+
|
|
267
|
+
if local_pytron_source and os.path.exists(local_pytron_source) and is_dev:
|
|
268
|
+
pytron_pkg_dir = local_pytron_source
|
|
269
|
+
console.print(
|
|
270
|
+
f" [Vendor] Development Mode: Copying pytron library from LOCAL source: {escape(str(pytron_pkg_dir))}",
|
|
271
|
+
style="bold blue",
|
|
272
|
+
)
|
|
273
|
+
else:
|
|
274
|
+
# Fallback to standard import mechanism (safest for installed users)
|
|
275
|
+
import pytron
|
|
276
|
+
|
|
277
|
+
pytron_pkg_dir = os.path.dirname(pytron.__file__)
|
|
278
|
+
console.print(
|
|
279
|
+
f" [Vendor] Copying pytron library from INSTALLED package: {escape(str(pytron_pkg_dir))}",
|
|
280
|
+
style="dim",
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
target_pytron_dir = os.path.join(site_packages_dir, "pytron")
|
|
284
|
+
|
|
285
|
+
if os.path.exists(target_pytron_dir):
|
|
286
|
+
shutil.rmtree(target_pytron_dir)
|
|
287
|
+
|
|
288
|
+
# Ignore 'dependencies' (heavy dlls) and standard cruft
|
|
289
|
+
shutil.copytree(
|
|
290
|
+
pytron_pkg_dir,
|
|
291
|
+
target_pytron_dir,
|
|
292
|
+
ignore=shutil.ignore_patterns(
|
|
293
|
+
"__pycache__", "*.pyc", "installer", "commands", "dependencies"
|
|
294
|
+
),
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
# AGGRESSIVE CLEANUP: Remove platform implementations from device
|
|
298
|
+
# We only need 'interface.py' and '__init__.py' in platforms
|
|
299
|
+
# Everything else (windows, linux, darwin, especially ANDROID/SHELL) should be purged
|
|
300
|
+
target_platforms = os.path.join(target_pytron_dir, "platforms")
|
|
301
|
+
if os.path.exists(target_platforms):
|
|
302
|
+
for item in os.listdir(target_platforms):
|
|
303
|
+
if item.endswith(".py") or item == "__pycache__":
|
|
304
|
+
continue
|
|
305
|
+
# Delete checking it is a dir
|
|
306
|
+
p_item = os.path.join(target_platforms, item)
|
|
307
|
+
if os.path.isdir(p_item):
|
|
308
|
+
shutil.rmtree(p_item)
|
|
309
|
+
console.print(
|
|
310
|
+
" [Vendor] Pruned 'platforms' directory (removed shell templates/native impls).",
|
|
311
|
+
style="dim",
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
# 4. Unzip Standard Library & Fix .so files (User Request)
|
|
315
|
+
# We do this at build time to avoid runtime unzip and to fix filenames
|
|
316
|
+
python_zip = os.path.join(python_dir, "python314.zip")
|
|
317
|
+
|
|
318
|
+
# If python314.zip is missing, try to provision it using AndroidBuilder (BeeWare support)
|
|
319
|
+
if not os.path.exists(python_zip) and not os.path.exists(
|
|
320
|
+
os.path.join(python_dir, "Lib")
|
|
321
|
+
):
|
|
322
|
+
console.print(
|
|
323
|
+
" [StdLib] Python runtime not found. Provisioning via BeeWare...",
|
|
324
|
+
style="dim",
|
|
325
|
+
)
|
|
326
|
+
try:
|
|
327
|
+
builder = AndroidBuilder(arch="aarch64")
|
|
328
|
+
# This downloads to a cache dir
|
|
329
|
+
cache_dir = os.path.join(target_android_dir, "wheels_cache")
|
|
330
|
+
os.makedirs(cache_dir, exist_ok=True)
|
|
331
|
+
|
|
332
|
+
support_pkg_dir = builder.setup_python_target(cache_dir)
|
|
333
|
+
|
|
334
|
+
# Copy from support package to assets/python
|
|
335
|
+
# BeeWare structure: /python/lib/python3.x/...
|
|
336
|
+
# We need to map it to our structure.
|
|
337
|
+
# Usually support package has a 'python' folder or similar.
|
|
338
|
+
|
|
339
|
+
# Let's look for 'lib' or 'usr/lib'
|
|
340
|
+
# BeeWare support package structure varies.
|
|
341
|
+
# Usually: /python/lib/python3.X
|
|
342
|
+
|
|
343
|
+
# Simple recursive copy of the whole thing into python_dir?
|
|
344
|
+
# Our python_dir expects: Lib/, lib-dynload/, etc.
|
|
345
|
+
|
|
346
|
+
# Let's just copy everything from the support package root to python_dir
|
|
347
|
+
if os.path.exists(support_pkg_dir):
|
|
348
|
+
shutil.copytree(support_pkg_dir, python_dir, dirs_exist_ok=True)
|
|
349
|
+
console.print(
|
|
350
|
+
" [StdLib] Provisioned Python runtime.", style="success"
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
except Exception as e:
|
|
354
|
+
console.print(
|
|
355
|
+
f" [StdLib] Failed to provision Python: {e}", style="error"
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
if os.path.exists(python_zip):
|
|
359
|
+
console.print(f" [StdLib] Unzipping {python_zip}...", style="dim")
|
|
360
|
+
try:
|
|
361
|
+
with zipfile.ZipFile(python_zip, "r") as zip_ref:
|
|
362
|
+
zip_ref.extractall(python_dir)
|
|
363
|
+
|
|
364
|
+
console.print(
|
|
365
|
+
" [StdLib] Extraction complete. Removing zip.", style="dim"
|
|
366
|
+
)
|
|
367
|
+
os.remove(python_zip)
|
|
368
|
+
|
|
369
|
+
except Exception as e:
|
|
370
|
+
log(f" [StdLib] Error unzipping: {e}", style="error")
|
|
371
|
+
|
|
372
|
+
# 4b. ALWAYS Fix .so filenames (Shared Libraries)
|
|
373
|
+
# We do this regardless of whether we just unzipped or if it was already there
|
|
374
|
+
search_paths = [
|
|
375
|
+
os.path.join(python_dir, "Lib", "lib-dynload"),
|
|
376
|
+
os.path.join(python_dir, "lib-dynload"),
|
|
377
|
+
]
|
|
378
|
+
|
|
379
|
+
for lib_dynload in search_paths:
|
|
380
|
+
if os.path.exists(lib_dynload):
|
|
381
|
+
console.print(
|
|
382
|
+
f" [Fixes] Scanning for .so files in {escape(os.path.basename(lib_dynload))}...",
|
|
383
|
+
style="dim",
|
|
384
|
+
)
|
|
385
|
+
count = 0
|
|
386
|
+
for f in os.listdir(lib_dynload):
|
|
387
|
+
if ".cpython-" in f and f.endswith(".so"):
|
|
388
|
+
# e.g. _struct.cpython-313-android-x86_64.so -> _struct.so
|
|
389
|
+
parts = f.split(".cpython-")
|
|
390
|
+
simple_name = parts[0] + ".so"
|
|
391
|
+
src = os.path.join(lib_dynload, f)
|
|
392
|
+
dst = os.path.join(lib_dynload, simple_name)
|
|
393
|
+
|
|
394
|
+
if not os.path.exists(dst):
|
|
395
|
+
try:
|
|
396
|
+
os.rename(src, dst)
|
|
397
|
+
count += 1
|
|
398
|
+
except Exception as e:
|
|
399
|
+
console.print(
|
|
400
|
+
f" Failed rename {f}: {e}",
|
|
401
|
+
style="error",
|
|
402
|
+
)
|
|
403
|
+
if count > 0:
|
|
404
|
+
console.print(
|
|
405
|
+
f" Renamed {count} shared libraries for Android compatibility.",
|
|
406
|
+
style="dim",
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
# Verify critical modules
|
|
410
|
+
critical_modules = ["_random", "_ctypes", "_socket", "_ssl"]
|
|
411
|
+
for mod in critical_modules:
|
|
412
|
+
if os.path.exists(os.path.join(lib_dynload, f"{mod}.so")):
|
|
413
|
+
console.print(
|
|
414
|
+
f" [OK] Found critical module: {mod}.so",
|
|
415
|
+
style="success",
|
|
416
|
+
)
|
|
417
|
+
else:
|
|
418
|
+
console.print(
|
|
419
|
+
f" [WARNING] Missing critical module: {mod}.so (Runtime fails likely)",
|
|
420
|
+
style="warning",
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
# 5. Native Extensions Handling
|
|
424
|
+
if not native:
|
|
425
|
+
console.print(
|
|
426
|
+
" [Native] Skipping native extension compilation (Use --native to enable).",
|
|
427
|
+
style="dim",
|
|
428
|
+
)
|
|
429
|
+
else:
|
|
430
|
+
console.print(
|
|
431
|
+
" [Native] Scanning for native extensions to cross-compile...",
|
|
432
|
+
style="dim",
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
# We need the path to headers for the builder
|
|
436
|
+
# They should be in the shell template we just copied/synced to
|
|
437
|
+
# android/app/src/main/cpp/include
|
|
438
|
+
cpp_include = os.path.join(
|
|
439
|
+
target_android_dir, "app", "src", "main", "cpp", "include"
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
# Cache dir for wheels to avoid rebuilding every sync
|
|
443
|
+
cache_dir = os.path.join(target_android_dir, "wheels_cache")
|
|
444
|
+
os.makedirs(cache_dir, exist_ok=True)
|
|
445
|
+
|
|
446
|
+
# Get mapping of module -> distribution (e.g. cv2 -> opencv-python)
|
|
447
|
+
# We use the current environment because that's where we copied from.
|
|
448
|
+
try:
|
|
449
|
+
packages_dists = importlib.metadata.packages_distributions()
|
|
450
|
+
except Exception:
|
|
451
|
+
packages_dists = {}
|
|
452
|
+
|
|
453
|
+
# Scan site-packages
|
|
454
|
+
builder = None
|
|
455
|
+
|
|
456
|
+
for item in os.listdir(site_packages_dir):
|
|
457
|
+
item_path = os.path.join(site_packages_dir, item)
|
|
458
|
+
if not os.path.isdir(item_path):
|
|
459
|
+
continue
|
|
460
|
+
|
|
461
|
+
if item == "pytron":
|
|
462
|
+
continue # We handle pytron separately
|
|
463
|
+
|
|
464
|
+
# Check for binaries
|
|
465
|
+
# recursive glob for .pyd or .so
|
|
466
|
+
# Note: valid android .so files might already be there if we synced before?
|
|
467
|
+
# But sync deletes and recopies, so they are definitely from host.
|
|
468
|
+
|
|
469
|
+
has_binary = False
|
|
470
|
+
for root, dirs, files in os.walk(item_path):
|
|
471
|
+
for f in files:
|
|
472
|
+
if f.endswith(".pyd") or (f.endswith(".so") and "android" not in f):
|
|
473
|
+
has_binary = True
|
|
474
|
+
break
|
|
475
|
+
if has_binary:
|
|
476
|
+
break
|
|
477
|
+
|
|
478
|
+
if has_binary:
|
|
479
|
+
dist_name = packages_dists.get(item, [item])[0]
|
|
480
|
+
console.print(
|
|
481
|
+
f" [Native] Found binary extension in '{item}' (Package: {dist_name})",
|
|
482
|
+
style="info",
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
# Check Cache
|
|
486
|
+
# Look for wheel starting with dist_name in cache
|
|
487
|
+
# e.g. numpy-*.whl
|
|
488
|
+
cached_wheels = glob.glob(os.path.join(cache_dir, f"{dist_name}-*.whl"))
|
|
489
|
+
|
|
490
|
+
target_wheel = None
|
|
491
|
+
if cached_wheels:
|
|
492
|
+
# Filter for Android/Linux/ARM64 wheels
|
|
493
|
+
valid_wheels = [
|
|
494
|
+
w
|
|
495
|
+
for w in cached_wheels
|
|
496
|
+
if "aarch64" in w or "android" in w or "linux" in w
|
|
497
|
+
]
|
|
498
|
+
if valid_wheels:
|
|
499
|
+
valid_wheels.sort(key=os.path.getmtime)
|
|
500
|
+
target_wheel = valid_wheels[-1]
|
|
501
|
+
console.print(
|
|
502
|
+
f" Using cached wheel: {os.path.basename(target_wheel)}",
|
|
503
|
+
style="dim",
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
if not target_wheel:
|
|
507
|
+
# Build it
|
|
508
|
+
if not builder:
|
|
509
|
+
console.print(
|
|
510
|
+
" Initializing Android NDK Builder...",
|
|
511
|
+
style="dim",
|
|
512
|
+
)
|
|
513
|
+
builder = AndroidBuilder(arch="aarch64")
|
|
514
|
+
if not builder.ndk_info:
|
|
515
|
+
console.print(
|
|
516
|
+
" [WARNING] Android NDK or Nano-Sysroot fallback failed. Skipping native build. App may crash.",
|
|
517
|
+
style="warning",
|
|
518
|
+
)
|
|
519
|
+
continue
|
|
520
|
+
|
|
521
|
+
console.print(
|
|
522
|
+
f" Compiling {dist_name} for Android (ARM64)... This may take a while.",
|
|
523
|
+
style="info",
|
|
524
|
+
)
|
|
525
|
+
if builder.build_wheel(dist_name, cache_dir, cpp_include):
|
|
526
|
+
# Find the generated wheel
|
|
527
|
+
generated = glob.glob(
|
|
528
|
+
os.path.join(cache_dir, f"{dist_name}-*.whl")
|
|
529
|
+
)
|
|
530
|
+
if generated:
|
|
531
|
+
valid_generated = [
|
|
532
|
+
w
|
|
533
|
+
for w in generated
|
|
534
|
+
if "aarch64" in w or "android" in w or "linux" in w
|
|
535
|
+
]
|
|
536
|
+
if valid_generated:
|
|
537
|
+
valid_generated.sort(key=os.path.getmtime)
|
|
538
|
+
target_wheel = valid_generated[-1]
|
|
539
|
+
else:
|
|
540
|
+
console.print(
|
|
541
|
+
f" [FAILED] Could not build {dist_name}.",
|
|
542
|
+
style="error",
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
if target_wheel:
|
|
546
|
+
console.print(
|
|
547
|
+
f" Installing {dist_name} to assets...", style="dim"
|
|
548
|
+
)
|
|
549
|
+
try:
|
|
550
|
+
with zipfile.ZipFile(target_wheel, "r") as z:
|
|
551
|
+
z.extractall(site_packages_dir)
|
|
552
|
+
except Exception as e:
|
|
553
|
+
console.print(
|
|
554
|
+
f" Error installing wheel {os.path.basename(target_wheel)}: {e}",
|
|
555
|
+
style="error",
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
# 6. Finalize Dependency Flattening: Copy flattened libs to jniLibs
|
|
559
|
+
if builder and builder.flattened_libs_dir:
|
|
560
|
+
jni_libs_dir = os.path.join(
|
|
561
|
+
target_android_dir, "app", "src", "main", "jniLibs", "arm64-v8a"
|
|
562
|
+
)
|
|
563
|
+
os.makedirs(jni_libs_dir, exist_ok=True)
|
|
564
|
+
|
|
565
|
+
console.print(
|
|
566
|
+
f" [Native] Finalizing Dependency Flattening (Syncing jniLibs)...",
|
|
567
|
+
style="dim",
|
|
568
|
+
)
|
|
569
|
+
# 6a. Copy flattened libraries from builder cache
|
|
570
|
+
for lib_file in os.listdir(builder.flattened_libs_dir):
|
|
571
|
+
src = os.path.join(builder.flattened_libs_dir, lib_file)
|
|
572
|
+
dst = os.path.join(jni_libs_dir, lib_file)
|
|
573
|
+
if not os.path.exists(dst) or os.path.getmtime(src) > os.path.getmtime(
|
|
574
|
+
dst
|
|
575
|
+
):
|
|
576
|
+
shutil.copy2(src, dst)
|
|
577
|
+
console.print(
|
|
578
|
+
f" Added flattened lib: {lib_file}", style="dim"
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
# 6b. Ensure libpython is also in jniLibs if provided by builder (Minimalist approach)
|
|
582
|
+
if (
|
|
583
|
+
hasattr(builder, "ndk_info")
|
|
584
|
+
and builder.ndk_info
|
|
585
|
+
and builder.ndk_info.get("lib")
|
|
586
|
+
):
|
|
587
|
+
libpy_src = os.path.join(builder.ndk_info["lib"], "libpython3.14.so")
|
|
588
|
+
if os.path.exists(libpy_src):
|
|
589
|
+
shutil.copy2(
|
|
590
|
+
libpy_src, os.path.join(jni_libs_dir, "libpython3.14.so")
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
# 6c. ALWAYS ensure libpython3.14.so is in jniLibs/arm64-v8a if not already there
|
|
594
|
+
# This is critical for the native bridge to link against it, even if no other extensions are built.
|
|
595
|
+
jni_libs_arm64 = os.path.join(
|
|
596
|
+
target_android_dir, "app", "src", "main", "jniLibs", "arm64-v8a"
|
|
597
|
+
)
|
|
598
|
+
os.makedirs(jni_libs_arm64, exist_ok=True)
|
|
599
|
+
libpy_dst = os.path.join(jni_libs_arm64, "libpython3.14.so")
|
|
600
|
+
|
|
601
|
+
# Check for local workspace android-python-3.14 (Common in this user's env)
|
|
602
|
+
workspace_root = os.path.dirname(project_root)
|
|
603
|
+
local_python_dir = os.path.join(workspace_root, "android-python-3.14")
|
|
604
|
+
|
|
605
|
+
if not os.path.exists(libpy_dst):
|
|
606
|
+
local_lib_path = os.path.join(
|
|
607
|
+
local_python_dir, "jniLibs", "arm64-v8a", "libpython3.14.so"
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
if os.path.exists(local_lib_path):
|
|
611
|
+
shutil.copy2(local_lib_path, libpy_dst)
|
|
612
|
+
console.print(
|
|
613
|
+
f" [Native] Copied libpython3.14.so from local workspace: {escape(str(local_lib_path))}",
|
|
614
|
+
style="success",
|
|
615
|
+
)
|
|
616
|
+
else:
|
|
617
|
+
# Fallback: Initialize builder just to find the lib if missing
|
|
618
|
+
if not builder:
|
|
619
|
+
try:
|
|
620
|
+
builder = AndroidBuilder(arch="aarch64")
|
|
621
|
+
if builder.ndk_info and builder.ndk_info.get("lib"):
|
|
622
|
+
libpy_src = os.path.join(
|
|
623
|
+
builder.ndk_info["lib"], "libpython3.14.so"
|
|
624
|
+
)
|
|
625
|
+
if os.path.exists(libpy_src):
|
|
626
|
+
shutil.copy2(libpy_src, libpy_dst)
|
|
627
|
+
console.print(
|
|
628
|
+
" [Native] Copied libpython3.14.so to jniLibs (Critical for bridge).",
|
|
629
|
+
style="dim",
|
|
630
|
+
)
|
|
631
|
+
except Exception:
|
|
632
|
+
pass
|
|
633
|
+
|
|
634
|
+
# 6d. Ensure libffi.so is present (Required by libpython3.14.so)
|
|
635
|
+
libffi_dst = os.path.join(jni_libs_arm64, "libffi.so")
|
|
636
|
+
if not os.path.exists(libffi_dst):
|
|
637
|
+
ffi_candidates = [
|
|
638
|
+
os.path.join(local_python_dir, "libffi.so"),
|
|
639
|
+
os.path.join(local_python_dir, "lib-dynload", "libffi.so"),
|
|
640
|
+
os.path.join(local_python_dir, "jniLibs", "arm64-v8a", "libffi.so"),
|
|
641
|
+
]
|
|
642
|
+
for ffi in ffi_candidates:
|
|
643
|
+
if os.path.exists(ffi):
|
|
644
|
+
shutil.copy2(ffi, libffi_dst)
|
|
645
|
+
console.print(
|
|
646
|
+
f" [Native] Copied libffi.so from local workspace: {escape(str(ffi))}",
|
|
647
|
+
style="success",
|
|
648
|
+
)
|
|
649
|
+
break
|
|
650
|
+
|
|
651
|
+
# 7. Inject Project Metadata (Name, Author, Version)
|
|
652
|
+
log(" [Metadata] Injecting project details...", style="dim")
|
|
653
|
+
try:
|
|
654
|
+
settings_path = os.path.join(project_root, "settings.json")
|
|
655
|
+
config = {}
|
|
656
|
+
if os.path.exists(settings_path):
|
|
657
|
+
with open(settings_path, "r") as f:
|
|
658
|
+
config = json.load(f)
|
|
659
|
+
|
|
660
|
+
app_title = config.get("title", "Pytron App")
|
|
661
|
+
author = config.get("author", "PytronUser")
|
|
662
|
+
version = config.get("version", "1.0.0") # Fallback
|
|
663
|
+
|
|
664
|
+
# Sanitize for IDs
|
|
665
|
+
safe_title = (
|
|
666
|
+
"".join(c if c.isalnum() else "_" for c in app_title).lower().strip("_")
|
|
667
|
+
)
|
|
668
|
+
safe_author = (
|
|
669
|
+
"".join(c if c.isalnum() else "_" for c in author).lower().strip("_")
|
|
670
|
+
)
|
|
671
|
+
|
|
672
|
+
# 7a. Update strings.xml (App Name)
|
|
673
|
+
res_val_dir = os.path.join(
|
|
674
|
+
target_android_dir, "app", "src", "main", "res", "values"
|
|
675
|
+
)
|
|
676
|
+
os.makedirs(res_val_dir, exist_ok=True)
|
|
677
|
+
strings_xml = os.path.join(res_val_dir, "strings.xml")
|
|
678
|
+
|
|
679
|
+
strings_content = f"""<?xml version="1.0" encoding="utf-8"?>
|
|
680
|
+
<resources>
|
|
681
|
+
<string name="app_name">{app_title}</string>
|
|
682
|
+
</resources>"""
|
|
683
|
+
with open(strings_xml, "w") as f:
|
|
684
|
+
f.write(strings_content)
|
|
685
|
+
|
|
686
|
+
# 7b. Update Manifest (Label)
|
|
687
|
+
manifest_path = os.path.join(
|
|
688
|
+
target_android_dir, "app", "src", "main", "AndroidManifest.xml"
|
|
689
|
+
)
|
|
690
|
+
if os.path.exists(manifest_path):
|
|
691
|
+
with open(manifest_path, "r") as f:
|
|
692
|
+
m_content = f.read()
|
|
693
|
+
|
|
694
|
+
# Replace hardcoded label with reference
|
|
695
|
+
if 'android:label="Pytron App"' in m_content:
|
|
696
|
+
m_content = m_content.replace(
|
|
697
|
+
'android:label="Pytron App"', 'android:label="@string/app_name"'
|
|
698
|
+
)
|
|
699
|
+
with open(manifest_path, "w") as f:
|
|
700
|
+
f.write(m_content)
|
|
701
|
+
|
|
702
|
+
# 7c. Update build.gradle (Version & ID)
|
|
703
|
+
gradle_path = os.path.join(target_android_dir, "app", "build.gradle")
|
|
704
|
+
if os.path.exists(gradle_path):
|
|
705
|
+
with open(gradle_path, "r") as f:
|
|
706
|
+
g_lines = f.readlines()
|
|
707
|
+
|
|
708
|
+
new_lines = []
|
|
709
|
+
app_id = f"com.{safe_author}.{safe_title}"
|
|
710
|
+
for line in g_lines:
|
|
711
|
+
if "versionName" in line:
|
|
712
|
+
new_lines.append(f' versionName "{version}"\n')
|
|
713
|
+
elif "applicationId" in line:
|
|
714
|
+
new_lines.append(f' applicationId "{app_id}"\n')
|
|
715
|
+
else:
|
|
716
|
+
new_lines.append(line)
|
|
717
|
+
|
|
718
|
+
with open(gradle_path, "w") as f:
|
|
719
|
+
f.writelines(new_lines)
|
|
720
|
+
console.print(
|
|
721
|
+
f" Updated Metadata: ID={app_id}, Ver={version}, Name={app_title}",
|
|
722
|
+
style="dim",
|
|
723
|
+
)
|
|
724
|
+
|
|
725
|
+
# 7d. Update App Icon
|
|
726
|
+
app_icon_rel = config.get("icon")
|
|
727
|
+
if app_icon_rel:
|
|
728
|
+
app_icon_src = os.path.join(project_root, app_icon_rel)
|
|
729
|
+
if os.path.exists(app_icon_src):
|
|
730
|
+
console.print(
|
|
731
|
+
f" Updating App Icon: {escape(str(app_icon_rel))}",
|
|
732
|
+
style="dim",
|
|
733
|
+
)
|
|
734
|
+
# Android template currently uses mipmap-xxhdpi
|
|
735
|
+
mipmap_dir = os.path.join(
|
|
736
|
+
target_android_dir, "app", "src", "main", "res", "mipmap-xxhdpi"
|
|
737
|
+
)
|
|
738
|
+
os.makedirs(mipmap_dir, exist_ok=True)
|
|
739
|
+
|
|
740
|
+
# Copy to both standard and round icon names
|
|
741
|
+
shutil.copy2(app_icon_src, os.path.join(mipmap_dir, "ic_launcher.png"))
|
|
742
|
+
shutil.copy2(
|
|
743
|
+
app_icon_src, os.path.join(mipmap_dir, "ic_launcher_round.png")
|
|
744
|
+
)
|
|
745
|
+
else:
|
|
746
|
+
console.print(
|
|
747
|
+
f" Warning: Icon file not found at {escape(str(app_icon_src))}",
|
|
748
|
+
style="warning",
|
|
749
|
+
)
|
|
750
|
+
|
|
751
|
+
except Exception as e:
|
|
752
|
+
console.print(
|
|
753
|
+
f" Warning: Failed to inject metadata: {e}", style="warning"
|
|
754
|
+
)
|
|
755
|
+
|
|
756
|
+
# 8. Generate Build Timestamp for Smart Caching
|
|
757
|
+
try:
|
|
758
|
+
timestamp = str(int(time.time()))
|
|
759
|
+
ts_path = os.path.join(python_dir, "build_timestamp.txt")
|
|
760
|
+
with open(ts_path, "w") as f:
|
|
761
|
+
f.write(timestamp)
|
|
762
|
+
console.print(
|
|
763
|
+
f" [Cache] Generated build timestamp: {timestamp}", style="dim"
|
|
764
|
+
)
|
|
765
|
+
except Exception as e:
|
|
766
|
+
console.print(
|
|
767
|
+
f" [Cache] Failed to generate timestamp: {e}", style="warning"
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
log("Sync complete.", style="success")
|