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