Stock-Tool/activation_dialog.py

169 lines
4.7 KiB
Python

"""
Activation Dialog
=================
Shown on first launch when no license key is stored.
Collects the license key, verifies it against Supabase, and on success
saves it to disk so it won't be asked again.
"""
import tkinter as tk
from tkinter import ttk
import license_check
from hwid import get_hwid
# ---- Colors matching the screener's dark theme ----
_BG = "#1e1e2e"
_PANEL = "#2a2a3e"
_ACCENT = "#4f8ef7"
_TEXT = "#e0e0f0"
_SUBTEXT = "#888899"
_ERROR = "#ff6b6b"
_SUCCESS = "#50fa7b"
_BORDER = "#3a3a5e"
_ENTRY_BG = "#12121f"
def run_activation() -> bool:
"""
Open the activation dialog and block until the user either activates
successfully or closes the window.
Returns True if activated, False if the user cancelled / closed.
"""
activated = [False]
root = tk.Tk()
root.title("Ultimate Investment Tool — Activation")
root.configure(bg=_BG)
root.resizable(False, False)
# Center the window
root.update_idletasks()
w, h = 480, 340
x = (root.winfo_screenwidth() - w) // 2
y = (root.winfo_screenheight() - h) // 2
root.geometry(f"{w}x{h}+{x}+{y}")
# Intercept close button — same as clicking Exit
root.protocol("WM_DELETE_WINDOW", lambda: _on_exit(root, activated))
# ---- Header ----
header = tk.Frame(root, bg=_ACCENT, height=4)
header.pack(fill="x")
tk.Label(
root, text="Ultimate Investment Tool",
font=("Segoe UI", 16, "bold"),
bg=_BG, fg=_TEXT
).pack(pady=(28, 4))
tk.Label(
root, text="Enter your license key to activate this software.",
font=("Segoe UI", 9),
bg=_BG, fg=_SUBTEXT
).pack()
# ---- Key entry ----
entry_frame = tk.Frame(root, bg=_PANEL, bd=0, highlightthickness=1,
highlightbackground=_BORDER)
entry_frame.pack(padx=40, pady=24, fill="x")
key_var = tk.StringVar()
key_entry = tk.Entry(
entry_frame, textvariable=key_var,
font=("Consolas", 11), bg=_ENTRY_BG, fg=_TEXT,
insertbackground=_TEXT, relief="flat",
bd=10, width=36
)
key_entry.pack(fill="x")
key_entry.focus()
# ---- Status label ----
status_var = tk.StringVar(value="")
status_label = tk.Label(
root, textvariable=status_var,
font=("Segoe UI", 9),
bg=_BG, fg=_ERROR, wraplength=400
)
status_label.pack(pady=(0, 8))
# ---- Buttons ----
btn_frame = tk.Frame(root, bg=_BG)
btn_frame.pack(pady=4)
activate_btn = tk.Button(
btn_frame, text="Activate",
font=("Segoe UI", 10, "bold"),
bg=_ACCENT, fg="white",
activebackground="#3a7ae0", activeforeground="white",
relief="flat", cursor="hand2", padx=24, pady=8,
command=lambda: _on_activate(root, key_var, status_var, status_label,
activate_btn, activated)
)
activate_btn.grid(row=0, column=0, padx=8)
exit_btn = tk.Button(
btn_frame, text="Exit",
font=("Segoe UI", 10),
bg=_PANEL, fg=_SUBTEXT,
activebackground=_BORDER, activeforeground=_TEXT,
relief="flat", cursor="hand2", padx=24, pady=8,
command=lambda: _on_exit(root, activated)
)
exit_btn.grid(row=0, column=1, padx=8)
# Allow Enter key to trigger activation
root.bind("<Return>", lambda e: _on_activate(
root, key_var, status_var, status_label, activate_btn, activated
))
# ---- Footer ----
tk.Label(
root, text="Need a license? Contact us to subscribe.",
font=("Segoe UI", 8),
bg=_BG, fg=_SUBTEXT
).pack(side="bottom", pady=14)
root.mainloop()
return activated[0]
def _on_activate(root, key_var, status_var, status_label, activate_btn, activated):
key = key_var.get().strip()
if not key:
status_var.set("Please enter a license key.")
return
# Show checking state
activate_btn.config(state="disabled", text="Checking…")
status_var.set("Contacting license server…")
status_label.config(fg=_SUBTEXT)
root.update()
try:
hwid = get_hwid()
valid, reason = license_check.verify_license(key, hwid)
except Exception as exc:
activate_btn.config(state="normal", text="Activate")
status_var.set(f"Error: {exc}")
status_label.config(fg=_ERROR)
return
if valid:
license_check.save_license_key(key, hwid)
status_var.set("Activated successfully! Launching…")
status_label.config(fg=_SUCCESS)
activated[0] = True
root.after(900, root.destroy)
else:
activate_btn.config(state="normal", text="Activate")
status_var.set(reason)
status_label.config(fg=_ERROR)
def _on_exit(root, activated):
activated[0] = False
root.destroy()