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()