From afe040d06dd2ae1bffce8ec31946392cba87c18c Mon Sep 17 00:00:00 2001 From: sroth Date: Sun, 13 Apr 2025 23:30:49 +0200 Subject: [PATCH] still setting up and testing basic structure --- src/brovski-adress-etiketten-verwaltung.py | 218 +++++++++++++++++---- 1 file changed, 180 insertions(+), 38 deletions(-) diff --git a/src/brovski-adress-etiketten-verwaltung.py b/src/brovski-adress-etiketten-verwaltung.py index b139e0d..8e18f4c 100644 --- a/src/brovski-adress-etiketten-verwaltung.py +++ b/src/brovski-adress-etiketten-verwaltung.py @@ -1,48 +1,190 @@ +import csv +import os import tkinter as tk +from configparser import NoSectionError, NoOptionError +from configparser import ConfigParser +from tkinter import messagebox from tkinter import ttk -from tksheet import Sheet +import json -def load_file(): - print("loading file") +class Config: + parser: ConfigParser + + def __init__(self): + """ + Config parser reading config.ini + + Attributes: + self.parser: ConfigParser holding list of sections and options + self.__filename: Path and name to the config file + """ + self.parser = ConfigParser() + + self.config_file_name = "config.ini" + self.root_path = os.path.dirname(os.path.abspath(__file__)) + self.config_file = os.path.join(self.root_path, self.config_file_name) + + self._load() + + def _save(self): + with open(self.config_file, 'w') as outfile: + self.parser.write(outfile) + + def _load(self): + self.parser.read(self.config_file) + + def add_section(self, section): + self._load() + self.parser.add_section(section) + self._save() + + def set(self, section: str, option: str, value: str): + self._load() + self.parser.set(section, option, value) + self._save() + + def get(self, section: str, option: str): + self._load() + return self.parser.get(section, option) -def save_file(): - print("saving file") +class Application: + def __init__(self): + self.config = Config() + + self.address_list = [] + + # json vars + self.json_file_name = "address_data.json" + self.root_path = os.path.dirname(os.path.abspath(__file__)) + self.json_file = os.path.join(self.root_path, self.json_file_name) + + # tkinter settings + x_offset = 700 + y_offset = 400 + title = "Brovski Adress-Etiketten Verwaltung" + + self.root = tk.Tk() + self.root.title(title) + self.root.geometry(f"+{x_offset}+{y_offset}") + + top_frame = tk.Frame(self.root) + top_frame.pack(side=tk.TOP, fill=tk.X) + button_width = 8 + tk.Button(top_frame, text="Load", command=self.load_file, width=button_width).grid(row=0, column=0) + tk.Button(top_frame, text="Safe", command=self.save_file, width=button_width).grid(row=0, column=1) + tk.Button(top_frame, text="Export CSV", command=self.export_csv, width=button_width).grid(row=0, column=2) + tk.Button(top_frame, text="Insert", command=self.export_csv, width=button_width).grid(row=1, column=0) + tk.Button(top_frame, text="Delete", command=self.export_csv, width=button_width).grid(row=1, column=1) + + self.firma = tk.StringVar() + self.name = tk.StringVar() + self.strasse = tk.StringVar() + self.plz_ort = tk.StringVar() + + edit_frame = tk.Frame(self.root) + edit_frame.pack(side=tk.TOP, fill=tk.X) + tk.Label(edit_frame, text="Firma").grid(row=0, column=0) + tk.Label(edit_frame, text="Name").grid(row=0, column=1) + tk.Label(edit_frame, text="Strasse").grid(row=0, column=3) + tk.Label(edit_frame, text="Plz/Ort").grid(row=0, column=4) + edit_firma = tk.Entry(edit_frame, textvariable=self.firma) + edit_firma.grid(row=1, column=0) + edit_name = tk.Entry(edit_frame, textvariable=self.name) + edit_name.grid(row=1, column=1) + edit_strasse = tk.Entry(edit_frame, textvariable=self.strasse) + edit_strasse.grid(row=1, column=3) + edit_plz_ort = tk.Entry(edit_frame, textvariable=self.plz_ort) + edit_plz_ort.grid(row=1, column=4) + + data_frame = tk.Frame(self.root, bg="teal") + data_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True) + + self.table = ttk.Treeview(data_frame, columns=("0", "1", "2", "3", "4"), show="headings") + self.table.heading('0', text="Aktiv") + self.table.heading('1', text="Firma") + self.table.heading('2', text="Name") + self.table.heading('3', text="Strasse") + self.table.heading('4', text="Plz/Ort") + self.table.pack() + + self.load_file() + + self.root.mainloop() + + def load_file(self): + try: + with open(self.json_file, "r", encoding="utf-8") as f: + self.address_list = json.load(f) + self.address_list.sort(key=lambda x: (x[0], x[1])) + except FileNotFoundError: + self.show_error( + message_title="File not found", + message=f"{self.json_file_name} not found, creating empty file at {self.root_path}" + ) + self.address_list = [["firma", "name", "adresse", "plz/ort"]] + with open(self.json_file, "w", encoding="utf-8") as f: + json.dump(self.address_list, f) + self.populate_table() + + def save_file(self): + try: + with open(self.json_file, "w", encoding="utf-8") as f: + json.dump(self.address_list, f, indent=4, sort_keys=True) + except FileNotFoundError: + self.show_error( + message_title="Unexpected Error: File not found?!", message=f"{self.json_file_name} not found" + ) + + def export_csv(self): + try: + file_name = self.config.get("csv", "file_name") + except NoOptionError: + self.show_error("Error: Option missing", "Option file_name is missing [csv]") + return + + try: + path = self.config.get("csv", "path") + except NoOptionError: + self.show_error("Error: Option missing", "Option path is missing [csv]") + return + + if file_name == "": + self.show_error("Error: Bad config file", "var file_name for section [csv] not set") + return + + if path == "": + self.show_error( + "Alert: CSV path not set", + f"var path for section [csv] not set, file will be saved in {self.root_path}" + ) + path = self.root_path + + csv_file = os.path.join(path, file_name) + try: + with open(csv_file, "w", encoding="utf-8") as f: + writer = csv.writer(f, delimiter=",") + for address in self.address_list: + if address[0] == "": + del address[0] + writer.writerow(address) + except FileNotFoundError: + self.show_error("Unexpected error", f"Could not write file {csv_file}") -def export_csv(): - print("exporting csv") + def populate_table(self): + self.delete_all_table_items() + for index, item in enumerate(self.address_list): + self.table.insert('', 'end', iid=index, values=item) + + def delete_all_table_items(self): + for item in self.table.get_children(): + self.table.delete(item) + + def show_error(self, message_title: str, message: str): + messagebox.showwarning(title=message_title, message=message) -customers = [ - ["", "hans muster", "musterstrasse", "musterort"], - ["muster-firma", "peter muster", "peterstrasse", "peterort"], -] -window_width = 500 -window_height = 400 -x_offset = 700 -y_offset = 400 - -root = tk.Tk() -# root.geometry(f"{window_width}x{window_height}+{x_offset}+{y_offset}") -root.geometry(f"+{x_offset}+{y_offset}") - -top_frame = tk.Frame(root) -top_frame.pack(side=tk.TOP, fill=tk.X) - -tk.Button(top_frame, text="Load", command=load_file).pack(side=tk.LEFT) -tk.Button(top_frame, text="Safe", command=save_file).pack(side=tk.LEFT) -tk.Button(top_frame, text="Export CSV", command=export_csv).pack(side=tk.LEFT) - -data_frame = tk.Frame(root, bg="teal") -data_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True) - -table = ttk.Treeview(data_frame, columns=("firma, name, strasse, plzort"), show="headings") -table.heading('firma', text="Firma") -table.heading('name', text="Name") -table.heading('strasse', text="Strasse") -table.heading('plzort', text="PLZ/Ort") -table.pack() - -root.mainloop() +if __name__ == '__main__': + Application()