浏览代码

Add command line arguments

master
Sindre Stephansen 2 个月前
父节点
当前提交
588ffa2b0d
签署人:: sindre <sindre@sindrestephansen.com> GPG 密钥 ID: B06FC67D17A46ADE
共有 1 个文件被更改,包括 62 次插入27 次删除
  1. +62
    -27
      ynab.py

+ 62
- 27
ynab.py 查看文件

@@ -8,9 +8,13 @@ import os
import sys import sys
import glob import glob
import re import re
import argparse
import logging
import pandas as pd import pandas as pd
from pathlib import Path from pathlib import Path


logger = logging.getLogger(__name__)

def parse_norwegian_number(value): def parse_norwegian_number(value):
"""Convert Norwegian number format (comma decimal) to float""" """Convert Norwegian number format (comma decimal) to float"""
if pd.isna(value) or value == '': if pd.isna(value) or value == '':
@@ -30,7 +34,7 @@ def parse_norwegian_date(date_str):
# Parse DD.MM.YYYY and convert to date object # Parse DD.MM.YYYY and convert to date object
return pd.to_datetime(date_str, format='%d.%m.%Y') return pd.to_datetime(date_str, format='%d.%m.%Y')
except (ValueError, TypeError): except (ValueError, TypeError):
print(f"Invalid date format: {date_str}")
logger.error(f"Invalid date format: {date_str}")
exit(1) exit(1)


def convert_memo(original): def convert_memo(original):
@@ -184,7 +188,7 @@ def process_bank_statement(file_path, parse_function, delimiter, encoding):
elif file_extension in [".xlsx", ".xls"]: elif file_extension in [".xlsx", ".xls"]:
data = pd.read_excel(file_path) data = pd.read_excel(file_path)
else: else:
print(f"Skipping unsupported file type: {file_path}")
logger.warning(f"Skipping unsupported file type: {file_path}")
return pd.DataFrame() return pd.DataFrame()
# Call the appropriate bank-specific parsing function # Call the appropriate bank-specific parsing function
@@ -192,7 +196,7 @@ def process_bank_statement(file_path, parse_function, delimiter, encoding):
return ynab_data return ynab_data
except Exception as e: except Exception as e:
print(f"Error processing file {file_path}: {e}")
logger.error(f"Error processing file {file_path}: {e}")
raise e raise e
return pd.DataFrame() return pd.DataFrame()


@@ -217,26 +221,30 @@ def find_bank_config(filename):
return None, None return None, None




def convert_bank_statements_to_ynab(input_files=None):
def convert_bank_statements_to_ynab(input_files, output_directory):
""" """
Convert bank statements to YNAB format Convert bank statements to YNAB format
Args: Args:
input_files (list): Optional list of specific files to process
If None, processes all files in current directory
input_files (list): List of specific files to process
If empty, processes all files in current directory
""" """
current_directory = Path.cwd() current_directory = Path.cwd()
output_directory = current_directory / "YNAB_Outputs"

if not output_directory:
output_directory = current_directory / "YNAB_Outputs"
logger.debug(f"No output directory set. Defaulting to {output_directory}")
# Create output directory if it doesn't exist # Create output directory if it doesn't exist
output_directory.mkdir(exist_ok=True)
output_directory.mkdir(exist_ok=True, parents=True)
# Get list of files to process # Get list of files to process
if input_files: if input_files:
print(f"Processing {len(input_files)} dragged file(s)...")
logger.info(f"Processing {len(input_files)} dragged file(s)...")
files_to_process = [Path(f) for f in input_files if Path(f).exists()] files_to_process = [Path(f) for f in input_files if Path(f).exists()]
else: else:
print("Processing all files in current directory...")
logger.info("Processing all files in current directory...")
logger.debug(f"Current directory is {current_directory}")
files_to_process = [] files_to_process = []
# Collect all files matching any bank pattern # Collect all files matching any bank pattern
for bank_config in BANKS.values(): for bank_config in BANKS.values():
@@ -249,17 +257,17 @@ def convert_bank_statements_to_ynab(input_files=None):
# Process each file # Process each file
for file_path in files_to_process: for file_path in files_to_process:
if not file_path.exists(): if not file_path.exists():
print(f"File not found: {file_path}")
logger.warning(f"File not found: {file_path}")
continue continue
# Find matching bank configuration # Find matching bank configuration
bank_name, bank_config = find_bank_config(file_path.name) bank_name, bank_config = find_bank_config(file_path.name)
if not bank_config: if not bank_config:
print(f"No bank configuration found for file: {file_path.name}")
logger.warning(f"No bank configuration found for file: {file_path.name}")
continue continue
print(f"Processing file: {file_path} for {bank_name}")
logger.info(f"Processing file: {file_path} for {bank_name}")
parse_function = bank_config["parse_function"] parse_function = bank_config["parse_function"]
delimiter = bank_config.get("delimiter", ",") delimiter = bank_config.get("delimiter", ",")
@@ -269,7 +277,7 @@ def convert_bank_statements_to_ynab(input_files=None):
ynab_data = process_bank_statement(str(file_path), parse_function, delimiter, encoding) ynab_data = process_bank_statement(str(file_path), parse_function, delimiter, encoding)
if ynab_data.empty: if ynab_data.empty:
print(f"No data processed for {file_path}")
logger.warning(f"No data processed for {file_path}")
continue continue
filename_placeholders = { filename_placeholders = {
@@ -295,22 +303,49 @@ def convert_bank_statements_to_ynab(input_files=None):
# Export to CSV for YNAB import # Export to CSV for YNAB import
ynab_data.to_csv(output_file, index=False) ynab_data.to_csv(output_file, index=False)
print(f"Data saved to {output_file}")
logger.info(f"Data saved to {output_file}")
files_processed = True files_processed = True
if not files_processed: if not files_processed:
print("No files were processed. Make sure your files match the expected patterns.")
logger.warning("No files were processed. Make sure your files match the expected patterns.")




if __name__ == "__main__": if __name__ == "__main__":
# Check if files were dragged onto the script
if len(sys.argv) > 1:
# Files were dragged - process them
files = sys.argv[1:]
convert_bank_statements_to_ynab(files)
else:
# No files dragged - run normal directory processing
convert_bank_statements_to_ynab()
# Keep window open on Mac so user can see results
input("\nPress Enter to close...")
parser = argparse.ArgumentParser(
prog='YNAB',
description='Prepare bank transcripts for import to You Need A Budget',
)

parser.add_argument(
'filenames',
type=Path,
nargs='*',
help='The files to process',
)

parser.add_argument(
'-o', '--output-dir',
type=Path,
default=None,
help='The location to store the converted files',
)

parser.add_argument(
'-v', '--verbose',
default=0,
action='count',
help='Increase logging verbosity',
)

args = parser.parse_args()

if args.verbose <= 0:
log_level = logging.WARNING
elif args.verbose == 1:
log_level = logging.INFO
elif args.verbose >= 2:
log_level = logging.DEBUG

logging.basicConfig(level=log_level)

convert_bank_statements_to_ynab(args.filenames, args.output_dir)

正在加载...
取消
保存