updated some stuff (not worthy of a vb!)
This commit is contained in:
@@ -16,7 +16,7 @@ import numpy as np
|
||||
import shutil
|
||||
|
||||
# Local Dependencies
|
||||
from PfandApplication.wiki import main as WIKI
|
||||
from PfandApplication.wiki import main as wiki
|
||||
from PfandApplication.pfand_scanner import launch_pfand_scanner
|
||||
from PfandApplication.updater import open_updater as open_updater, run_silent_update
|
||||
from PfandApplication.tgtg_orderchecker import main as tgtg
|
||||
@@ -33,6 +33,7 @@ class Achievement:
|
||||
|
||||
class PfandCalculator:
|
||||
def __init__(self, root):
|
||||
self.achievement_image_gray = None
|
||||
self.root = root
|
||||
self.root.title("Österreichischer Pfandrechner")
|
||||
|
||||
@@ -63,7 +64,8 @@ class PfandCalculator:
|
||||
|
||||
self.achievement_image = self.load_achievement_image()
|
||||
|
||||
def load_image(self, product_name):
|
||||
@staticmethod
|
||||
def load_image(product_name):
|
||||
try:
|
||||
# Use Flaschen icon for Bierflasche
|
||||
if product_name == "Bierflasche":
|
||||
@@ -115,7 +117,8 @@ class PfandCalculator:
|
||||
print(f"Error loading achievement image: {e}")
|
||||
return None
|
||||
|
||||
def initialize_achievements(self):
|
||||
@staticmethod
|
||||
def initialize_achievements():
|
||||
return {
|
||||
"each_100": Achievement("Krass, Weiter So!", "Du hast bis jetzt 100 von jedem Element gesammelt!", "each_element", 100),
|
||||
"each_500": Achievement("Adlersson wäre neidisch!", "Adlersson wäre neidisch auf dich! Du hast 500 von jedem Element gesammelt!", "each_element", 500),
|
||||
@@ -463,7 +466,7 @@ class PfandCalculator:
|
||||
file_menu.add_command(label="Neulanden der UI", command=self.recreate_widgets, accelerator="Strg+R")
|
||||
file_menu.add_command(label="Updater", command=open_updater, accelerator="Strg+U") # Added this to the File Menu too!
|
||||
file_menu.add_separator()
|
||||
file_menu.add_command(label="Öffne PfandListe", command=WIKI.select_file, accelerator="Strg+L")
|
||||
file_menu.add_command(label="Öffne PfandListe", command=wiki.select_file, accelerator="Strg+L")
|
||||
file_menu.add_command(label="Beenden", command=self.root.quit, accelerator="Strg+Q")
|
||||
file_menu.add_separator()
|
||||
file_menu.add_command(label="Über Programm", command=self.create_credits, accelerator="Strg+F10")
|
||||
@@ -538,7 +541,7 @@ class PfandCalculator:
|
||||
self.root.bind('<Control-E>', lambda e: self.export_barcodes_csv() if e.state & 0x1 else self.export_history_csv())
|
||||
self.root.bind('<Control-p>', lambda e: self.show_add_product_window())
|
||||
self.root.bind('<Control-P>', lambda e: self.show_manage_products_window() if e.state & 0x1 else self.show_add_product_window())
|
||||
self.root.bind('<Control-l>', lambda e: WIKI.select_file())
|
||||
self.root.bind('<Control-l>', lambda e: wiki.select_file())
|
||||
self.root.bind('<Control-r>', lambda e: self.recreate_widgets())
|
||||
self.root.bind('<Control-u>', lambda e: open_updater()) # New Update Feature (Version 7.4.000 UPDATER)
|
||||
|
||||
@@ -1564,12 +1567,14 @@ class PfandCalculator:
|
||||
root = tk.Tk()
|
||||
app = PfandCalculator(root)
|
||||
|
||||
if check_for_update == True:
|
||||
root.after(1, run_silent_update) # Run uc on start (1s delay) => updater.py module || UNCOMMENT IN PROD
|
||||
else:
|
||||
if check_for_update is None:
|
||||
root.after(500, root.destroy) # We do a lil bit of Trolling here
|
||||
elif not check_for_update:
|
||||
pass
|
||||
else:
|
||||
root.after(1, run_silent_update)
|
||||
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
PfandCalculator.launch(True)
|
||||
# Run AutoUpdates by default
|
||||
if __name__ == "__main__": PfandCalculator.launch(True)
|
||||
|
||||
@@ -16,10 +16,10 @@ class TGTGOrdersApp:
|
||||
self.notebook.pack(fill="both", expand=True)
|
||||
|
||||
self.orders_tab = tk.Frame(self.notebook, bg="#ffffff")
|
||||
self.notebook.add(self.orders_tab, text="Orders")
|
||||
self.notebook.add(self.orders_tab, text="Bestellungen")
|
||||
|
||||
self.log_tab = tk.Frame(self.notebook, bg="#ffffff")
|
||||
self.notebook.add(self.log_tab, text="Log")
|
||||
self.notebook.add(self.log_tab, text="Protokoll")
|
||||
|
||||
self.log_text = tk.Text(self.log_tab, wrap=tk.WORD, height=15, font=("Arial", 10), bg="#f0f0f0")
|
||||
self.log_text.pack(fill="both", expand=True, padx=10, pady=10)
|
||||
@@ -30,12 +30,12 @@ class TGTGOrdersApp:
|
||||
self.menu = Menu(self.parent)
|
||||
self.parent.config(menu=self.menu)
|
||||
self.filemenu = Menu(self.menu)
|
||||
self.menu.add_cascade(label="File", menu=self.filemenu)
|
||||
self.filemenu.add_command(label="Exit", command=self.exit_applet)
|
||||
self.filemenu.add_command(label="Refetch", command=self.display_orders)
|
||||
self.filemenu.add_command(label="Save Log", command=self.save_log)
|
||||
self.menu.add_cascade(label="Datei", menu=self.filemenu)
|
||||
self.filemenu.add_command(label="Beenden", command=self.exit_applet)
|
||||
self.filemenu.add_command(label="Aktualisieren", command=self.display_orders)
|
||||
self.filemenu.add_command(label="Protokoll speichern", command=self.save_log)
|
||||
self.filemenu.add_separator()
|
||||
self.filemenu.add_command(label="About", command=self.about)
|
||||
self.filemenu.add_command(label="Über", command=self.about)
|
||||
|
||||
self.parent.after(1000, self.on_startup)
|
||||
|
||||
@@ -44,62 +44,60 @@ class TGTGOrdersApp:
|
||||
self.log_text.insert(tk.END, f"{timestamp} - {message}\n")
|
||||
self.log_text.yview(tk.END)
|
||||
|
||||
def format_time(self, iso_time):
|
||||
@staticmethod
|
||||
def format_time(iso_time):
|
||||
try:
|
||||
dt = datetime.fromisoformat(iso_time.replace("Z", "+00:00"))
|
||||
local_time = dt.astimezone()
|
||||
return local_time.strftime("%H:%M")
|
||||
except ValueError:
|
||||
return "Unknown Error!"
|
||||
return "Unbekannter Fehler!"
|
||||
|
||||
def fetch_orders(self):
|
||||
self.log_message("[ INFO ]: Fetching orders...")
|
||||
self.log_message("[ INFO ]: Bestellungen werden abgerufen...")
|
||||
try:
|
||||
active_orders = client.get_active()
|
||||
if not isinstance(active_orders, dict) or "orders" not in active_orders:
|
||||
raise ValueError("Unexpected API response format.")
|
||||
raise ValueError("Unerwartetes API-Antwortformat.")
|
||||
orders_list = active_orders.get("orders", [])
|
||||
except Exception as e:
|
||||
self.log_message(f"[ ERROR ]: Error fetching active orders: {e}")
|
||||
messagebox.showerror("Error", f"Error fetching active orders: {e}")
|
||||
self.log_message(f"[ FEHLER ]: Fehler beim Abrufen aktiver Bestellungen: {e}")
|
||||
messagebox.showerror("Fehler", f"Fehler beim Abrufen aktiver Bestellungen: {e}")
|
||||
return []
|
||||
|
||||
orders_data = []
|
||||
for order in orders_list:
|
||||
try:
|
||||
order_info = {
|
||||
"name": order.get("item_name", "Unknown"),
|
||||
"store_name": order.get("store_name", "Unknown"),
|
||||
"address": order.get("pickup_location", {}).get("address", {}).get("address_line", "Unknown"),
|
||||
"name": order.get("item_name", "Unbekannt"),
|
||||
"store_name": order.get("store_name", "Unbekannt"),
|
||||
"address": order.get("pickup_location", {}).get("address", {}).get("address_line", "Unbekannt"),
|
||||
"quantity": order.get("quantity", 1),
|
||||
"price": order.get("total_price", {}).get("minor_units", 0) / (10 ** order.get("total_price", {}).get("decimals", 2)),
|
||||
"currency": order.get("total_price", {}).get("code", "Unknown"),
|
||||
"payment_method": order.get("payment_method_display_name", "Unknown"),
|
||||
"currency": order.get("total_price", {}).get("code", "Unbekannt"),
|
||||
"payment_method": order.get("payment_method_display_name", "Unbekannt"),
|
||||
"pickup_window": {
|
||||
"start": self.format_time(order.get("pickup_interval", {}).get("start", "Unknown")),
|
||||
"end": self.format_time(order.get("pickup_interval", {}).get("end", "Unknown"))
|
||||
"start": self.format_time(order.get("pickup_interval", {}).get("start", "Unbekannt")),
|
||||
"end": self.format_time(order.get("pickup_interval", {}).get("end", "Unbekannt"))
|
||||
},
|
||||
"image_url": order.get("item_cover_image", {}).get("current_url", "")
|
||||
}
|
||||
orders_data.append(order_info)
|
||||
except Exception as e:
|
||||
self.log_message(f"[ FATAL ERROR ]: Skipping an order due to an error: {e}")
|
||||
self.log_message(f"[ KRITISCHER FEHLER ]: Eine Bestellung wird übersprungen: {e}")
|
||||
return orders_data
|
||||
|
||||
|
||||
def display_orders(self):
|
||||
self.log_message("[ INFO ]: Displaying orders...")
|
||||
self.log_message("[ INFO ]: Bestellungen werden angezeigt...")
|
||||
orders = self.fetch_orders()
|
||||
if not orders:
|
||||
messagebox.showinfo("Info", "No active orders found.")
|
||||
self.log_message("[ ERROR ]: No active orders found.")
|
||||
messagebox.showinfo("Info", "Keine aktiven Bestellungen gefunden.")
|
||||
self.log_message("[ FEHLER ]: Keine aktiven Bestellungen gefunden.")
|
||||
return
|
||||
|
||||
# Clear existing widgets
|
||||
for widget in self.order_frame.winfo_children():
|
||||
widget.destroy()
|
||||
|
||||
# Create a scrollable frame inside a Canvas
|
||||
canvas = tk.Canvas(self.order_frame, bg="#ffffff")
|
||||
scroll_frame = tk.Frame(canvas, bg="#ffffff")
|
||||
scrollbar = tk.Scrollbar(self.order_frame, orient="vertical", command=canvas.yview)
|
||||
@@ -110,16 +108,15 @@ class TGTGOrdersApp:
|
||||
canvas.pack(side="left", fill="both", expand=True)
|
||||
canvas.create_window((0, 0), window=scroll_frame, anchor="nw")
|
||||
|
||||
# Store image references to prevent garbage collection
|
||||
image_refs = []
|
||||
|
||||
for order in orders:
|
||||
text = (f"{order['name']} - {order['store_name']}\n"
|
||||
f"Address: {order['address']}\n"
|
||||
f"Quantity: {order['quantity']}\n"
|
||||
f"Price: {order['price']} {order['currency']}\n"
|
||||
f"Payment: {order['payment_method']}\n"
|
||||
f"Pickup: {order['pickup_window']['start']} to {order['pickup_window']['end']}\n")
|
||||
f"Adresse: {order['address']}\n"
|
||||
f"Menge: {order['quantity']}\n"
|
||||
f"Preis: {order['price']} {order['currency']}\n"
|
||||
f"Zahlung: {order['payment_method']}\n"
|
||||
f"Abholung: {order['pickup_window']['start']} bis {order['pickup_window']['end']}\n")
|
||||
|
||||
label = tk.Label(scroll_frame, text=text, justify="left", padx=10, pady=5, anchor="w", font=("Arial", 10),
|
||||
bg="#f0f0f0", relief="ridge")
|
||||
@@ -134,50 +131,47 @@ class TGTGOrdersApp:
|
||||
img_tk = ImageTk.PhotoImage(img)
|
||||
|
||||
img_label = tk.Label(scroll_frame, image=img_tk)
|
||||
img_label.image = img_tk # Store reference
|
||||
image_refs.append(img_tk) # Prevent garbage collection
|
||||
img_label.image = img_tk
|
||||
image_refs.append(img_tk)
|
||||
img_label.pack(pady=5)
|
||||
except Exception as e:
|
||||
self.log_message(f"[ ERROR ]: Failed to load image: {e}")
|
||||
self.log_message(f"[ FEHLER ]: Bild konnte nicht geladen werden: {e}")
|
||||
|
||||
# Update scroll region
|
||||
scroll_frame.update_idletasks()
|
||||
canvas.config(scrollregion=canvas.bbox("all"))
|
||||
|
||||
# Enable scrolling with the mouse wheel
|
||||
def on_mouse_wheel(event):
|
||||
canvas.yview_scroll(-1 * (event.delta // 120), "units")
|
||||
|
||||
canvas.bind_all("<MouseWheel>", on_mouse_wheel) # Windows & MacOS
|
||||
canvas.bind_all("<Button-4>", lambda e: canvas.yview_scroll(-1, "units")) # Linux Scroll Up
|
||||
canvas.bind_all("<Button-5>", lambda e: canvas.yview_scroll(1, "units")) # Linux Scroll Down
|
||||
canvas.bind_all("<MouseWheel>", on_mouse_wheel)
|
||||
canvas.bind_all("<Button-4>", lambda e: canvas.yview_scroll(-1, "units"))
|
||||
canvas.bind_all("<Button-5>", lambda e: canvas.yview_scroll(1, "units"))
|
||||
|
||||
def on_startup(self):
|
||||
self.log_message("[ INFO ]: Application started.")
|
||||
self.log_message("[ INFO ]: Anwendung gestartet.")
|
||||
self.display_orders()
|
||||
|
||||
def exit_applet(self):
|
||||
self.log_message("[ INFO ]: Exiting Applet")
|
||||
self.log_message("[ INFO ]: Anwendung wird beendet.")
|
||||
self.parent.quit()
|
||||
|
||||
def about(self):
|
||||
messagebox.showinfo("About", "PythonTGTG Script for fetching Orders on Desktop")
|
||||
@staticmethod
|
||||
def about():
|
||||
messagebox.showinfo("Über", "TGTG OrderChecker PV2-PKG1\n PfandApplication ©")
|
||||
|
||||
def save_log(self):
|
||||
try:
|
||||
log_content = self.log_text.get("1.0", tk.END)
|
||||
with open("log_file.log", "w") as log_file:
|
||||
with open("protokoll_datei.log", "w") as log_file:
|
||||
log_file.write(log_content)
|
||||
self.log_message("[ INFO ]: Log file saved successfully.")
|
||||
self.log_message("[ INFO ]: Protokolldatei erfolgreich gespeichert.")
|
||||
except Exception as e:
|
||||
self.log_message(f"[ ERROR ]: Error saving log file: {e}")
|
||||
messagebox.showerror("Error", f"Error saving log file: {e}")
|
||||
self.log_message(f"[ FEHLER ]: Fehler beim Speichern des Protokolls: {e}")
|
||||
messagebox.showerror("Fehler", f"Fehler beim Speichern des Protokolls: {e}")
|
||||
|
||||
def start_tgtg(parent=None):
|
||||
new_window = tk.Toplevel(parent) # Create a new window
|
||||
new_window.title("TGTG Bestellungen")
|
||||
new_window = tk.Toplevel(parent)
|
||||
new_window.title("TGTG Orders")
|
||||
new_window.geometry("500x600")
|
||||
|
||||
# Start the TGTGOrdersApp inside this new window
|
||||
app = TGTGOrdersApp(new_window)
|
||||
|
||||
|
||||
0
PfandApplication/wiki/__init__.py
Normal file
0
PfandApplication/wiki/__init__.py
Normal file
@@ -1,8 +1,9 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import csv
|
||||
import os
|
||||
import re
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
|
||||
|
||||
def select_file(callback=None):
|
||||
def set_choice(choice):
|
||||
@@ -39,7 +40,7 @@ class CSVViewerApp:
|
||||
self.root = root
|
||||
title = "PFANDLISTE - SPAR" if "SPAR" in filename else "PFANDLISTE - HOFER"
|
||||
self.root.title(title)
|
||||
self.root.geometry("600x400")
|
||||
self.root.geometry("800x600")
|
||||
|
||||
self.label = tk.Label(root, text=title, font=("Arial", 16, "bold"))
|
||||
self.label.pack(pady=10)
|
||||
@@ -47,7 +48,7 @@ class CSVViewerApp:
|
||||
self.frame = tk.Frame(root)
|
||||
self.frame.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
self.tree = ttk.Treeview(self.frame)
|
||||
self.tree = ttk.Treeview(self.frame, show="headings")
|
||||
self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
||||
|
||||
self.scrollbar = ttk.Scrollbar(self.frame, orient="vertical", command=self.tree.yview)
|
||||
@@ -55,31 +56,86 @@ class CSVViewerApp:
|
||||
|
||||
self.tree.configure(yscroll=self.scrollbar.set)
|
||||
|
||||
# Create a frame for search functionality and style it
|
||||
search_frame = tk.Frame(root, pady=10, padx=20)
|
||||
search_frame.pack(fill=tk.X)
|
||||
|
||||
self.search_label = tk.Label(search_frame, text="Search:", font=("Arial", 12), anchor="w")
|
||||
self.search_label.pack(side=tk.LEFT)
|
||||
|
||||
self.search_entry = tk.Entry(search_frame, font=("Arial", 12), relief="solid", borderwidth=2)
|
||||
self.search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=10)
|
||||
self.search_entry.bind("<KeyRelease>", self.search)
|
||||
|
||||
self.load_csv(filename)
|
||||
|
||||
def load_csv(self, filename):
|
||||
def search(self, event):
|
||||
search_term = self.search_entry.get().lower()
|
||||
for row in self.tree.get_children():
|
||||
self.tree.delete(row)
|
||||
self.load_csv(self.filename, search_term)
|
||||
|
||||
def load_csv(self, filename, search_term=""):
|
||||
self.filename = filename
|
||||
try:
|
||||
with open(filename, newline='', encoding='utf-8') as file:
|
||||
reader = csv.reader(file)
|
||||
headers = next(reader, None)
|
||||
|
||||
self.tree['columns'] = headers
|
||||
self.tree["columns"] = headers
|
||||
self.tree.heading("#0", text="#") # First column for index
|
||||
self.tree.column("#0", width=50)
|
||||
self.tree.column("#0", width=50, anchor="center")
|
||||
|
||||
for header in headers:
|
||||
self.tree.heading(header, text=header)
|
||||
self.tree.column(header, anchor="center")
|
||||
|
||||
for i, row in enumerate(reader, start=1):
|
||||
self.tree.insert("", "end", text=i, values=row)
|
||||
if any(search_term.lower() in str(cell).lower() for cell in row):
|
||||
self.tree.insert("", "end", text=i, values=row)
|
||||
except FileNotFoundError:
|
||||
print(f"Error: {filename} not found!")
|
||||
except Exception as e:
|
||||
print(f"Error loading CSV: {e}")
|
||||
|
||||
## Doesnt really work yet
|
||||
## In the Future maybe
|
||||
def sort_column(self, col):
|
||||
data = [(self.tree.item(item)["values"], item) for item in self.tree.get_children("")]
|
||||
data.sort(key=lambda x: x[0][col])
|
||||
for idx, item in enumerate(data):
|
||||
self.tree.move(item[1], '', idx)
|
||||
|
||||
def right_click_menu(self, event):
|
||||
selected_item = self.tree.selection()
|
||||
menu = tk.Menu(self.root, tearoff=0)
|
||||
menu.add_command(label="Copy", command=lambda: self.copy_cell(selected_item))
|
||||
menu.post(event.x_root, event.y_root)
|
||||
|
||||
def copy_cell(self, selected_item):
|
||||
# Copy data from the selected row to clipboard
|
||||
if selected_item:
|
||||
row_values = self.tree.item(selected_item[0])["values"]
|
||||
self.root.clipboard_clear()
|
||||
self.root.clipboard_append(' | '.join(row_values))
|
||||
|
||||
def open_wiki():
|
||||
wiki_window = tk.Tk()
|
||||
wiki_window.title("Wiki")
|
||||
wiki_window.geometry("500x400")
|
||||
|
||||
text_area = tk.Text(wiki_window, wrap=tk.WORD)
|
||||
text_area.pack(expand=True, fill=tk.BOTH)
|
||||
|
||||
filename = os.path.join("PfandApplication/wiki", "wiki.md")
|
||||
|
||||
try:
|
||||
with open(filename, "r", encoding="utf-8") as file:
|
||||
content = file.read()
|
||||
format_markdown(text_area, content)
|
||||
except FileNotFoundError:
|
||||
text_area.insert(tk.END, f"Fehler: '{filename}' nicht gefunden!")
|
||||
|
||||
wiki_window.mainloop()
|
||||
|
||||
def format_markdown(text_area, text):
|
||||
text_area.tag_configure("bold", font=("Arial", 10, "bold"))
|
||||
text_area.tag_configure("center", justify="center")
|
||||
@@ -104,30 +160,9 @@ def format_markdown(text_area, text):
|
||||
for segment, tag in segments:
|
||||
text_area.insert(tk.END, segment, tag if tag else "")
|
||||
|
||||
def open_wiki():
|
||||
wiki_window = tk.Tk()
|
||||
wiki_window.title("Wiki")
|
||||
wiki_window.geometry("500x400")
|
||||
|
||||
text_area = tk.Text(wiki_window, wrap=tk.WORD)
|
||||
text_area.pack(expand=True, fill=tk.BOTH)
|
||||
|
||||
filename = os.path.join("PfandApplication/wiki", "wiki.md")
|
||||
|
||||
try:
|
||||
with open(filename, "r", encoding="utf-8") as file:
|
||||
content = file.read()
|
||||
format_markdown(text_area, content)
|
||||
except FileNotFoundError:
|
||||
text_area.insert(tk.END, f"Fehler: '{filename}' nicht gefunden!")
|
||||
|
||||
wiki_window.mainloop()
|
||||
|
||||
def start_app(filename):
|
||||
root = tk.Tk()
|
||||
app = CSVViewerApp(root, filename)
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
select_file()
|
||||
|
||||
if __name__ == "__main__": select_file()
|
||||
17
run.py
17
run.py
@@ -1,15 +1,14 @@
|
||||
from PfandApplication import main
|
||||
if __name__ == "__main__": main.PfandCalculator.launch(False)
|
||||
|
||||
"""
|
||||
|
||||
If the function launch gets called with
|
||||
|
||||
False -> No autoupdates will be run || Best for Debugging!
|
||||
|
||||
True -> Autoupdates will be run
|
||||
/********************************************
|
||||
* Launch Function Parameters *
|
||||
* *
|
||||
* True -> Auto-Update *
|
||||
* False -> Dont Auto-Update *
|
||||
* None -> Idk check it :3 *
|
||||
********************************************/
|
||||
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main.PfandCalculator.launch(False)
|
||||
|
||||
Reference in New Issue
Block a user