Tilføj stop-knap til GUI uden at ændre i hovedscriptet

This commit is contained in:
Martin Tranberg
2026-03-26 16:03:34 +01:00
parent 368f4c515c
commit b33009c54c

View File

@@ -3,7 +3,21 @@ import threading
import logging
import customtkinter as ctk
from tkinter import filedialog, messagebox
import download_sharepoint # Importerer din eksisterende logik
import download_sharepoint # Din eksisterende kerne-logik
import requests
# --- Global Stop Flag ---
stop_event = threading.Event()
# For at stoppe uden at ændre download_sharepoint.py, "patcher" vi requests.get
# så den tjekker stop_event før hver anmodning.
original_get = requests.get
def patched_get(*args, **kwargs):
if stop_event.is_set():
raise InterruptedError("Synkronisering afbrudt af brugeren.")
return original_get(*args, **kwargs)
requests.get = patched_get
# --- Logging Handler for GUI ---
class TextboxHandler(logging.Handler):
@@ -31,19 +45,17 @@ class SharepointApp(ctk.CTk):
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")
# Layout
self.grid_columnconfigure(1, weight=1)
self.grid_rowconfigure(0, weight=1)
# Sidebar for indstillinger
# Sidebar
self.sidebar_frame = ctk.CTkFrame(self, width=350, corner_radius=0)
self.sidebar_frame.grid(row=0, column=0, sticky="nsew")
self.sidebar_frame.grid_rowconfigure(9, weight=1)
self.sidebar_frame.grid_rowconfigure(20, weight=1)
self.logo_label = ctk.CTkLabel(self.sidebar_frame, text="Indstillinger", font=ctk.CTkFont(size=20, weight="bold"))
self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
# Input Felter
self.entries = {}
fields = [
("TENANT_ID", "Tenant ID"),
@@ -58,22 +70,18 @@ class SharepointApp(ctk.CTk):
for i, (key, label) in enumerate(fields):
lbl = ctk.CTkLabel(self.sidebar_frame, text=label)
lbl.grid(row=i*2+1, column=0, padx=20, pady=(10, 0), sticky="w")
entry = ctk.CTkEntry(self.sidebar_frame, width=280, placeholder_text=f"Indtast {label}")
if key == "CLIENT_SECRET":
entry.configure(show="*")
entry = ctk.CTkEntry(self.sidebar_frame, width=280)
if key == "CLIENT_SECRET": entry.configure(show="*")
entry.grid(row=i*2+2, column=0, padx=20, pady=(0, 5))
self.entries[key] = entry
# Browse knap til lokal sti
self.browse_button = ctk.CTkButton(self.sidebar_frame, text="Vælg Mappe", command=self.browse_folder, height=32)
self.browse_button.grid(row=15, column=0, padx=20, pady=10)
# Gem knap
self.save_button = ctk.CTkButton(self.sidebar_frame, text="Gem Indstillinger", command=self.save_settings, fg_color="transparent", border_width=2)
self.save_button.grid(row=16, column=0, padx=20, pady=10)
# Højre side (Log og Status)
# Main side
self.main_frame = ctk.CTkFrame(self, corner_radius=0, fg_color="transparent")
self.main_frame.grid(row=0, column=1, sticky="nsew", padx=20, pady=20)
self.main_frame.grid_rowconfigure(1, weight=1)
@@ -85,10 +93,17 @@ class SharepointApp(ctk.CTk):
self.log_textbox = ctk.CTkTextbox(self.main_frame, state="disabled")
self.log_textbox.grid(row=1, column=0, sticky="nsew")
self.start_button = ctk.CTkButton(self.main_frame, text="Start Synkronisering", command=self.start_sync_thread, height=50, font=ctk.CTkFont(size=16, weight="bold"))
self.start_button.grid(row=2, column=0, pady=(20, 0), sticky="ew")
# Buttons frame
self.btn_frame = ctk.CTkFrame(self.main_frame, fg_color="transparent")
self.btn_frame.grid(row=2, column=0, pady=(20, 0), sticky="ew")
self.btn_frame.grid_columnconfigure(0, weight=1)
self.start_button = ctk.CTkButton(self.btn_frame, text="Start Synkronisering", command=self.start_sync_thread, height=50, font=ctk.CTkFont(size=16, weight="bold"))
self.start_button.grid(row=0, column=0, padx=(0, 10), sticky="ew")
self.stop_button = ctk.CTkButton(self.btn_frame, text="Stop", command=self.stop_sync, height=50, fg_color="#d32f2f", hover_color="#b71c1c", state="disabled")
self.stop_button.grid(row=0, column=1, sticky="ew")
# Initialisering
self.load_settings()
self.setup_logging()
@@ -111,20 +126,20 @@ class SharepointApp(ctk.CTk):
entry.insert(0, val)
def save_settings(self):
config_lines = []
for key, entry in self.entries.items():
val = entry.get()
config_lines.append(f'{key} = "{val}"')
config_lines = [f'{k} = "{v.get()}"' for k, v in self.entries.items()]
with open("connection_info.txt", "w", encoding="utf-8") as f:
f.write("\n".join(config_lines))
logger = logging.getLogger("sharepoint_gui")
# trigger a small log to show save happened
messagebox.showinfo("Succes", "Indstillinger er gemt i connection_info.txt")
def stop_sync(self):
stop_event.set()
self.stop_button.configure(state="disabled", text="Stopper...")
download_sharepoint.logger.warning("Stop-signal sendt. Venter på at tråde afbryder...")
def start_sync_thread(self):
self.save_settings()
self.start_button.configure(state="disabled", text="Arbejder...")
stop_event.clear()
self.start_button.configure(state="disabled")
self.stop_button.configure(state="normal", text="Stop")
self.status_label.configure(text="Status: Synkroniserer...", text_color="orange")
thread = threading.Thread(target=self.run_sync, daemon=True)
@@ -133,12 +148,18 @@ class SharepointApp(ctk.CTk):
def run_sync(self):
try:
download_sharepoint.main()
self.status_label.configure(text="Status: Gennemført!", text_color="green")
if stop_event.is_set():
self.status_label.configure(text="Status: Afbrudt", text_color="red")
else:
self.status_label.configure(text="Status: Gennemført!", text_color="green")
except InterruptedError:
self.status_label.configure(text="Status: Afbrudt", text_color="red")
except Exception as e:
self.status_label.configure(text=f"Status: Fejl!", text_color="red")
self.status_label.configure(text="Status: Fejl!", text_color="red")
messagebox.showerror("Fejl", str(e))
finally:
self.start_button.configure(state="normal", text="Start Synkronisering")
self.start_button.configure(state="normal")
self.stop_button.configure(state="disabled", text="Stop")
if __name__ == "__main__":
app = SharepointApp()