diff --git a/pyproject.toml b/pyproject.toml index 8deb5b6..40cf6ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,8 @@ dependencies = [ "py-moneyed", "openpyxl", "semver", - "importlib-resources" + "importlib-resources", + "pywin32;sys_platform=='win32'" ] [project.optional-dependencies] # Optional diff --git a/src/banker/__main__.py b/src/banker/__main__.py index e9198d0..07b0b3d 100644 --- a/src/banker/__main__.py +++ b/src/banker/__main__.py @@ -1,7 +1,43 @@ +import logging +import logging.handlers +import os + from banker.gui.manager import GuiManager +def configure_logging(): + root_logger = logging.getLogger() + root_logger.setLevel(logging.DEBUG) + log_formatter = logging.Formatter(fmt="[{asctime}][T:{thread}][{name}][{funcName}][{levelname}] {message}", + style='{') + console_handler = logging.StreamHandler() + console_handler.setLevel(logging.WARNING) + console_handler.setFormatter(log_formatter) + root_logger.addHandler(console_handler) + app_identifier = "matusiak_dev_banker" + if os.name == "posix": + syslog_handler = logging.handlers.SysLogHandler(address="/dev/log") + syslog_handler.setLevel(logging.DEBUG) + syslog_handler.setFormatter(log_formatter) + syslog_handler.ident = f"{app_identifier}: " + root_logger.addHandler(syslog_handler) + elif os.name == "nt": + nt_event_handler = logging.handlers.NTEventLogHandler(appname=app_identifier) + nt_event_handler.setLevel(logging.DEBUG) + nt_event_handler.setFormatter(log_formatter) + root_logger.addHandler(nt_event_handler) + root_logger.info("Logging configured") + + def main(): - gui_manager = GuiManager() + try: + configure_logging() + gui_manager = GuiManager() + + gui_manager.run_mainloop() + except Exception as e: + logging.getLogger().exception(e) + - gui_manager.run_mainloop() +if __name__ == "__main__": + main() diff --git a/src/banker/common/filesystem.py b/src/banker/common/filesystem.py index 3fba831..2c48e84 100644 --- a/src/banker/common/filesystem.py +++ b/src/banker/common/filesystem.py @@ -1,19 +1,8 @@ -from banker.data.category import Category -from banker.data.transaction import Transaction -from banker.parser.interfaces.categories_parser import ICategoriesParser -from banker.parser.interfaces.transactions_parser import ITransactionsParser - - -def get_parsed_categories(categories_parser: ICategoriesParser, categories_filepath: str) -> list[Category]: - with open(categories_filepath, "r") as file: - return categories_parser.parse_categories(file.read()) - - -def get_parsed_transactions(transactions_parser: ITransactionsParser, transactions_filepath: str) -> list[Transaction]: - with open(transactions_filepath, "r") as transactions_file: - return transactions_parser.parse_transactions(transactions_file.read()) +def read_file(filepath: str) -> str: + with open(filepath, "r", encoding="utf-8") as file: + return file.read() def save_to_file(filepath: str, content: str): - with open(filepath, "w") as file: + with open(filepath, "w", encoding="utf-8") as file: file.write(content) diff --git a/src/banker/executor/executor.py b/src/banker/executor/executor.py index e041ff7..e18db58 100644 --- a/src/banker/executor/executor.py +++ b/src/banker/executor/executor.py @@ -1,7 +1,7 @@ import os from banker.analyzer.analyze import deduce_month_year, analyze_transactions -from banker.common.filesystem import get_parsed_categories, get_parsed_transactions, save_to_file +from banker.common.filesystem import save_to_file, read_file from banker.formatter.interfaces.transactions_formatter import ITransactionsFormatter from banker.formatter.month_year_formatter import format_month_year from banker.parser.interfaces.categories_parser import ICategoriesParser @@ -22,9 +22,9 @@ def execute(self, transactions_filepath: str, categories_filepath: str, output_d output_unmatched_transactions_filepath = os.path.join(output_directory, "unmatched_transactions.html") output_matched_categories_filepath = os.path.join(output_directory, "autogen_budget.xlsx") - all_transactions = get_parsed_transactions(self.__transactions_parser, transactions_filepath) + all_transactions = self.__transactions_parser.parse_transactions(read_file(transactions_filepath)) month_year = deduce_month_year(all_transactions) - supported_categories = get_parsed_categories(self.__categories_parser, categories_filepath) + supported_categories = self.__categories_parser.parse_categories(read_file(categories_filepath)) analyze_result = analyze_transactions(all_transactions, supported_categories) formatted_transactions = self.__transactions_formatter.format_transactions( analyze_result.unmatched_transactions) diff --git a/src/banker/gui/manager.py b/src/banker/gui/manager.py index da8bc4d..36d2970 100644 --- a/src/banker/gui/manager.py +++ b/src/banker/gui/manager.py @@ -1,3 +1,4 @@ +import logging import tkinter as tk from tkinter import filedialog from tkinter import messagebox @@ -12,6 +13,7 @@ class GuiManager: def __init__(self): + self.__logger = logging.getLogger(self.__class__.__name__) self.__app_name = "Bankier" self.__select_categories_button_title = "Wybierz plik konfiguracyjny" self.__select_transactions_button_title = "Wybierz plik z transakcjami" @@ -74,6 +76,7 @@ def __set_categories_file(self): if not categories_filepath: return self.__categories_filepath = categories_filepath + self.__logger.info(f"Categories filepath set to: {self.__categories_filepath}") def __set_transactions_file(self): self.__transactions_filepath = filedialog.askopenfilename(title=self.__select_transactions_dialog_title, @@ -85,22 +88,28 @@ def __set_transactions_file(self): self.__transactions_filepath = None self.__select_file_button.configure(bg=self.__select_file_button_default_color) self.__select_file_button.configure(activebackground=self.__select_file_button_default_active_color) + self.__logger.info(f"Transactions filepath set to: {self.__transactions_filepath}") + + def __set_output_directory(self): + self.__output_directory = filedialog.askdirectory(title=self.__select_output_dir_dialog_title) + if not self.__output_directory: + self.__output_directory = None + self.__logger.info(f"Output directory set to: {self.__output_directory}") def __analyze(self): if not self.__transactions_filepath: tk.messagebox.showerror(title="Błąd", message=f"Musisz wybrać plik z transakcjami") return - self.__output_directory = filedialog.askdirectory(title=self.__select_output_dir_dialog_title) + self.__set_output_directory() if not self.__output_directory: - self.__output_directory = None return - try: self.__executor.execute(self.__transactions_filepath, self.__categories_filepath, self.__output_directory) tk.messagebox.showinfo(title="Sukces", message=f"Pliki wyjściowe zapisano w katalogu: {self.__output_directory}") except Exception as e: + self.__logger.exception(e) tk.messagebox.showerror(title="Błąd", message=f"Wystąpił błąd: {e}")