# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['pyportable_installer',
 'pyportable_installer.checkup',
 'pyportable_installer.compilers',
 'pyportable_installer.compilers.lib.pyportable_runtime_py310.pyportable_runtime',
 'pyportable_installer.compilers.lib.pyportable_runtime_py38.pyportable_runtime',
 'pyportable_installer.compilers.lib.pyportable_runtime_py39.pyportable_runtime',
 'pyportable_installer.main_flow',
 'pyportable_installer.main_flow.step1',
 'pyportable_installer.main_flow.step2',
 'pyportable_installer.main_flow.step3',
 'pyportable_installer.main_flow.step3.step3_1',
 'pyportable_installer.main_flow.step3.step3_2',
 'pyportable_installer.main_flow.step3.step3_3',
 'pyportable_installer.main_flow.step4',
 'pyportable_installer.template.pylauncher',
 'pyportable_installer.user_interface']

package_data = \
{'': ['*'],
 'pyportable_installer': ['template/*', 'template/depsland/*'],
 'pyportable_installer.user_interface': ['qml/*']}

install_requires = \
['embed-python-manager',
 'lk-logger>=5.0.1,<6.0.0',
 'lk-utils>=2.2.0,<3.0.0',
 'pyportable-crypto>=1.0.0,<2.0.0']

extras_require = \
{':platform_system == "Windows"': ['gen-exe'],
 'all': ['pillow', 'pyarmor', 'pysimplegui'],
 'gui': ['pysimplegui']}

