Files
FCCS/fccs_config.py

106 lines
3.2 KiB
Python

"""
Shared configuration, logging, and utilities for the FCCS extraction tool.
"""
import os
import re
import sys
import argparse
import configparser
from datetime import datetime
DEFAULT_CONFIG = "config.ini"
def parse_args():
"""Parse the optional --config argument common to all scripts."""
parser = argparse.ArgumentParser()
parser.add_argument(
"--config",
default=None,
help=f"Path to config file (default: {DEFAULT_CONFIG} in script directory)",
)
return parser.parse_args()
def load_config(path=None):
"""Read config.ini and return a ConfigParser object."""
if path is None:
script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
path = os.path.join(script_dir, DEFAULT_CONFIG)
if not os.path.exists(path):
print(f"ERROR: config file not found: {path}")
sys.exit(1)
cfg = configparser.ConfigParser()
cfg.read(path, encoding="utf-8")
return cfg
def make_logger(log_file):
"""Return a log() function that writes timestamped lines to console and file."""
def log(msg):
line = f"[{datetime.now():%Y-%m-%d %H:%M:%S}] {msg}"
print(line)
try:
with open(log_file, "a", encoding="utf-8") as f:
f.write(line + "\n")
except Exception:
pass
return log
def load_folder_list(path):
"""Load known FCCS folder names from file, one per line."""
if not os.path.exists(path):
print(f"ERROR: folder list file not found: {path}")
sys.exit(1)
folders = []
with open(path, "r", encoding="utf-8") as f:
for line in f:
s = line.strip()
if s and not s.startswith("#"):
folders.append(s)
return folders
def build_folder_patterns(templates):
"""
Convert folder template strings into regex patterns for matching.
Templates use YYYY as a year placeholder (e.g. 'YYYY Tax Documents').
Non-recurring folders (no YYYY) are matched literally.
A built-in pattern for 'UltraTax CS MM-DD-YYYY' is always included.
Returns a list of (compiled_regex, template_name) tuples, sorted
longest-first to prevent partial matches.
"""
patterns = []
# Built-in: UltraTax CS folders (auto-generated by UltraTax integration)
patterns.append((
re.compile(r"UltraTax CS \d{2}-\d{2}-\d{4}$"),
"UltraTax CS",
))
for tmpl in templates:
if "YYYY" in tmpl:
# Replace YYYY with 4-digit year pattern, escape the rest
parts = tmpl.split("YYYY")
regex_str = re.escape(parts[0]) + r"\d{4}" + re.escape(parts[1])
else:
# Non-recurring folder — exact match
regex_str = re.escape(tmpl)
patterns.append((re.compile(regex_str + "$"), tmpl))
# Sort by regex pattern length (longest first) to avoid partial matches
patterns.sort(key=lambda p: len(p[0].pattern), reverse=True)
return patterns
def load_lines(path):
"""Read non-blank, non-comment lines from a file."""
if not os.path.exists(path):
return []
with open(path, "r", encoding="utf-8") as f:
return [line.strip() for line in f if line.strip() and not line.strip().startswith("#")]