Scripts/build.py
2025-07-22 12:44:17 +04:00

271 lines
8.6 KiB
Python

import os
import zipfile
import base64
import subprocess
import tempfile
import shutil
def create_folders_zip():
"""Create a zip file containing all folders in a single SCRIPTS folder"""
# Folders to include
folders_to_include = [
"PLACE DPMS",
"PLACE DPM DEVICES",
"OTHER SCRIPTS",
"RESET IGNITION",
"TAGS"
]
# Create temporary zip file
temp_zip = "temp_folders.zip"
with zipfile.ZipFile(temp_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
for folder in folders_to_include:
if os.path.exists(folder):
print(f"Adding folder: {folder}")
# Walk through the folder and add all files with SCRIPTS prefix
for root, dirs, files in os.walk(folder):
for file in files:
file_path = os.path.join(root, file)
# Create arc_name with SCRIPTS prefix
arc_name = os.path.join("SCRIPTS", os.path.relpath(file_path, '.'))
zipf.write(file_path, arc_name)
print(f" - Added: {arc_name}")
else:
print(f"Warning: Folder '{folder}' not found, skipping...")
return temp_zip
def encode_zip_to_base64(zip_file):
"""Encode zip file to base64 string"""
with open(zip_file, 'rb') as f:
zip_data = f.read()
return base64.b64encode(zip_data).decode('utf-8')
def update_script_with_embedded_data(base64_data):
"""Update the script with embedded data"""
script_content = """import os
import shutil
import tkinter as tk
from tkinter import filedialog, messagebox
import sys
import tempfile
import zipfile
import base64
# Embedded folder data - this will be populated by the build script
EMBEDDED_FOLDERS_DATA = \"\"\"
{embedded_data}
\"\"\"
def extract_embedded_folders():
\"\"\"Extract embedded folders to a temporary location\"\"\"
try:
# Create temporary directory
temp_dir = tempfile.mkdtemp(prefix="folder_creator_")
# Decode the embedded data
if EMBEDDED_FOLDERS_DATA.strip() == "# This will be replaced with actual base64 encoded zip data during build":
messagebox.showerror("Error", "No embedded folders found in executable!")
return None
# Decode base64 data
zip_data = base64.b64decode(EMBEDDED_FOLDERS_DATA)
# Write to temporary zip file
temp_zip = os.path.join(temp_dir, "folders.zip")
with open(temp_zip, 'wb') as f:
f.write(zip_data)
# Extract zip file
with zipfile.ZipFile(temp_zip, 'r') as zip_ref:
zip_ref.extractall(temp_dir)
# Remove the zip file
os.remove(temp_zip)
return temp_dir
except Exception as e:
messagebox.showerror("Error", f"Failed to extract embedded folders:\\n{{str(e)}}")
return None
def select_destination_folder():
\"\"\"Open a dialog for user to select destination folder\"\"\"
root = tk.Tk()
root.withdraw() # Hide the main window
# Show folder selection dialog
destination = filedialog.askdirectory(
title="Select destination folder for installing folders"
)
return destination
def copy_folders_to_destination(source_path, destination_path):
\"\"\"Copy all folders from source to destination\"\"\"
try:
# Get all items in the source directory
items = os.listdir(source_path)
# Filter only directories
folders = [item for item in items if os.path.isdir(os.path.join(source_path, item))]
if not folders:
messagebox.showwarning("Warning", "No folders found in the embedded data!")
return False
# Create destination if it doesn't exist
if not os.path.exists(destination_path):
os.makedirs(destination_path)
copied_folders = []
# Copy each folder
for folder in folders:
source_folder = os.path.join(source_path, folder)
dest_folder = os.path.join(destination_path, folder)
# Copy the folder and its contents
shutil.copytree(source_folder, dest_folder)
copied_folders.append(folder)
print(f"Installed: {{folder}}")
# Show success message
messagebox.showinfo(
"Success",
f"Successfully installed {{len(copied_folders)}} folders to:\\n{{destination_path}}\\n\\nInstalled folders:\\n" +
"\\n".join(copied_folders)
)
return True
except Exception as e:
messagebox.showerror("Error", f"An error occurred while installing folders:\\n{{str(e)}}")
return False
def cleanup_temp_files(temp_dir):
\"\"\"Clean up temporary files\"\"\"
try:
if temp_dir and os.path.exists(temp_dir):
shutil.rmtree(temp_dir)
except:
pass # Ignore cleanup errors
def main():
\"\"\"Main function\"\"\"
print("Folder Installer Tool")
print("=" * 50)
temp_dir = None
try:
# Extract embedded folders
print("Extracting embedded folders...")
temp_dir = extract_embedded_folders()
if not temp_dir:
return
print(f"Extracted to temporary location: {{temp_dir}}")
# Select destination folder
destination = select_destination_folder()
if not destination:
print("No destination folder selected. Exiting...")
return
print(f"Destination directory: {{destination}}")
# Confirm with user
confirm = messagebox.askyesno(
"Confirm Installation",
f"Install all folders to:\\n{{destination}}\\n\\nProceed?"
)
if confirm:
# Copy the folders
success = copy_folders_to_destination(temp_dir, destination)
if success:
print("Installation completed successfully!")
else:
print("Installation failed!")
else:
print("Installation cancelled by user.")
finally:
# Clean up temporary files
cleanup_temp_files(temp_dir)
if __name__ == "__main__":
main()
""".format(embedded_data=base64_data)
with open("folder_creator_embedded_final.py", "w") as f:
f.write(script_content)
def build_executable():
"""Build the executable using PyInstaller"""
try:
print("Building executable with embedded folders...")
# PyInstaller command
cmd = [
"pyinstaller",
"--onefile", # Create a single executable file
"--windowed", # Don't show console window (optional)
"--name=ScriptsInstaller", # Name of the executable
"folder_creator_embedded_final.py"
]
# Run PyInstaller
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print("✅ Executable built successfully!")
print(f"Executable location: {os.path.join('dist', 'ScriptsInstaller.exe')}")
else:
print("❌ Error building executable:")
print(result.stderr)
except FileNotFoundError:
print("❌ PyInstaller not found. Please install it first:")
print("pip install pyinstaller")
except Exception as e:
print(f"❌ Error: {str(e)}")
def main():
"""Main build process"""
print("Building Folder Installer with Embedded Folders")
print("=" * 60)
# Step 1: Create zip file with all folders
print("Step 1: Creating zip file with all folders...")
zip_file = create_folders_zip()
# Step 2: Encode zip to base64
print("Step 2: Encoding zip file to base64...")
base64_data = encode_zip_to_base64(zip_file)
print(f"Base64 data length: {len(base64_data)} characters")
# Step 3: Update script with embedded data
print("Step 3: Updating script with embedded data...")
update_script_with_embedded_data(base64_data)
# Step 4: Build executable
print("Step 4: Building executable...")
build_executable()
# Step 5: Cleanup
print("Step 5: Cleaning up temporary files...")
if os.path.exists(zip_file):
os.remove(zip_file)
if os.path.exists("folder_creator_embedded_final.py"):
os.remove("folder_creator_embedded_final.py")
print("✅ Build process completed!")
if __name__ == "__main__":
main()