Skip to content

Commit 1d9b94e

Browse files
author
Your Name
committed
Use poetry for dependency management
- Introduce Google fire - Code cleanup with ruff rules - stop using `globals()`
1 parent a2e3ddf commit 1d9b94e

34 files changed

+3031
-827
lines changed

beanborg/arg_parser.py

Lines changed: 0 additions & 28 deletions
This file was deleted.

beanborg/bb_archive.py

Lines changed: 92 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,110 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
33

4-
__copyright__ = "Copyright (C) 2023 Luciano Fiandesio"
4+
__copyright__ = "Copyright (C) 2024 Luciano Fiandesio"
55
__license__ = "GNU GPLv2"
66

77
import csv
88
import os
99
import shutil
1010
import sys
1111
from datetime import datetime
12+
from typing import Optional
1213

14+
import fire
15+
from fire.decorators import SetParseFns
1316
from rich import print as rprint
1417

15-
from beanborg.arg_parser import eval_args
1618
from beanborg.config import init_config
1719

1820

19-
def main():
20-
21-
args = eval_args("Archives imported CVS file")
22-
config = init_config(args.file, args.debug)
23-
24-
target_csv = os.path.join(config.csv.target, config.csv.ref + ".csv")
25-
26-
if not os.path.isfile(target_csv):
27-
rprint(f"[red]file: {target_csv} does not exist![red]")
28-
sys.exit(-1)
29-
30-
if not os.path.isdir(config.csv.archive):
31-
os.mkdir(config.csv.archive)
21+
class BeanborgArchiver:
22+
"""Archive imported CSV files with date range in filename.
23+
24+
Synopsis:
25+
bb_archive --config_file=CONFIG_FILE [--debug=true]
26+
27+
Description:
28+
Archives processed CSV files by moving them to an archive directory.
29+
The archived filename includes the date range of transactions contained
30+
in the file.
31+
32+
Arguments:
33+
config_file: Path to the YAML configuration file
34+
debug: Enable debug output (default: False)
35+
36+
Examples:
37+
bb_archive --config_file=config.yaml
38+
bb_archive --config_file=/path/to/config.yaml --debug=true
39+
"""
40+
41+
@SetParseFns(f=str, config_file=str, debug=bool)
42+
def __call__(
43+
self,
44+
f: Optional[str] = None,
45+
config_file: Optional[str] = None,
46+
debug: bool = False,
47+
):
48+
"""Archive the processed CSV file.
49+
50+
Args:
51+
f: Path to the configuration file (shorthand for --config-file)
52+
config_file: Path to the configuration file
53+
debug: Enable debug mode
54+
55+
Returns:
56+
int: 0 for success, 1 for failure
57+
"""
58+
final_config_file = f or config_file
59+
if not final_config_file:
60+
raise ValueError(
61+
"Configuration file must be specified using either -f or --config-file"
62+
)
63+
config = init_config(final_config_file, debug)
64+
65+
target_csv = os.path.join(config.csv.target, config.csv.ref + ".csv")
66+
67+
if not os.path.isfile(target_csv):
68+
rprint(f"[red]file: {target_csv} does not exist![red]")
69+
sys.exit(-1)
70+
71+
if not os.path.isdir(config.csv.archive):
72+
os.mkdir(config.csv.archive)
73+
74+
dates = []
75+
print("\u2713" + " detecting start and end date of transaction file...")
76+
with open(target_csv) as csv_file:
77+
csv_reader = csv.reader(csv_file, delimiter=config.csv.separator)
78+
for _ in range(config.csv.skip):
79+
next(csv_reader) # skip the line
80+
81+
for row in csv_reader:
82+
try:
83+
dates.append(
84+
datetime.strptime(
85+
row[config.indexes.date].strip(), config.csv.date_format
86+
)
87+
)
88+
except Exception as ex:
89+
print("error: " + str(ex))
90+
91+
print("\u2713" + " moving file to archive...")
92+
os.rename(
93+
target_csv,
94+
config.csv.archive
95+
+ "/"
96+
+ config.csv.ref
97+
+ "_"
98+
+ str(min(dates).date())
99+
+ "_"
100+
+ str(max(dates).date())
101+
+ ".csv",
102+
)
103+
104+
print("\u2713" + " removing temp folder")
105+
shutil.rmtree(config.csv.target)
32106

