import os import sys import shutil import zipfile from tkinter import Tk, Label, Button, messagebox, filedialog, simpledialog from PIL import Image, ImageTk from tkinter import PhotoImage from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class IngameInsignia: def __init__(self, root): self.root = root self.root.title("Image MOE Widget") self.current_image_index = 0 self.current_folder = "images/Insignia/" # Default folder path self.dds_files = [] self.image_label = Label(self.root) self.image_label.pack() # Count label self.count_label = Label(self.root, text="", width=30) # Set width for alignment self.count_label.pack() # Determine app path (to handle frozen executable paths) if getattr(sys, 'frozen', False): # If running as .exe app_path = sys._MEIPASS else: # If running as script app_path = os.path.dirname(os.path.abspath(__file__)) # Define image paths using `app_path` self.left_arrow_path = os.path.join(app_path, 'Images', 'gui', 'left-arrow.png') self.right_arrow_path = os.path.join(app_path, 'Images', 'gui', 'right-arrow.png') # Load arrows for buttons self.prev_arrow = PhotoImage(file=self.left_arrow_path) self.next_arrow = PhotoImage(file=self.right_arrow_path) self.prev_button = Button(self.root, image=self.prev_arrow, command=self.show_previous_image, width=50, height=50) self.prev_button.pack(side="left") self.next_button = Button(self.root, image=self.next_arrow, command=self.show_next_image, width=50, height=50) self.next_button.pack(side="right") self.select_folder_button = Button(self.root, text="Select Folder", command=self.select_folder) self.select_folder_button.pack() self.create_moe_button = Button(self.root, text="Create MOE", command=self.create_moe) self.create_moe_button.pack() self.load_dds_files() # Start folder monitoring self.start_monitoring() def load_dds_files(self): if os.path.exists(self.current_folder): # Reload DDS files in the selected folder self.dds_files = [f for f in os.listdir(self.current_folder) if f.endswith("_3.dds")] if not self.dds_files: messagebox.showwarning("Warning", "No DDS files found in the folder.") self.dds_files = [] # Clear list if no files are found else: self.current_image_index = 0 # Reset to first image when the folder is reloaded self.show_image() # Display the first image after loading the files self.update_count_label() # Update the image count else: self.select_folder_button.config(state="normal") # Enable button to select folder def select_folder(self): folder_selected = filedialog.askdirectory(title="Select Images Folder") if folder_selected: # User selected a folder self.current_folder = folder_selected self.load_dds_files() # Reload images from the new folder def show_image(self): if self.dds_files: # Ensure we are not out of bounds if self.current_image_index >= len(self.dds_files): self.current_image_index = len(self.dds_files) - 1 image_path = os.path.join(self.current_folder, self.dds_files[self.current_image_index]) try: img = Image.open(image_path).convert("RGBA") img = img.resize((200, 200), Image.LANCZOS) # Fixed size img_tk = ImageTk.PhotoImage(img) self.image_label.config(image=img_tk) self.image_label.image = img_tk # Keep a reference to avoid garbage collection # Update the count label with image count and set name self.update_count_label() except Exception as e: messagebox.showerror("Error Loading Image", f"Error loading image: {e}") def update_count_label(self): if self.dds_files: total_images = len(self.dds_files) base_name = self.dds_files[self.current_image_index].split("_3.dds")[0] # Get base name self.count_label.config(text=f"Image {self.current_image_index + 1} of {total_images}\nSet: {base_name}") def show_previous_image(self): if self.dds_files: self.current_image_index = (self.current_image_index - 1) % len(self.dds_files) self.show_image() def show_next_image(self): if self.dds_files: self.current_image_index = (self.current_image_index + 1) % len(self.dds_files) self.show_image() def create_moe(self): nations = ["china", "czech", "france_uk", "germany", "italian", "japan", "poland", "sweden", "usa", "ussr"] # Get the base name from the currently displayed DDS file current_dds_file = self.dds_files[self.current_image_index] base_name = current_dds_file.split("_3.dds")[0] # Get the base name (e.g., candy) # Ask for the file name with the base name as a default filename = simpledialog.askstring("Filename", "Enter the filename for the MOE:", initialvalue=f"{base_name}") if not filename: return # User canceled the input # Create a temporary directory for the files temp_dir = "temp_moe_dir" os.makedirs(temp_dir, exist_ok=True) try: for nation in nations: for i in range(1, 4): # Assuming "_1", "_2", "_3" for each nation src_file = os.path.join(self.current_folder, f"{base_name}_{i}.dds") if os.path.exists(src_file): # Copy and rename the file according to the nation dest_file_name = f"gun_{nation}_{i}.dds" # Create the necessary folder structure dest_folder = os.path.join(temp_dir, "res", "gui", "maps", "vehicles", "decals", "insignia") os.makedirs(dest_folder, exist_ok=True) dest_file_path = os.path.join(dest_folder, dest_file_name) shutil.copy(src_file, dest_file_path) # Create a zip file with store compression and include folder structure zip_file_path = f"MOE-{filename}.zip" with zipfile.ZipFile(zip_file_path, 'w', zipfile.ZIP_STORED) as zipf: for root, dirs, files in os.walk(temp_dir): for file in files: # Create a relative path for the files to maintain the folder structure file_path = os.path.join(root, file) zipf.write(file_path, os.path.relpath(file_path, temp_dir)) # Change the extension to .wotmod os.rename(zip_file_path, zip_file_path[:-4] + '.wotmod') messagebox.showinfo("Success", f"MOE created successfully as 'MOE-{filename}.wotmod'.") except Exception as e: messagebox.showerror("Error", f"An error occurred: {e}") finally: # Clean up the temporary directory shutil.rmtree(temp_dir) def start_monitoring(self): event_handler = FileSystemEventHandler() event_handler.on_created = self.on_folder_change self.observer = Observer() self.observer.schedule(event_handler, self.current_folder, recursive=True) self.observer.start() def on_folder_change(self, event): # Only react to new files being created (ignore other events) if event.event_type == 'created': # Check if the created file is part of a new image set (e.g., _1.dds, _2.dds, _3.dds) base_name = self.get_base_name_from_filename(event.src_path) if base_name: # Reload files if a new set of images has been added self.root.after(100, self.reload_and_refresh) def get_base_name_from_filename(self, file_path): # Extract the base name from the filename, checking if it's part of an image set file_name = os.path.basename(file_path) if file_name.endswith(("_1.dds", "_2.dds", "_3.dds")): return file_name.split("_")[0] # Return base name (e.g., "candy") return None def reload_and_refresh(self): # Reload the files and refresh the image count and view self.load_dds_files() # Refresh the files list self.show_image() # Refresh the image view self.update_count_label() # Update the count label if __name__ == "__main__": root = Tk() app = IngameInsignia(root) root.mainloop()