Migrate to GitLab
This commit is contained in:
110
excel_filter/utils/file_utils.py
Normal file
110
excel_filter/utils/file_utils.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""
|
||||
File utility functions for the Excel Filter Tool
|
||||
"""
|
||||
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog
|
||||
import json
|
||||
import logging
|
||||
|
||||
# Logging konfigurieren
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def browse_file(initialdir=None, filetypes=None, title="Datei auswählen"):
|
||||
"""
|
||||
Opens a file dialog to browse and select a file
|
||||
|
||||
Args:
|
||||
initialdir: Initial directory to open
|
||||
filetypes: File types to filter by
|
||||
title: Dialog title
|
||||
|
||||
Returns:
|
||||
Selected file path or None if canceled
|
||||
"""
|
||||
root = tk.Tk()
|
||||
root.withdraw() # Hide the main window
|
||||
|
||||
file_path = filedialog.askopenfilename(
|
||||
initialdir=initialdir,
|
||||
title=title,
|
||||
filetypes=filetypes
|
||||
)
|
||||
|
||||
root.destroy()
|
||||
return file_path
|
||||
|
||||
|
||||
def browse_save_file(initialdir=None, filetypes=None, title="Datei speichern", defaultextension=".xlsx"):
|
||||
"""
|
||||
Opens a file dialog to browse and save a file
|
||||
|
||||
Args:
|
||||
initialdir: Initial directory to open
|
||||
filetypes: File types to filter by
|
||||
title: Dialog title
|
||||
defaultextension: Default file extension
|
||||
|
||||
Returns:
|
||||
Selected file path or None if canceled
|
||||
"""
|
||||
root = tk.Tk()
|
||||
root.withdraw() # Hide the main window
|
||||
|
||||
file_path = filedialog.asksaveasfilename(
|
||||
initialdir=initialdir,
|
||||
title=title,
|
||||
filetypes=filetypes,
|
||||
defaultextension=defaultextension
|
||||
)
|
||||
|
||||
root.destroy()
|
||||
return file_path
|
||||
|
||||
|
||||
def load_config(config_file: str) -> dict:
|
||||
"""
|
||||
Loads configuration from a JSON file
|
||||
|
||||
Args:
|
||||
config_file: Path to the configuration file
|
||||
|
||||
Returns:
|
||||
Dictionary containing the configuration
|
||||
|
||||
Raises:
|
||||
Exception if the file cannot be loaded
|
||||
"""
|
||||
try:
|
||||
with open(config_file, 'r') as f:
|
||||
config = json.load(f)
|
||||
logger.info(f"Configuration loaded: {config_file}")
|
||||
return config
|
||||
except FileNotFoundError:
|
||||
logger.warning(f"Configuration file not found: {config_file}")
|
||||
return {}
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading configuration: {e}")
|
||||
raise Exception(f"Error loading configuration: {e}")
|
||||
|
||||
|
||||
def save_config(config_file: str, config: dict):
|
||||
"""
|
||||
Saves configuration to a JSON file
|
||||
|
||||
Args:
|
||||
config_file: Path to the configuration file
|
||||
config: Dictionary containing the configuration to save
|
||||
|
||||
Raises:
|
||||
Exception if the file cannot be saved
|
||||
"""
|
||||
try:
|
||||
with open(config_file, 'w') as f:
|
||||
json.dump(config, f, indent=4)
|
||||
logger.info(f"Configuration saved: {config_file}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving configuration: {e}")
|
||||
raise Exception(f"Error saving configuration: {e}")
|
||||
114
excel_filter/utils/logging_utils.py
Normal file
114
excel_filter/utils/logging_utils.py
Normal file
@@ -0,0 +1,114 @@
|
||||
"""
|
||||
Logging utility functions for the Excel Filter Tool
|
||||
"""
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
import tkinter as tk
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def setup_logging(log_file=None, level=logging.INFO):
|
||||
"""
|
||||
Sets up logging configuration
|
||||
|
||||
Args:
|
||||
log_file: Optional path to log file
|
||||
level: Logging level
|
||||
"""
|
||||
handlers = [logging.StreamHandler()]
|
||||
|
||||
if log_file:
|
||||
handlers.append(logging.FileHandler(log_file))
|
||||
|
||||
logging.basicConfig(
|
||||
level=level,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
handlers=handlers
|
||||
)
|
||||
|
||||
|
||||
def log_message(text_widget, message, is_error=False):
|
||||
"""
|
||||
Logs a message to a Tkinter Text widget
|
||||
|
||||
Args:
|
||||
text_widget: Tkinter Text widget to log to
|
||||
message: Message to log
|
||||
is_error: Whether this is an error message
|
||||
"""
|
||||
timestamp = datetime.now().strftime("%H:%M:%S")
|
||||
log_entry = f"[{timestamp}] {message}\n"
|
||||
|
||||
text_widget.config(state=tk.NORMAL)
|
||||
text_widget.insert(tk.END, log_entry)
|
||||
|
||||
if is_error:
|
||||
text_widget.tag_add("error", f"{text_widget.index(tk.END)} - 1 lines", tk.END)
|
||||
text_widget.tag_config("error", foreground="red")
|
||||
|
||||
text_widget.see(tk.END)
|
||||
text_widget.config(state=tk.DISABLED)
|
||||
|
||||
# Also log to console
|
||||
if is_error:
|
||||
logger.error(message)
|
||||
else:
|
||||
logger.info(message)
|
||||
|
||||
|
||||
def log_error(text_widget, message):
|
||||
"""
|
||||
Logs an error message to a Tkinter Text widget
|
||||
|
||||
Args:
|
||||
text_widget: Tkinter Text widget to log to
|
||||
message: Error message to log
|
||||
"""
|
||||
log_message(text_widget, f"[ERROR]: {message}", is_error=True)
|
||||
|
||||
def log_detailed_error(text_widget, error_type, error_message, context=None):
|
||||
"""
|
||||
Logs a detailed error message with context information
|
||||
|
||||
Args:
|
||||
text_widget: Tkinter Text widget to log to
|
||||
error_type: Type of error (e.g., "Datei nicht gefunden", "Regex-Fehler")
|
||||
error_message: Detailed error message
|
||||
context: Optional context information
|
||||
"""
|
||||
timestamp = datetime.now().strftime("%H:%M:%S")
|
||||
|
||||
text_widget.config(state=tk.NORMAL)
|
||||
|
||||
# Add separator
|
||||
text_widget.insert(tk.END, "=" * 60 + "\n")
|
||||
|
||||
# Add error header
|
||||
error_header = f"[{timestamp}] [ERROR] {error_type.upper()}"
|
||||
text_widget.insert(tk.END, error_header + "\n")
|
||||
|
||||
# Add error message
|
||||
text_widget.insert(tk.END, f"[ERROR] {error_message}\n")
|
||||
|
||||
# Add context if provided
|
||||
if context:
|
||||
text_widget.insert(tk.END, f"Kontext: {context}\n")
|
||||
|
||||
text_widget.insert(tk.END, "=" * 60 + "\n")
|
||||
|
||||
# Apply error styling
|
||||
start_line = float(text_widget.index(tk.END)) - 5.0 # Approximate start line
|
||||
text_widget.tag_add("error", f"{start_line} lines", tk.END)
|
||||
text_widget.tag_config("error", foreground="red")
|
||||
|
||||
text_widget.see(tk.END)
|
||||
text_widget.config(state=tk.DISABLED)
|
||||
|
||||
# Also log to console
|
||||
logger.error(f"{error_type}: {error_message}")
|
||||
if context:
|
||||
logger.error(f"Context: {context}")
|
||||
Reference in New Issue
Block a user