ソースを参照

Add option to archive or delete processed files

master
Sindre Stephansen 2ヶ月前
コミット
ff91a84a0a
署名者: sindre <sindre@sindrestephansen.com> GPGキーID: B06FC67D17A46ADE
2個のファイルの変更71行の追加20行の削除
  1. +37
    -18
      src/convert.py
  2. +34
    -2
      src/main.py

+ 37
- 18
src/convert.py ファイルの表示

@@ -13,19 +13,19 @@ BANKS = {
"SparebankenNorge": {
"patterns": ["Transaksjoner*.csv"],
"encoding": "latin1",
"output_filename": "YNAB-{bank}-FROM-{first_date}-TO-{last_date}",
"output_filename": "YNAB-{bank}-FROM-{first_date}-TO-{last_date}.csv",
"parse_function": parse_sparebanken_norge,
"delimiter": ";"
},
"Sparebank1": {
"patterns": ["OversiktKonti*.csv"],
"output_filename": "YNAB-{bank}-FROM-{first_date}-TO-{last_date}",
"output_filename": "YNAB-{bank}-FROM-{first_date}-TO-{last_date}.csv",
"parse_function": parse_sparebank1,
"delimiter": ";"
},
"Norwegian": {
"patterns": ["BankNorwegian*.xlsx", "Statement*.xlsx"],
"output_filename": "YNAB-{bank}-FROM-{first_date}-TO-{last_date}",
"output_filename": "YNAB-{bank}-FROM-{first_date}-TO-{last_date}.csv",
"parse_function": parse_bank_norwegian
}
# Add more banks and patterns as needed
@@ -87,7 +87,24 @@ def process_bank_statement(file_path, parse_function, delimiter, encoding):
return pd.DataFrame()


def convert_bank_statements_to_ynab(input_paths, output_directory):
def get_unique_filename(original_path):
file_retry_count = 0

while True:
result = Path(original_path)

if file_retry_count > 0:
result = result.with_stem(result.stem + f"({file_retry_count})")
if result.exists():
logging.debug(f"File {result} exists. Looking for available alternative")
file_retry_count += 1
continue
else:
return result


def convert_bank_statements_to_ynab(input_paths, output_directory, archive_directory, on_success, overwrite):
"""
Convert bank statements to YNAB format
@@ -147,25 +164,27 @@ def convert_bank_statements_to_ynab(input_paths, output_directory):
'last_date': ynab_data['Date'].max().date(),
}

file_retry_count = 0
while True:
output_filename = bank_config["output_filename"].format(**filename_placeholders)

if file_retry_count > 0:
output_filename += f" ({file_retry_count})"
output_filename += ".csv"
output_file = output_directory / output_filename

if not output_file.exists():
break

file_retry_count += 1
output_file = output_directory / Path(bank_config["output_filename"].format(**filename_placeholders))
if not overwrite:
output_file = get_unique_filename(output_file)
# Export to CSV for YNAB import
ynab_data.to_csv(output_file, index=False)
logging.info(f"Data saved to {output_file}")
files_processed = True

if on_success == 'delete':
logging.info(f"Deleting {file_path}")
file_path.unlink()
elif on_success == 'archive':
archive_directory.mkdir(exist_ok=True, parents=True)
file_archive_path = archive_directory / file_path.name
if not overwrite:
file_archive_path = get_unique_filename(file_archive_path)
logging.debug(f"Archiving {file_path} to {file_archive_path}")
file_path.rename(file_archive_path)
elif on_success and on_success != 'nothing':
logger.warning(f"Invalid operation after conversion: {on_success}")
if not files_processed:
logging.warning("No files were processed. Make sure your files match the expected patterns.")

+ 34
- 2
src/main.py ファイルの表示

@@ -48,6 +48,27 @@ if __name__ == "__main__":
help='The location to store the converted files',
)

parser.add_argument(
'-a', '--archive-dir',
type=Path,
default=None,
help='The location to store the original files after conversion, if --on-success is "archive"',
)

parser.add_argument(
'-s', '--on-success',
default=None,
choices=['delete', 'archive', 'nothing'],
help='What to do with the original file after the conversion.',
)

parser.add_argument(
'-f', '--force',
action='store_true',
default=None,
help='Overwrite existing files',
)

parser.add_argument(
'-v', '--verbose',
default=0,
@@ -85,9 +106,20 @@ if __name__ == "__main__":
logging.info("Processing all files in current directory")
inputs = [current_directory]

output_dir = args.output_dir or Path(config.get('output_dir'))
output_dir = args.output_dir or config.get('output_dir')
if not output_dir:
output_dir = current_directory / "YNAB_Outputs"
logging.debug(f"No output directory set. Defaulting to {output_dir}")
output_dir = Path(output_dir).expanduser()

archive_dir = args.archive_dir or config.get('archive_dir')
if not archive_dir:
archive_dir = current_directory / "YNAB_Archive"
logging.debug(f"No archive directory set. Defaulting to {archive_dir}")
archive_dir = Path(archive_dir).expanduser()

on_success = args.on_success or config.get('on_success') or 'nothing'

force = args.force or config.get('force') or False

convert_bank_statements_to_ynab(inputs, output_dir)
convert_bank_statements_to_ynab(inputs, output_dir, archive_dir, on_success, force)

読み込み中…
キャンセル
保存