112 lines
3.5 KiB
Python
112 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
账单清理统一入口
|
|
自动识别微信或支付宝账单,调用对应的清理逻辑
|
|
|
|
用法: python clean_bill.py <输入文件> [输出文件] [日期筛选选项]
|
|
示例:
|
|
python clean_bill.py 账单.csv --year 2026
|
|
python clean_bill.py 账单.csv --year 2026 --month 1
|
|
python clean_bill.py 账单.csv --start 2026-01-01 --end 2026-01-15
|
|
"""
|
|
import sys
|
|
import io
|
|
from pathlib import Path
|
|
|
|
# 解决 Windows 控制台编码问题
|
|
if sys.stdout.encoding != 'utf-8':
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
|
|
if sys.stderr.encoding != 'utf-8':
|
|
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
|
|
|
|
from cleaners.base import create_arg_parser, compute_date_range
|
|
from cleaners import AlipayCleaner, WechatCleaner
|
|
|
|
|
|
def detect_bill_type(filepath: str) -> str | None:
|
|
"""
|
|
检测账单类型
|
|
|
|
Returns:
|
|
'alipay' | 'wechat' | None
|
|
"""
|
|
try:
|
|
with open(filepath, "r", encoding="utf-8") as f:
|
|
for _ in range(20):
|
|
line = f.readline()
|
|
if not line:
|
|
break
|
|
|
|
# 支付宝特征:表头包含"交易分类"和"对方账号"
|
|
if "交易分类" in line and "对方账号" in line:
|
|
return "alipay"
|
|
|
|
# 微信特征:表头包含"交易类型"和"金额(元)"
|
|
if "交易类型" in line and "金额(元)" in line:
|
|
return "wechat"
|
|
|
|
# 数据行特征
|
|
if line.startswith("202"):
|
|
if "¥" in line:
|
|
return "wechat"
|
|
if "@" in line:
|
|
return "alipay"
|
|
|
|
except Exception as e:
|
|
print(f"读取文件失败: {e}", file=sys.stderr)
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
def main():
|
|
parser = create_arg_parser("账单清理统一入口 - 自动识别微信/支付宝账单")
|
|
parser.add_argument(
|
|
"--type", "-t",
|
|
choices=["alipay", "wechat", "auto"],
|
|
default="auto",
|
|
help="手动指定账单类型(默认自动检测)"
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
input_file = args.input_file
|
|
|
|
# 检查文件是否存在
|
|
if not Path(input_file).exists():
|
|
print(f"❌ 错误:文件不存在 - {input_file}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# 检测账单类型
|
|
if args.type == "auto":
|
|
bill_type = detect_bill_type(input_file)
|
|
if bill_type is None:
|
|
print("❌ 无法识别账单类型,请使用 --type 参数手动指定", file=sys.stderr)
|
|
print(" 支持: --type alipay (支付宝) 或 --type wechat (微信)", file=sys.stderr)
|
|
sys.exit(1)
|
|
else:
|
|
bill_type = args.type
|
|
|
|
# 显示检测结果
|
|
type_names = {"alipay": "支付宝", "wechat": "微信"}
|
|
print(f"📋 检测到账单类型: {type_names[bill_type]}")
|
|
print()
|
|
|
|
# 计算日期范围
|
|
start_date, end_date = compute_date_range(args)
|
|
|
|
# 获取输出格式
|
|
output_format = getattr(args, 'format', 'csv')
|
|
|
|
# 创建对应的清理器
|
|
if bill_type == "alipay":
|
|
cleaner = AlipayCleaner(args.input_file, args.output_file, output_format)
|
|
else:
|
|
cleaner = WechatCleaner(args.input_file, args.output_file, output_format)
|
|
|
|
cleaner.set_date_range(start_date, end_date)
|
|
cleaner.clean()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|