#!/usr/bin/env python3 """ PST 邮件清理规则执行脚本 v1.2 用法: python3 apply_rules.py """ import csv import json import sys from collections import defaultdict RULES_FILE = '/Users/weishen/pst-processing/rules/delete_rules.json' def load_rules(): with open(RULES_FILE) as f: return json.load(f)['rules'] def apply_rules(csv_path): rules = load_rules() rows = list(csv.DictReader(open(csv_path, encoding='utf-8'))) for r in rows: r['delete_flag'] = 'N' total_deleted = 0 for rule in rules: folder_pattern = rule['folder_contains'] action = rule['action'] folder_rows = [r for r in rows if folder_pattern in r['folder']] if not folder_rows: continue deleted_count = 0 kept_count = 0 if action == 'keep': kept_count = len(folder_rows) elif action == 'delete_all': for r in folder_rows: r['delete_flag'] = 'Y' deleted_count += 1 elif action == 'keep_sample': keep_limit = rule['keep_count'] subject_map = defaultdict(list) for r in folder_rows: subj = r['subject'].strip()[:80] subject_map[subj].append(r) sorted_subjects = sorted(subject_map.items(), key=lambda x: -len(x[1])) for subj, emails in sorted_subjects: if kept_count >= keep_limit: for r in emails: r['delete_flag'] = 'Y' deleted_count += 1 else: for i, r in enumerate(emails): if i == 0: kept_count += 1 else: r['delete_flag'] = 'Y' deleted_count += 1 elif action == 'keep_if_attachment': for r in folder_rows: if r['has_attachment'] == 'Y': kept_count += 1 else: r['delete_flag'] = 'Y' deleted_count += 1 print(f" {folder_pattern}: {len(folder_rows)} | 保留{kept_count} | 删除{deleted_count}") total_deleted += deleted_count total_kept = len(rows) - total_deleted print(f"📊 总计: 保留{total_kept} | 删除{total_deleted}") fieldnames = list(rows[0].keys()) out_marked = csv_path.replace('.csv', '_marked.csv') out_delete = csv_path.replace('.csv', '_delete_list.csv') with open(out_marked, 'w', newline='', encoding='utf-8') as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() writer.writerows(rows) with open(out_delete, 'w', newline='', encoding='utf-8') as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() writer.writerows([r for r in rows if r['delete_flag'] == 'Y']) print(f"✅ 输出: {out_marked}") print(f"✅ 删除清单: {out_delete} ({total_deleted} 封)") if __name__ == '__main__': if len(sys.argv) < 2: print("用法: python3 apply_rules.py ") sys.exit(1) apply_rules(sys.argv[1])