abdulsalam2121
Add automation bot with Flask and Playwright
5b29309
Raw
History Blame Contribute Delete
5.83 kB
import os
import threading
import queue
import webbrowser
from pathlib import Path
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox, filedialog
from bot import BotRunner
from config import DEFAULT_CREDENTIALS_FILE, save_credentials
LOG_POLL_MS = 200
class GUI:
def __init__(self, root: tk.Tk):
self.root = root
root.title("ADM PURCHASING TOOLS")
root.geometry("760x620")
self.log_queue = queue.Queue()
self.stop_event = threading.Event()
self.worker_thread = None
frm = ttk.Frame(root, padding=12)
frm.pack(fill=tk.BOTH, expand=True)
# Inputs
inputs = ttk.Frame(frm)
inputs.pack(fill=tk.X)
ttk.Label(inputs, text="Username:").grid(row=0, column=0, sticky=tk.W, pady=4)
self.username_var = tk.StringVar()
ttk.Entry(inputs, textvariable=self.username_var, width=40).grid(row=0, column=1, sticky=tk.W)
ttk.Label(inputs, text="Password:").grid(row=1, column=0, sticky=tk.W, pady=4)
self.password_var = tk.StringVar()
ttk.Entry(inputs, textvariable=self.password_var, width=40, show="*").grid(row=1, column=1, sticky=tk.W)
ttk.Label(inputs, text="Studio URL or Name:").grid(row=2, column=0, sticky=tk.W, pady=4)
self.studio_var = tk.StringVar()
ttk.Entry(inputs, textvariable=self.studio_var, width=60).grid(row=2, column=1, sticky=tk.W)
ttk.Label(inputs, text="Minimum Price:").grid(row=3, column=0, sticky=tk.W, pady=4)
self.min_price_var = tk.StringVar(value="6.00")
ttk.Entry(inputs, textvariable=self.min_price_var, width=12).grid(row=3, column=1, sticky=tk.W)
# Buttons
btns = ttk.Frame(frm, padding=(0, 8, 0, 8))
btns.pack(fill=tk.X)
self.start_btn = ttk.Button(btns, text="Start", command=self.start)
self.start_btn.pack(side=tk.LEFT, padx=6)
self.stop_btn = ttk.Button(btns, text="Stop", command=self.stop, state=tk.DISABLED)
self.stop_btn.pack(side=tk.LEFT, padx=6)
ttk.Button(btns, text="Open Export Folder", command=self.open_exports).pack(side=tk.LEFT, padx=6)
ttk.Button(btns, text="Save Credentials", command=self.save_creds).pack(side=tk.LEFT, padx=6)
# Status / Progress
status_frame = ttk.Frame(frm)
status_frame.pack(fill=tk.X)
self.status_var = tk.StringVar(value="Ready")
ttk.Label(status_frame, textvariable=self.status_var).pack(side=tk.LEFT)
self.progress = ttk.Progressbar(status_frame, mode="indeterminate")
self.progress.pack(fill=tk.X, padx=8, pady=6)
# Log panel
ttk.Label(frm, text="Logs:").pack(anchor=tk.W)
self.log_widget = scrolledtext.ScrolledText(frm, height=20, state=tk.DISABLED)
self.log_widget.pack(fill=tk.BOTH, expand=True)
# Poll logs
root.after(LOG_POLL_MS, self._poll_log)
def append_log(self, text: str):
self.log_widget.configure(state=tk.NORMAL)
self.log_widget.insert(tk.END, text + "\n")
self.log_widget.see(tk.END)
self.log_widget.configure(state=tk.DISABLED)
def _poll_log(self):
try:
while True:
item = self.log_queue.get_nowait()
if isinstance(item, dict) and item.get("type") == "status":
self.status_var.set(item.get("text", ""))
else:
self.append_log(str(item))
except queue.Empty:
pass
finally:
self.root.after(LOG_POLL_MS, self._poll_log)
def start(self):
username = self.username_var.get().strip()
password = self.password_var.get().strip()
studio = self.studio_var.get().strip()
try:
min_price = float(self.min_price_var.get().strip())
except Exception:
messagebox.showerror("Invalid input", "Minimum price must be a number")
return
if not username or not password or not studio:
messagebox.showerror("Missing fields", "Please enter username, password and studio URL/name")
return
self.stop_event.clear()
self.start_btn.config(state=tk.DISABLED)
self.stop_btn.config(state=tk.NORMAL)
self.progress.start(10)
self.status_var.set("Starting...")
runner = BotRunner(
username=username,
password=password,
studio_input=studio,
min_price=min_price,
log_queue=self.log_queue,
stop_event=self.stop_event,
)
def worker():
try:
runner.run()
self.log_queue.put({"type": "status", "text": "Completed"})
except Exception as e:
self.log_queue.put(f"Error: {e}")
finally:
self.progress.stop()
self.start_btn.config(state=tk.NORMAL)
self.stop_btn.config(state=tk.DISABLED)
self.worker_thread = threading.Thread(target=worker, daemon=True)
self.worker_thread.start()
def stop(self):
if messagebox.askyesno("Stop", "Stop the running job?"):
self.stop_event.set()
self.status_var.set("Stopping...")
def open_exports(self):
p = Path.cwd()
webbrowser.open(p.as_uri())
def save_creds(self):
u = self.username_var.get().strip()
p = self.password_var.get().strip()
if not u or not p:
messagebox.showerror("Error", "Provide both username and password to save")
return
save_credentials(u, p, DEFAULT_CREDENTIALS_FILE)
messagebox.showinfo("Saved", f"Credentials saved to {DEFAULT_CREDENTIALS_FILE}")
def run_gui():
root = tk.Tk()
gui = GUI(root)
root.mainloop()