Misc ns-usbloader MacOS Application

TheStonedModder

Well-Known Member
OP
Member
Joined
Dec 25, 2022
Messages
1,275
Trophies
1
Age
27
XP
2,793
Country
United States
Java programs are annoying to use on mac, so I bundled it and a python script into a standalone .app file so that it can be installed and launched directly from the command center like a normal application. (assuming you have python3, and java installed already)


image (1).png

If anyone wants to update or improve it here is the script that I used.

This will bundle an "ns-usbloader.jar" and run.py script in root into a .app file
Code:
import os
import shutil
import subprocess
import sys

def create_mac_app():
    # Define paths
    app_name = "ns-usbloader"
    app_bundle = f"{app_name}.app"
    contents_dir = os.path.join(app_bundle, "Contents")
    macos_dir = os.path.join(contents_dir, "MacOS")
    resources_dir = os.path.join(contents_dir, "Resources")
    python_script = "run.py"

    # Step 1: Create the macOS application bundle structure
    print("Creating macOS application bundle structure...")
    os.makedirs(macos_dir, exist_ok=True)
    os.makedirs(resources_dir, exist_ok=True)

    # Step 2: Copy the Python script, JAR files, and icon into the bundle
    print("Copying Python script, JAR files, and icon...")
    shutil.copy(python_script, resources_dir)
    for file in os.listdir():
        if file.endswith(".jar") and "ns-usbloader" in file:
            shutil.copy(file, resources_dir)
  
    # Copy the .icns file if it exists
    if os.path.exists("AppIcon.icns"):
        shutil.copy("AppIcon.icns", resources_dir)
    else:
        print("Warning: AppIcon.icns not found. The app will use a default icon.")

    # Step 3: Create a shell script to run the Python script
    print("Creating shell script...")
    shell_script_content = f"""#!/bin/bash
DIR="$( cd "$( dirname "${{BASH_SOURCE[0]}}" )" && pwd )"
cd "$DIR/../Resources"
export PYTHONPATH="$PYTHONPATH:$(pwd)"
/usr/bin/env python3 {python_script}
"""
    with open(os.path.join(macos_dir, "run_app"), "w") as shell_script:
        shell_script.write(shell_script_content)
    os.chmod(os.path.join(macos_dir, "run_app"), 0o755)

    # Step 4: Create the Info.plist file
    print("Creating Info.plist...")
    info_plist_content = f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleExecutable</key>
    <string>run_app</string>
    <key>CFBundleIdentifier</key>
    <string>com.yourcompany.{app_name}</string>
    <key>CFBundleName</key>
    <string>{app_name}</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleIconFile</key>
    <string>AppIcon.icns</string>
    <key>NSHighResolutionCapable</key>
    <true/>
    <key>LSMinimumSystemVersion</key>
    <string>10.9</string>
</dict>
</plist>
"""
    with open(os.path.join(contents_dir, "Info.plist"), "w") as plist_file:
        plist_file.write(info_plist_content)

    print(f"{app_name}.app has been created successfully.")

if __name__ == "__main__":
    create_mac_app()

If you want the application to have an icon. Just put a png file next to this script, and run it. It should spit out the proper icns file. You can than just drag the icsn file next to the scripts above, and run the make script again to give it an icon
Code:
import os
import subprocess
from PIL import Image
import shutil

def create_iconset(png_path, iconset_path):
    # Define the sizes for the iconset
    sizes = [16, 32, 64, 128, 256, 512, 1024]

    # Create the iconset directory
    os.makedirs(iconset_path, exist_ok=True)

    # Generate images for each size
    for size in sizes:
        img = Image.open(png_path)
        img = img.resize((size, size), Image.LANCZOS)  # Use LANCZOS instead of ANTIALIAS
        img.save(os.path.join(iconset_path, f"icon_{size}x{size}.png"))

        # Save @2x images for Retina displays
        img_2x = img.resize((size * 2, size * 2), Image.LANCZOS)  # Use LANCZOS instead of ANTIALIAS
        img_2x.save(os.path.join(iconset_path, f"icon_{size}x{size}@2x.png"))

def convert_to_icns(iconset_path, icns_path):
    # Use iconutil to convert the iconset to an icns file
    subprocess.run(['iconutil', '-c', 'icns', iconset_path, '-o', icns_path], check=True)

def main():
    png_path = "icon.png"
    iconset_path = "AppIcon.iconset"
    icns_path = "AppIcon.icns"

    if not os.path.exists(png_path):
        print(f"{png_path} not found.")
        return

    print("Creating iconset...")
    create_iconset(png_path, iconset_path)

    print("Converting iconset to icns...")
    convert_to_icns(iconset_path, icns_path)

    print(f"{icns_path} has been created successfully.")

    # Clean up the iconset directory
    shutil.rmtree(iconset_path)

if __name__ == "__main__":
    main()

Download: https://gbatemp.net/download/ns-usbloader-macos-app-v7-1.38845/
 
Last edited by TheStonedModder,
  • Like
Reactions: hippy dave

thesjaakspoiler

Well-Known Member
Member
Joined
Nov 20, 2018
Messages
1,259
Trophies
0
Age
124
XP
1,889
Country
Afghanistan
Thanks very much!

What is that run.py script in python_script = "run.py"?
Maybe I didn't install Python3 correctly or maybe some path hasn't been set up correctly.
 

TheStonedModder

Well-Known Member
OP
Member
Joined
Dec 25, 2022
Messages
1,275
Trophies
1
Age
27
XP
2,793
Country
United States
Thanks very much!

What is that run.py script in python_script = "run.py"?
Maybe I didn't install Python3 correctly or maybe some path hasn't been set up correctly.
I don’t quite understand. Do you have a screenshot?

This is the first time I made something like this so it’s very possible I forgot something when uploading
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    K3Nv2 @ K3Nv2: Camera cuts back inside geeze I wonder how all that happened