271 lines
8.6 KiB
Python
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() |