setup_kwargs = {
    'name': 'pyportable-installer',
    'version': '4.3.1',
    'description': 'Build and distribute portable Python application by all-in-one configuration file.',
    'long_description': '# PyPortable Installer\n\n> pyportable-installer 提供源码版和直装版两个版本供使用. 请根据需要选择:\n>\n> | 版本类型 | 说明 | 体积 | 下载方式 |\n> | -------- | ---- | ---- | -------- |\n> | 第三方库 | 适合开发者在 Python 工程中引入 | 4MB | `pip install pyportable-installer` |\n> | 独立免安装版 (标准版) | 用户电脑上需预先安装 [Depsland][1] 软件, 安装过程需要联网 | 4.5MB | 见本项目 Release 页面 |\n> | 独立免安装版 (完整版) | 该压缩包内置了 [Depsland][1]. 下载后解压即可使用, 无需 Python 开发环境, 完全离线安装 | 47MB | 见本项目 Release 页面 |\n>\n> `python -m pyportable_installer` 快速演示:\n>\n> ![](./.assets/QCdvnW6kJK.gif)\n\n--------------------------------------------------------------------------------\n\n`pyportable-installer` 是一个 Python 项目打包工具, 它受启发于 [poetry](https://github.com/python-poetry/poetry), 并旨在作为 [pyinstaller](https://github.com/pyinstaller/pyinstaller) 的替代品出现.\n\n`pyportable-installer` 通过一个 **all-in-one 配置文件** 来管理打包工作, 通过该文件可将您的 Python 项目打包为 "免安装版" 的软件, 用户无需安装 Python 程序或第三方依赖 (注: 该特性需要您在配置中启用虚拟环境选项), 真正做到 "开箱即用, 双击启动".\n\n# 特性\n\n`pyportable-installer` 具有以下特点:\n\n1.  打包后的体积很小. 在不附带虚拟环境的情况下, 与您的源代码同等量级 (这通常只有几百 KB ~ 几 MB 之间)\n\n2.  易于使用. 您只需要维护一个 pyproject.json 配置文件即可. 在快速迭代的环境下, 您甚至只需要更改版本号就能立即生成新的打包结果\n\n3.  打包速度快. 一个中小型项目在数秒间即可生成打包结果\n\n4.  源代码加密. `pyportable-installer` 内置了多种编译和混淆器供选择, 其中推荐使用 [pyportable-crypto](https://github.com/likianta/pyportable-crypto) 库或 [pyarmor](https://github.com/dashingsoft/pyarmor) 库对源代码进行混淆, 保障代码安全\n\n5.  开箱即用. `pyportable-installer` 打包后的目录结构非常清晰, 如下示例:\n\n    ![](.assets/20210914-105505.png)\n\n    ```\n    my_project\n    |= dist\n       |= hello_world_0.1.0  # 打包结果\n          |= build  # 一些构建信息\n             |- mainifest.json\n          |= src    # 您的源代码将被编译并放置在此目录下\n             |- ...\n          |= lib    # 一些自定义的第三方库会放在此目录下, 并在程序启动时加载\n             |= pyportable_runtime  # 用于解算加密后的源代码, 保障代码安全\n                |- ...\n          |= venv   # 自带的虚拟环境 (可选)\n             |- ...\n          |- README.html    # 自述文档\n          |- Hello.exe      # 双击即可启动!\n    ```\n\n6.  不破坏相对路径. 在打包后的 `src` 目录下, 所有文件夹仍然维持着原项目的目录结构. 程序在启动时会将工作目录切换到启动脚本所在的目录, 这意味着您在原项目中所使用的相对路径, 在打包后仍然保持一致\n\n7.  摆脱虚拟环境 (该特性仍处于实验阶段). 您可以在 配置文件/虚拟环境配置项 中启用 "[depsland][1]" 选项, 客户端在安装 depsland 软件后, 运行您发布的程序时会自动部署依赖, 这样真正做到打包体积控制, 加快分发并减轻用户下载负担\n\n8.  *无痛更新 (该特性将在后续版本提供). 双击软件目录下的 `checkup/update.pyd` 即可获取软件的最新版本*\n\n9.  *激活和授权 (该特性将在后续版本提供). 该特性由 pyarmor 提供, `pyportable-installer` 将其同样整合在 all-in-one 配置文件中*\n\n# 工作流程\n\n它的流程可以概括如下:\n\n1.  准备您要打包的项目\n\n2.  在项目的根目录下新建一个 all-in-one 配置文件: "pyproject.json"\n\n    1.  该文件名是可以任取的\n\n    2.  [这里](./pyportable_installer/template/pyproject.json) 有一个模板文件可供使用. 以及一个 [手册](./docs/pyproject-template-manual.zh.md) 供查阅每个选项的格式和作用\n\n3.  通过 `pyportable-installer` 处理此配置文件, 完成打包:\n\n    ```py\n    from pyportable_installer import full_build\n    full_build(\'./pyproject.json\')\n    ```\n\n`pyportable-installer` 会为您的项目生成:\n\n> 注: 这里演示的是启用 `pyportable-crypto` 选项加密的效果.\n\n1.  加密后的源代码文件\n\n    1.  加密后的文件后缀仍然是 \'.py\'\n\n    2.  加密后的文件由 `~/lib/pyportable_runtime` 包在运行时解码\n\n    3.  使用文本编辑器打开加密文件, 其密文如下所示:  \n\n        ![](.assets/20210914-112055.png)\n\n2.  一个 exe 格式的启动器\n\n3.  自定义的启动器图标 (注: 缺省图标为 python.ico)\n\n4.  一个干净的虚拟环境 (这是可选的)\n\n5.  整个打包后的结果会以文件夹的形式存在\n\n之后, 您可以将该文件夹制作为压缩文件, 并作为 "免安装版" 的软件发布.\n\n# 安装和使用\n\n通过 pip 安装:\n\n```\npip install pyportable-installer\n```\n\n> 注意事项:\n> \n> 1. pyportable-installer 最新版本为 4.3.0+ (截至 2021-12-30)\n> 2. 上代版本 (3.3.3 及以前) 已不推荐使用\n> 3. pyportable-installer 需要 Python 3.8 及以上的解释器运行\n\n下面以一个 "Hello World" 项目为例, 介绍具体的打包工作:\n\n假设 "Hello World" 的项目结构如下:\n\n```\nhello_world_project\n|= data\n   |- names.txt\n|= dist\n|= hello_world\n   |- main.py\n   |  # def say_hello(file):\n   |  #     with open(file, \'r\') as f:\n   |  #         for name in f:\n   |  #             print(f\'Hello {name}!\')\n   |  #\n   |  # if __name__ == \'__main__\':\n   |  #     say_hello(\'../data/names.txt\')\n|- pyproject.json\n|- README.md\n```\n\n在项目根目录下新建 \'pyproject.json\' ([这里](./pyportable_installer/template/pyproject.json) 有一个模板文件可供使用), 填写以下内容:\n\n> 注: \'◆◇◆\' 标记的是必填的项, 其他可使用缺省设置.\n\n```json5\n{\n    // 注意: 凡是配置项中涉及到路径的填写, 均使用相对于本文件的相对路径, 或者使\n    // 用绝对路径. pyportable-installer 会自动将它们转换到打包目录的内部结构中.\n\n    // ◆◇◆ 应用名称 ◆◇◆\n    "app_name": "Hello World",\n    // ◆◇◆ 应用版本 ◆◇◆\n    "app_version": "0.1.0",\n    "description": "",\n    "authors": [],\n    "build": {\n        // ◆◇◆ 项目目录的入口 ◆◇◆\n        "proj_dir": "./hello_world",\n        // ◆◇◆ 打包结果放在哪里 ◆◇◆\n        //     注意打包结果的父目录必须事先存在, 以及打包结果目录事先应不存在.\n        //     否则打包活动将中止.\n        "dist_dir": "./dist/{app_name_snake}_{app_version}",\n        // ◆◇◆ 启动器配置 ◆◇◆\n        //  1. 启动器配置是一个字典.\n        //  2. 字典的键是要生成的启动器. 键可以使用花括号语法指代一个名称, 例如 \n        //     "{app_name}" 指代 "Hello World", "{app_name_lower}" 指代 "hello \n        //     world" 等 (详见配置指南).\n        //  3. 字典的值是该启动器的配置.\n        "launchers": {\n            "{app_name}": {\n                "file": "./hello_world/main.py",\n                "icon": "",\n                "function": "main",\n                "args": ["../data/names.txt"],\n                "kwargs": {}\n            }\n        },\n        "readme": "",\n        // ◆◇◆ 要加入到打包的附件 ◆◇◆\n        "attachments": {\n            "./data/names.txt": "assets"\n        },\n        "attachments_exclusions": [],\n        "attachments_exist_scheme": "override",\n        "module_paths": [],\n        "module_paths_scheme": "translate",\n        // ◆◇◆ 目标应用的 python 解释器版本 ◆◇◆\n        "python_version": "3.8",\n        "venv": {\n            "enable_venv": true,\n            "mode": "source_venv",\n            "options": {\n                "depsland": {\n                    "venv_name": "{app_name_lower}_venv",\n                    "venv_id": "",\n                    "requirements": [],\n                    "offline": false,\n                    "local": ""\n                },\n                "source_venv": {\n                    "path": "",\n                    "copy_venv": true\n                },\n                "pip": {\n                    "requirements": [],\n                    "pypi_url": "https://pypi.python.org/simple/",\n                    "offline": false,\n                    "local": ""\n                },\n                "embed_python": {\n                    "path": ""\n                }\n            }\n        },\n        "compiler": {\n            "name": "pyportable_crypto",\n            "options": {\n                "cythonize": {\n                    "c_compiler": "msvc",\n                    "python_path": "auto_detect"\n                },\n                "pyarmor": {\n                    "license": "trial",\n                    "obfuscate_level": 0\n                },\n                "pyc": {\n                    "optimize_level": 0\n                },\n                "pyportable_crypto": {\n                    "key": "{random}"\n                },\n                "zipapp": {\n                    "password": ""\n                }\n            }\n        },\n        "experimental_features": {\n            "add_pywin32_support": false,\n            "platform": "system_default"\n        },\n        "enable_console": true\n    },\n    "note": "",\n    "pyportable_installer_version": "4.3.0"\n}\n```\n\n*注: 更多用法请参考 [Pyproject Template Manual](./docs/pyproject-template-manual.zh.md).*\n\n运行以下代码即可生成打包结果:\n\n```py\nfrom pyportable_installer import full_build\nfull_build(\'pyproject.json\')\n\n# 当增量更新时, 运行以下:\n# from pyportable_installer import min_build\n# min_build(\'pyproject.json\')\n\n# 如不需要加密源代码, 运行以下 (仅用于调试!):\n# from pyportable_installer import debug_build\n# debug_build(\'pyproject.json\')\n```\n\n生成的安装包位于 `hello_world/dist/hello_world_0.1.0`:\n\n```\nhello_world\n|= dist\n   |= hello_world_0.1.0\n      |= build\n         |- manifest.json   # 1. 应用构建信息 (数据已自动去敏, 可随项目一起发布)\n      |= src\n         |= .pylauncher_conf\n            |- __main__.pkl     # 5. pylauncher 会从这里读取启动配置信息\n         |= data\n            |- names.txt\n         |= hello_world\n            |- main.py          # 2. 这是加密后的脚本, 与源文件同名\n         |- pylauncher.py       # 4. 启动器 (exe) 会调用这个文件\n      |= lib\n         |= pyportable_runtime\n            |- __init__.py\n            |- inject.pyd\n      |- Hello World.exe    # 3. 双击启动!\n|- ...\n```\n\n# 注意事项\n\n1.  要生成的打包目录事先应不存在, 否则 pyportable-installer 会中止打包\n2.  如果您启用了虚拟环境选项, 则安装路径不能包含中文, 否则会导致启动失败 (该问题可能与 Embedded Python 解释器有关)\n3.  `pyportable-installer` 需要 Python 3.8 及以上的解释器运行. 打包的目标 Python 版本可调 (目前对 Python 2.7 和 Python 3.7 以下的版本未做充分测试)\n\n# FAQ\n\n## 程序在启动后会出现一个黑色的控制台, 该怎么隐藏?\n\n在配置文件中将 "enable_console" 选项关闭:\n\n```json\n{\n    "...": "...",\n    "build": {\n        "...": "...",\n        "enable_console": false\n    }\n}\n```\n\n## 运行报错: 没有找到 tkinter 库\n\n这是因为您发布的项目中的虚拟环境使用的是嵌入式 Python, 而嵌入式 Python 并没有自带 tkinter 库.\n\n~~解决方法 1 (适用于 v4.0.0b3+): 在配置文件中的实验性功能中启用 "add_tkinter_support":~~\n\n```json5\n{\n    // ...\n    "build": {\n        // ...\n        "experimental_features": {\n            "add_tkinter_support": {\n                "enable": true,\n                "system_python_path": "_auto_detect"\n            }\n        }\n    }\n}\n```\n\n解决方法 2: 请参考此文: [如何将 Tk 套件加入到嵌入式 Python 中](./docs/add-tkinter-to-embed-python.md).\n\n## pywin32, win32, win32clipboard 等相关问题\n\n解决方法 1 (适用于 v4.0.0b4+): 在配置文件中的实验性功能中启用 "add_pywin32_support".\n\n解决方法 2: 请参考此文: [Pywin32 库相关问题产生原因及解决方法](./docs/pywin32-problems-and-solutions.zh.md).\n\n## 如何添加图标文件\n\n图标仅支持 ico 格式. 如果您手上只有 png, jpg 等格式的图片文件, 可通过在线网站转换:\n\n- https://www.aconvert.com/cn/image/\n\n或者通过本项目自带的脚本:\n\n*(注意: 需要事先安装 pillow 库.)*\n\n```python\nfrom pyportable_installer.bat_2_exe import png_2_ico\n\n# a) 传入文件名和目标位置\npng_2_ico.main(\'some_icon.png\', \'launcher.ico\')\n\n# b) 根据提示传入一个文件名, 会在同一目录下生成 .ico 后缀的同名文件\npng_2_ico.dialog()\n```\n\n## 如何通过配置文件实现: 打包路径用英文, 启动器名字用中文?\n\n更改配置文件如下所示:\n\n方案 1:\n\n```json5\n{\n    "app_name": "你好世界",  // 定义应用名为中文. 将生成 "你好世界.exe"\n    "build": {\n        "dist_dir": "dist/hello_world_{app_version}",  // 这里用英文路径\n        // ...\n    },\n    // ...\n}\n```\n\n方案 2 (推荐):\n\n```json5\n{\n    "app_name": "Hello World",  // 仍保持原来的名字\n    "build": {\n        "launchers": {\n            // 单独修改启动器的名字\n            "你好世界": {...}\n        },\n        // ...\n    },\n    // ...\n}\n```\n\n## pyportable-installer 加密的安全吗?\n\npyportable-installer 以插件的方式集成了多个编译器支持. 您可以在 `配置文件:compiler:name` 中选择合适的加密方案.\n\n完整的支持列表和各编译器差异可在手册 (*TODO*) 中查询. 开发者也可以定义自己的编译器来保障安全 (需要继承 `pyportable_installer.compilers.base_compiler.BaseCompiler`).\n\n这里简要介绍下推荐的编译器:\n\n**[pyportable-crypto](https://github.com/likianta/pyportable-crypto)**\n\npyportable-installer 的姊妹项目之一, 提供开源免费的加密措施.\n\npyportable-crypto 使用随机步骤生成器产生一个密钥机, 再将密钥机通过 cython 编译为 pyd 文件 (inject.pyd). 由于密钥机内置了密钥 (非固定码文保存), 在发布后附带此密钥机可以解算经同一密钥加密的 py 文件.\n\n值得注意的是 pyportable-crypto 的开发仍处于非常早期的阶段, 任何问题和反馈都欢迎提交到 issues. 在正式版推出之前, 建议使用下面要介绍的 pyarmor 库.\n\n**[pyarmor](https://github.com/dashingsoft/pyarmor)**\n\n阅读此文了解: [PyArmor 的安全性](https://pyarmor.readthedocs.io/zh/latest/security.html).\n\n注意: 请勿使用 pyarmor 试用版加密您的产品! 任何人都可以通过公开的 license 获取到源代码内容. 如需在正式产品中使用 pyarmor, 请 [购买 pyarmor 使用许可](https://pyarmor.readthedocs.io/zh/latest/license.html).\n\n## 虚拟环境各个配置方案的区别, 我该如何选择?\n\n*TODO*\n\n**[depsland][2]**\n\n*TODO*\n\n[1]: https://github.com/likianta/depsland/releases\n[2]: https://github.com/likianta/depsland\n',
    'author': 'Likianta',
    'author_email': 'likianta@foxmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': None,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'extras_require': extras_require,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