33-
dates = []
34-
print("\u2713" + " detecting start and end date of transaction file...")
35-
with open(target_csv) as csv_file:
36-
csv_reader = csv.reader(csv_file, delimiter=config.csv.separator)
37-
for _ in range(config.csv.skip):
38-
next(csv_reader) # skip the line
39107

40-
for row in csv_reader:
41-
try:
42-
dates.append(
43-
datetime.strptime(
44-
row[config.indexes.date].strip(), config.csv.date_format
45-
)
46-
)
47-
except Exception as ex:
48-
print("error: " + str(ex))
49-
50-
print("\u2713" + " moving file to archive...")
51-
os.rename(
52-
target_csv,
53-
config.csv.archive
54-
+ "/"
55-
+ config.csv.ref
56-
+ "_"
57-
+ str(min(dates).date())
58-
+ "_"
59-
+ str(max(dates).date())
60-
+ ".csv",
61-
)
62-
63-
print("\u2713" + " removing temp folder")
64-
shutil.rmtree(config.csv.target)
65-
66-
67-
if __name__ == "__main__":
68-
main()
108+
def main():
109+
"""Main function to run the beanborg archiver."""
110+
fire.Fire(BeanborgArchiver)

beanborg/bb_import.py

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,60 @@
44
__copyright__ = "Copyright (C) 2024 Luciano Fiandesio"
55
__license__ = "GNU GPLv2"
66

7+
from typing import Optional
8+
9+
import fire
10+
from fire.decorators import SetParseFns
711

812
from beanborg.importer import Importer
913

1014

11-
def main():
12-
imp = Importer()
13-
imp.import_transactions()
15+
class BeanborgImporter:
16+
"""Parse bank CSV file and import into beancount.
17+
18+
Synopsis:
19+
bb_import --config_file=CONFIG_FILE [--debug=true] [--fix_only=true]
20+
21+
Description:
22+
Imports bank transactions from CSV files into beancount format.
23+
Can also fix uncategorized transactions using the --fix-only flag.
24+
25+
Arguments:
26+
config_file: Path to the YAML configuration file
27+
debug: Enable debug output (default: False)
28+
fix_only: Only fix transactions without an account (default: False)
1429
30+
Examples:
31+
bb_import --config_file=config.yaml
32+
bb_import --config_file=config.yaml --debug=true
33+
bb_import --config_file=config.yaml --fix_only=true
34+
"""
1535

16-
if __name__ == "__main__":
17-
main()
36+
@SetParseFns(f=str, config_file=str, debug=bool, fix_only=bool)
37+
def __call__(
38+
self,
39+
f: Optional[str] = None,
40+
config_file: Optional[str] = None,
41+
debug: bool = False,
42+
fix_only: bool = False,
43+
):
44+
"""Import transactions from CSV to beancount.
45+
46+
Args:
47+
f: Path to the configuration file (shorthand for --config-file)
48+
config_file: Path to the configuration file
49+
debug: Enable debug mode
50+
fix_only: Only fix uncategorized transactions
51+
"""
52+
final_config_file = f or config_file
53+
if not final_config_file:
54+
raise ValueError(
55+
"Configuration file must be specified using either -f or --config-file"
56+
)
57+
imp = Importer()
58+
return imp.import_transactions(final_config_file, debug, fix_only)
59+
60+
61+
def main():
62+
"""Main function to run the beanborg importer."""
63+
fire.Fire(BeanborgImporter)

0 commit comments

Comments
 (0)