├── __init__.py ├── fpyo2apk ├── __init__.py ├── Tools │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── check_system.cpython-311.pyc │ │ ├── check_venv.cpython-311.pyc │ │ └── unzip_assets.cpython-311.pyc │ ├── check_system.py │ ├── check_venv.py │ └── unzip_assets.py ├── assets │ ├── __init__.py │ └── fpyo2apkdist.zip ├── beeware_tools │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── the_app_py.cpython-311.pyc │ │ ├── the_localhost_py.cpython-311.pyc │ │ ├── create_new_project.cpython-311.pyc │ │ └── edit_beeware_project.cpython-311.pyc │ ├── the_localhost_py.py │ ├── the_app_py.py │ └── edit_beeware_project.py └── build.py ├── .DS_Store ├── MANIFEST.in ├── pyproject.toml ├── setup.py ├── LICENSE ├── .github └── workflows │ └── python-publish.yml └── README.md /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fpyo2apk/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fpyo2apk/Tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fpyo2apk/assets/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/.DS_Store -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include fpyo2apk/ 2 | include fpyo2apk/assets/* 3 | include fpyo2apk/assets/fpyo2apkdist.zip -------------------------------------------------------------------------------- /fpyo2apk/assets/fpyo2apkdist.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/assets/fpyo2apkdist.zip -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools>=54", 4 | "wheel" 5 | ] 6 | build-backend = "setuptools.build_meta" -------------------------------------------------------------------------------- /fpyo2apk/Tools/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/Tools/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/Tools/__pycache__/check_system.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/Tools/__pycache__/check_system.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/Tools/__pycache__/check_venv.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/Tools/__pycache__/check_venv.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/Tools/__pycache__/unzip_assets.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/Tools/__pycache__/unzip_assets.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/beeware_tools/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/__pycache__/the_app_py.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/beeware_tools/__pycache__/the_app_py.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/Tools/check_system.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | def is_it_mac (): 5 | import sys 6 | if "darwin" in str(sys.platform): 7 | return True 8 | else: 9 | return False -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/__pycache__/the_localhost_py.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/beeware_tools/__pycache__/the_localhost_py.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/__pycache__/create_new_project.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/beeware_tools/__pycache__/create_new_project.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/__pycache__/edit_beeware_project.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKbarbon/fpyo2apk/HEAD/fpyo2apk/beeware_tools/__pycache__/edit_beeware_project.cpython-311.pyc -------------------------------------------------------------------------------- /fpyo2apk/Tools/check_venv.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | def is_on_venv (): 6 | import os 7 | if os.environ.get('VIRTUAL_ENV') is not None: 8 | return True 9 | else: 10 | return False -------------------------------------------------------------------------------- /fpyo2apk/build.py: -------------------------------------------------------------------------------- 1 | from .Tools.check_system import is_it_mac 2 | from .Tools.check_venv import is_on_venv 3 | from .beeware_tools.edit_beeware_project import edit_an_exist_project 4 | import sys 5 | import sys 6 | 7 | # python -m fpyo2ipa.build 8 | args = str(sys.argv) 9 | 10 | if is_on_venv() == False: 11 | #? exit if not in venv. 12 | sys.exit("Exit: Please run this on a virtual environment. Run this command to create one: `python3 -m venv venv`") 13 | 14 | 15 | #! important informations 16 | print(""" 17 | This is `fpyo2apk`. A flet-pyodide dist to apk converter. 18 | Be sure that Android Studio is installed and setuped. 19 | Starting.. 20 | 21 | """) 22 | 23 | #! Step1: Create the project 24 | edit_an_exist_project() -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='fpyo2apk', 5 | version='1.1.4', 6 | author='SKbarbon', 7 | description='A package tool that allow you to built a python Android apps with flet-pyodide dist.', 8 | long_description="https://github.com/SKbarbon/fpyo2apk", 9 | url='https://github.com/SKbarbon/fpyo2apk', 10 | install_requires=["briefcase==0.3.14"], 11 | include_package_data=True, 12 | packages=find_packages(), 13 | classifiers=[ 14 | "Programming Language :: Python :: 3", 15 | "Operating System :: MacOS :: MacOS X", 16 | "Operating System :: Microsoft :: Windows" 17 | ], 18 | include_dirs=["assets"], 19 | package_data={"assets": ["pyo2ipadist.zip"]}, 20 | ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Yousef Aladwani 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/the_localhost_py.py: -------------------------------------------------------------------------------- 1 | The_localhost_py_script = """ 2 | import threading 3 | import subprocess 4 | 5 | class LocalHoat : 6 | def __init__(self) -> None: 7 | import socketserver 8 | 9 | self.started = False 10 | with socketserver.TCPServer(("localhost", 0), None) as s: 11 | free_port = s.server_address[1] 12 | self.PORT = int(free_port) 13 | 14 | def start (self): 15 | threading.Thread(target=self.run_server, daemon=True).start() 16 | 17 | def run_server (self): 18 | import http.server 19 | import socketserver 20 | import threading 21 | import webbrowser 22 | import time 23 | import random 24 | 25 | PORT = self.PORT # Change this to the desired port number 26 | 27 | class MyHandler(http.server.SimpleHTTPRequestHandler): 28 | def log_message(self, format, *args): 29 | pass 30 | 31 | with socketserver.TCPServer(("", PORT), MyHandler) as httpd: 32 | self.started = True 33 | httpd.serve_forever() 34 | """ -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Upload Python Package 10 | 11 | on: 12 | release: 13 | types: [published] 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | deploy: 20 | 21 | runs-on: ubuntu-latest 22 | 23 | steps: 24 | - uses: actions/checkout@v3 25 | - name: Set up Python 26 | uses: actions/setup-python@v3 27 | with: 28 | python-version: '3.x' 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | pip install build 33 | - name: Build package 34 | run: python -m build 35 | - name: Publish package 36 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 37 | with: 38 | user: __token__ 39 | password: ${{ secrets.PYPI_API_TOKEN }} 40 | -------------------------------------------------------------------------------- /fpyo2apk/Tools/unzip_assets.py: -------------------------------------------------------------------------------- 1 | import os 2 | import zipfile 3 | import shutil 4 | 5 | def Unzip_asset (): 6 | asset_path = str(__file__).replace("Tools/unzip_assets.py", "assets/fpyo2apkdist.zip") 7 | 8 | if r"Tools\unzip_assets.py" in str(asset_path): 9 | asset_path = str(asset_path).replace(r"Tools\unzip_assets.py", r"assets\fpyo2apkdist.zip") 10 | 11 | if not os.path.isfile(asset_path): 12 | raise FileNotFoundError("Cannot found the assets.") 13 | 14 | if os.path.isdir("fpyo2apkdist"): 15 | shutil.rmtree("fpyo2apkdist") 16 | 17 | with zipfile.ZipFile(asset_path, "r") as zip_ref: 18 | zip_ref.extractall("fpyo2apkdist") 19 | 20 | shutil.copytree("fpyo2apkdist/fpyo2apkdist", "_fpyo2apkdist") 21 | shutil.rmtree("fpyo2apkdist") 22 | shutil.move("_fpyo2apkdist", "fpyo2apkdist") 23 | 24 | #? Edit the pyproject.toml file. 25 | AppName = input("Write the name of your app: ") 26 | Describe = input("Write a small descibe of your app:") 27 | if str(AppName).replace(" ", "") == "": AppName = "fpyo2apk" 28 | if '"' in str(AppName): AppName = "fpyo2apk" 29 | if '"' in str(Describe): Describe = "fpyo2apk" 30 | 31 | print("setting your appname and describe..") 32 | read_file = open("fpyo2apkdist/pyproject.toml", encoding="utf-8").read() 33 | read_file = str(read_file).replace("_here_the_app_name_", AppName) 34 | read_file = str(read_file).replace("_here_the_describe_of_app_", Describe) 35 | 36 | open("fpyo2apkdist/pyproject.toml", "w+", encoding="utf-8").write(read_file) 37 | 38 | print("unzip is done..") -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fpyo2apk 2 | ## This project is no longer maintaned. Please use the official way to distrebute flet apps 3 | A python package tool for create Android apps project for a `flet-pyodide` `dist` folder. Its very easy to use. 4 | 5 | For iOS/iPadOS ? [fpyo2ipa](https://github.com/SKbarbon/fpyo2ipa) 6 | 7 | ## requirements 8 | - python: up than python3.8 9 | - Android Studio: This is very important to make `briefcase` work. 10 | - briefcase==0.3.14 (it will be auto installed if you install this package) 11 | 12 | * `Note`: This package is tested on macOS only, but it should work on windows as will. if there is any issues report it here: [issue](https://github.com/SKbarbon/fpyo2apk/issues) 13 | 14 | ## Little peek 15 | 16 | Screenshot 2023-05-08 at 8 20 22 PM 17 | 18 | ## usage 19 | This is a video tutorial: [Tutorial](https://youtu.be/302AT_INDo8) 20 | 21 | 1- Publish your flet script into flet-pyodide dist. Use this command for that: 22 | 23 | ``` 24 | flet publish main.py 25 | ``` 26 | 27 | 2- Create a python virtual environment (highly recommended): 28 | 29 | ``` 30 | python3 -m venv venv 31 | ``` 32 | 33 | 3- Install `fpyo2apk` package: 34 | 35 | ``` 36 | pip install fpyo2apk --upgrade 37 | ``` 38 | 39 | 4- Start building your Android App project. 40 | 41 | * Make sure that your `dist` folder is in the current cmd's folder, and make sure that you are done with Android Studio setup. 42 | ``` 43 | python3 -m fpyo2apk.build 44 | ``` 45 | -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/the_app_py.py: -------------------------------------------------------------------------------- 1 | The_app_py_script = """ 2 | 3 | import toga 4 | from toga.style import Pack 5 | from toga.style.pack import COLUMN, ROW 6 | import time 7 | import webbrowser 8 | from .localhost import LocalHoat 9 | 10 | 11 | # basedurlhere 12 | class AppNameBabe(toga.App): 13 | 14 | def startup(self): 15 | main_box = toga.Box(style=Pack(direction=COLUMN)) 16 | 17 | #? Get and setup the localhost 18 | dist_folder_path = str(__file__).replace("app.py", "assets/dist") 19 | LH = LocalHoat() 20 | LH.start() 21 | for i in range(15): 22 | if LH.started == True: break 23 | time.sleep(0.5) 24 | 25 | #! --- 26 | import shutil 27 | import os 28 | sandbox_documents_dir = os.path.expanduser('~/Documents') 29 | 30 | if os.path.isdir(f"{sandbox_documents_dir}/dist"): 31 | shutil.rmtree(f"{sandbox_documents_dir}/dist") 32 | shutil.copytree(dist_folder_path, f"{sandbox_documents_dir}/dist") 33 | 34 | the_file = open(f"{sandbox_documents_dir}/dist/index.html", encoding="utf-8").read() 35 | the_file = the_file.replace("/basedurlhere/", f"{sandbox_documents_dir}/dist/") 36 | open(f"{sandbox_documents_dir}/dist/index.html", "w+", encoding="utf-8").write(the_file) 37 | 38 | #! --- 39 | 40 | #? reWrite the index file. 41 | if 1 != 1: 42 | the_file = open(f"{dist_folder_path}/index.html", encoding="utf-8").read() 43 | the_file = the_file.replace("/basedurlhere/", f"{dist_folder_path}/") 44 | open(f"{dist_folder_path}/index.html", "w+", encoding="utf-8").write(the_file) 45 | 46 | #? create the webview 47 | webview = toga.WebView(style=Pack(flex=1)) 48 | url = f'http://localhost:{LH.PORT}/{sandbox_documents_dir}/dist' 49 | webview.url = url 50 | main_box.add(webview) 51 | 52 | self.main_window = toga.MainWindow(title=self.formal_name) 53 | self.main_window.content=main_box 54 | self.main_window.show() 55 | 56 | 57 | def main(): 58 | return AppNameBabe() 59 | 60 | 61 | """ -------------------------------------------------------------------------------- /fpyo2apk/beeware_tools/edit_beeware_project.py: -------------------------------------------------------------------------------- 1 | from .the_app_py import The_app_py_script 2 | from .the_localhost_py import The_localhost_py_script 3 | from ..Tools.unzip_assets import Unzip_asset 4 | import os 5 | import shutil 6 | import subprocess 7 | import sys 8 | 9 | def edit_an_exist_project(): 10 | print("Create a briefcase project..") 11 | Unzip_asset() 12 | 13 | 14 | project_name = "fpyo2apkdist" 15 | if not os.path.isdir(project_name): 16 | raise FileNotFoundError(f"There is no folder with path '{project_name}'.") 17 | 18 | if not os.path.isdir(f"{project_name}/src"): 19 | raise FileNotFoundError(f"There is no folder with path '{project_name}/src'.") 20 | 21 | if not os.path.isdir(f"{project_name}/src/fpyo2apk/assets"): 22 | os.mkdir(f"{project_name}/src/fpyo2apk/assets") 23 | 24 | if not os.path.isdir("dist"): 25 | raise FileNotFoundError("There must be a flet-pyodide folder called `dist` to start.") 26 | 27 | print("editing the dist..") 28 | if ' ' in open("dist/index.html", encoding="utf-8").read(): 29 | pass 30 | elif ' ' not in open("dist/index.html", encoding="utf-8").read(): 31 | sys.exit("Exit with Error: The base/href url of the dist must be '/'.") 32 | 33 | the_index_file = open("dist/index.html", encoding="utf-8").read() 34 | the_index_file = str(the_index_file).replace(' ', ' ') 35 | open("dist/index.html", "w+", encoding="utf-8").write(the_index_file) 36 | 37 | print("copy the dist..") 38 | if os.path.isdir(f"{project_name}/src/fpyo2apk/assets/dist"): 39 | shutil.rmtree(f"{project_name}/src/fpyo2apk/assets/dist") 40 | shutil.copytree("dist", f"{project_name}/src/fpyo2apk/assets/dist") 41 | 42 | print("start edit the 'app.py' file..") 43 | open(f"{project_name}/src/fpyo2apk/app.py", "w+", encoding="utf-8").write(The_app_py_script) 44 | 45 | print("start creating/editing the 'localhost.py' file..") 46 | open(f"{project_name}/src/fpyo2apk/localhost.py", "w+", encoding="utf-8").write(The_localhost_py_script) 47 | 48 | print(""" 49 | 50 | Your project has been created successfully! 51 | There are some problems with running brifcase commands automatically, 52 | so you will have to run them manually. 53 | 54 | $ cd fpyo2apkdist 55 | $ briefcase create Android 56 | $ briefcase build Android 57 | $ briefcase run Android 58 | 59 | """) --------------------------------------------------------------------------------