Files
purposed_apps/RollCall_App/activation_code.py
2025-05-19 09:03:20 +08:00

199 lines
8.6 KiB
Python

# activation_code_gui.py
import tkinter as tk
from tkinter import ttk
import uuid
import random # For date-based index generation
from datetime import date
import os
import sys
# --- Seed Date Configuration (MUST MATCH THE ONE IN THE MAIN APP) ---
# This is set once when the script starts.
current_date = date.today()
SEED_YEAR = current_date.year
SEED_MONTH = current_date.month
SEED_DAY = current_date.day
# ---------------------------------------------------------------------
# --- Helper function for PyInstaller resource path ---
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS (for one-file bundles)
# For one-dir bundles, sys.frozen is True but _MEIPASS might not be set,
# or it might point to the bundle directory.
# The reliable check is sys.frozen and then decide based on _MEIPASS.
if hasattr(sys, 'frozen') and sys.frozen:
if hasattr(sys, '_MEIPASS'):
# Running in a PyInstaller one-file bundle
base_path = sys._MEIPASS
else:
# Running in a PyInstaller one-dir bundle
base_path = os.path.dirname(sys.executable)
else:
# Not running in a bundle (running as a script)
base_path = os.path.dirname(os.path.abspath(__file__))
except Exception:
# Fallback (e.g., if __file__ is not defined in some environments)
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
# ---------------------------------------------------------
class ActivationCodeGeneratorApp:
def __init__(self, root_window):
self.root = root_window
self.root.title("Activation Code Generator")
# --- Set Window Icon ---
# The 'key.ico' file should be in the same directory as the script
# or included with the PyInstaller bundle.
# For PyInstaller, add it using: --add-data "key.ico:."
try:
icon_path = resource_path("key.ico")
if os.path.exists(icon_path):
self.root.iconbitmap(icon_path)
else:
print(f"Warning: Icon file 'key.ico' not found at resolved path: {icon_path}")
except tk.TclError as e:
print(f"Warning: Could not set window icon (TclError): {e}. Ensure 'key.ico' is a valid .ico file.")
except Exception as e:
print(f"Warning: An unexpected error occurred while setting window icon: {e}")
# -------------------------
# Minimum size to ensure all elements are visible and comfortably spaced
self.root.minsize(500, 320)
# --- Main Frame ---
main_frame = ttk.Frame(self.root, padding="10 10 10 10")
main_frame.pack(expand=True, fill=tk.BOTH)
# --- Generate Button ---
self.generate_button = ttk.Button(main_frame, text="Generate New UUID & Key", command=self.generate_and_display_code)
self.generate_button.pack(pady=(0, 15))
# --- UUID Display ---
uuid_frame = ttk.LabelFrame(main_frame, text="Generated UUID")
uuid_frame.pack(pady=5, padx=5, fill=tk.X)
self.uuid_var = tk.StringVar()
self.uuid_entry = ttk.Entry(uuid_frame, textvariable=self.uuid_var, state='readonly', width=36)
self.uuid_entry.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=(5, 5), pady=5)
self.copy_uuid_button = ttk.Button(uuid_frame, text="Copy UUID", command=self.copy_uuid)
self.copy_uuid_button.pack(side=tk.LEFT, padx=(0, 5), pady=5)
# --- Activation Key Display (Raw) ---
key_frame = ttk.LabelFrame(main_frame, text="Activation Key (Raw)")
key_frame.pack(pady=5, padx=5, fill=tk.X)
self.key_var = tk.StringVar()
self.key_entry = ttk.Entry(key_frame, textvariable=self.key_var, state='readonly', width=10)
self.key_entry.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=(5, 5), pady=5)
self.copy_key_button = ttk.Button(key_frame, text="Copy Key", command=self.copy_key)
self.copy_key_button.pack(side=tk.LEFT, padx=(0, 5), pady=5)
# --- Formatted Key Display ---
formatted_key_frame = ttk.LabelFrame(main_frame, text="Suggested Key Format for User (XXXX-XXXX)")
formatted_key_frame.pack(pady=5, padx=5, fill=tk.X)
self.formatted_key_var = tk.StringVar()
self.formatted_key_entry = ttk.Entry(formatted_key_frame, textvariable=self.formatted_key_var, state='readonly', width=12)
self.formatted_key_entry.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=(5, 5), pady=5)
self.copy_formatted_key_button = ttk.Button(formatted_key_frame, text="Copy Formatted", command=self.copy_formatted_key)
self.copy_formatted_key_button.pack(side=tk.LEFT, padx=(0, 5), pady=5)
# --- Info Label ---
info_text = (
f"The seed date for key generation is fixed to: {SEED_YEAR}-{SEED_MONTH:02d}-{SEED_DAY:02d}.\n"
"This seed is determined when this application starts.\n"
"Provide the UUID and either the Raw or Formatted Activation Key to the user."
)
info_label = ttk.Label(
main_frame,
text=info_text,
justify=tk.LEFT,
wraplength=480
)
info_label.pack(pady=(10, 0), fill=tk.X)
self.generate_and_display_code()
def _generate_code_logic(self):
generated_uuid = uuid.uuid4()
uuid_str = str(generated_uuid)
s = uuid_str.replace('-', '')
date_seed_value = SEED_YEAR * 10000 + SEED_MONTH * 100 + SEED_DAY
rng = random.Random(date_seed_value)
all_possible_indices = list(range(32))
rng.shuffle(all_possible_indices)
dynamic_indices = sorted(all_possible_indices[:8])
activation_key_raw = "ERRORKEY"
if len(s) == 32:
try:
key_chars = [s[i] for i in dynamic_indices]
activation_key_raw = "".join(key_chars).upper()
except IndexError:
activation_key_raw = "IDXERROR"
else:
activation_key_raw = "LENERROR"
return uuid_str, activation_key_raw
def generate_and_display_code(self):
generated_uuid, activation_key = self._generate_code_logic()
self.uuid_var.set(generated_uuid)
self.key_var.set(activation_key)
if len(activation_key) == 8 and activation_key not in ["IDXERROR", "LENERROR", "ERRORKEY"]:
formatted_display_key = f"{activation_key[:4]}-{activation_key[4:]}"
self.formatted_key_var.set(formatted_display_key)
else:
self.formatted_key_var.set(activation_key)
def _copy_to_clipboard(self, text_to_copy, button_widget=None):
if not text_to_copy:
return
self.root.clipboard_clear()
self.root.clipboard_append(text_to_copy)
self.root.update()
if button_widget:
original_text = button_widget.cget("text")
button_widget.config(text="Copied!")
self.root.after(1000, lambda: button_widget.config(text=original_text))
def copy_uuid(self):
self._copy_to_clipboard(self.uuid_var.get(), self.copy_uuid_button)
def copy_key(self):
self._copy_to_clipboard(self.key_var.get(), self.copy_key_button)
def copy_formatted_key(self):
self._copy_to_clipboard(self.formatted_key_var.get(), self.copy_formatted_key_button)
if __name__ == "__main__":
# To create an executable with PyInstaller, ensure 'key.ico' is in the same directory
# as this script, and then run a command like:
# For a single file executable:
# pyinstaller --onefile --windowed --add-data "key.ico:." activation_code_gui.py
# For a one-directory bundle:
# pyinstaller --windowed --add-data "key.ico:." activation_code_gui.py
# (The '--name' option can be used to set the executable name)
# Create a dummy key.ico if it doesn't exist for testing purposes
# In a real scenario, you'd have your actual key.ico file.
if not os.path.exists("key.ico"):
try:
print("Note: 'key.ico' not found. A dummy one will not be created by this script.")
print("Please provide a real 'key.ico' file for the icon to work.")
# For demonstration, one might create a placeholder, but it's better if the user provides it.
# with open("key.ico", "w") as f:
# f.write("") # This would create an empty, invalid icon file. Not recommended.
except Exception as e:
print(f"Could not create a dummy key.ico for testing: {e}")
root = tk.Tk()
app = ActivationCodeGeneratorApp(root)
root.mainloop()