diff --git a/AppIcon.ico b/AppIcon.ico new file mode 100644 index 0000000..fa4611a Binary files /dev/null and b/AppIcon.ico differ diff --git a/setup.py b/setup.py index d704226..98f5ddb 100644 --- a/setup.py +++ b/setup.py @@ -1,41 +1,102 @@ #!/usr/bin/env python3 import sys -from setuptools import setup +import platform +from pathlib import Path +import subprocess -# Application metadata -APP_NAME = "PNG Metadata Editor" -APP_VERSION = "1.0.0" -AUTHOR = "Robert Tusa" -DESCRIPTION = "A graphical tool for viewing and editing metadata in PNG files" +def check_pyinstaller(): + """Check if PyInstaller is installed and available""" + try: + subprocess.run( + [sys.executable, "-m", "PyInstaller", "--version"], + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + return True + except (subprocess.CalledProcessError, FileNotFoundError): + return False -# Read the long description from README -with open('README.md', 'r', encoding='utf-8') as f: - long_description = f.read() +def install_pyinstaller(): + """Install PyInstaller if not already installed""" + print("PyInstaller not found. Installing now...") + try: + subprocess.check_call( + [sys.executable, "-m", "pip", "install", "--upgrade", "pyinstaller"], + stdout=subprocess.DEVNULL + ) + print("PyInstaller installed successfully.") + return True + except subprocess.CalledProcessError as e: + print(f"Failed to install PyInstaller: {e}") + return False -setup( - name=APP_NAME, - version=APP_VERSION, - description=DESCRIPTION, - long_description=long_description, - long_description_content_type='text/markdown', - author=AUTHOR, - author_email='robert@tusa.at', # Replace with your email - url='https://git.tusa.at/robert/png-meta-editor', # Replace with your repo - license='MIT', - python_requires='>=3.6', - app=['png-meta-editor.py'], # Your main script - data_files=[('', - ['AppIcon.icns', 'version.txt'])], # Include these files - options={ - 'py2app': { - 'argv_emulation': True, - 'iconfile': 'AppIcon.icns', - 'plist': { - 'CFBundleName': APP_NAME, - 'CFBundleShortVersionString': APP_VERSION, - 'CFBundleVersion': APP_VERSION, - }, - }, - }, - setup_requires=['py2app'], -) +def main(): + # Check and install PyInstaller if needed + if not check_pyinstaller(): + if not install_pyinstaller(): + print("Error: PyInstaller installation failed. Please install it manually:") + print("pip install pyinstaller") + sys.exit(1) + + # Check if requirements.txt exists and install dependencies + req_file = Path("requirements.txt") + if req_file.exists(): + print("\nInstalling dependencies from requirements.txt...") + try: + subprocess.check_call( + [sys.executable, "-m", "pip", "install", "-r", "requirements.txt"], + stdout=subprocess.DEVNULL + ) + except subprocess.CalledProcessError as e: + print(f"Warning: Failed to install some dependencies: {e}") + else: + print("\nWarning: requirements.txt not found. Installing default dependencies...") + try: + subprocess.check_call( + [sys.executable, "-m", "pip", "install", "pillow>=9.0.0", "pngmeta>=1.0.0"], + stdout=subprocess.DEVNULL + ) + except subprocess.CalledProcessError as e: + print(f"Warning: Failed to install default dependencies: {e}") + + # Determine platform-specific build options + system = platform.system() + base_args = [ + "--name", "PNG Metadata Editor", + "--windowed", + "--onefile" + ] + + # Check for version.txt + version_file = Path("version.txt") + if version_file.exists(): + print(f"\nUsing version info from {version_file}") + base_args.extend(["--version-file", "version.txt"]) + else: + print("\nWarning: version.txt not found. Using default version.") + + if system == "Windows": + base_args.extend(["--icon", "AppIcon.ico"]) + elif system == "Darwin": # macOS + base_args.extend(["--icon", "AppIcon.icns"]) + else: # Linux + pass + + # Build the PyInstaller command + pyinstaller_args = ["--distpath", "dist", "--workpath", "build"] + base_args + cmd = [sys.executable, "-m", "PyInstaller"] + pyinstaller_args + ["png-meta-editor.py"] + + print(f"\nBuilding PNG Metadata Editor for {system}...") + try: + result = subprocess.run(cmd) + if result.returncode == 0: + print("\nBuild completed successfully!") + print(f"Your executable is in the dist/ folder") + return result.returncode + except subprocess.CalledProcessError as e: + print(f"\nBuild failed with error: {e}") + return 1 + +if __name__ == "__main__": + sys.exit(main())