# PST 邮件处理流程总结

> 创建时间: 2026-04-13
> 处理对象: Shen Wei 2025.pst (15GB, 55,647封)

---

## 📋 全流程概述

### 阶段一：PST 提取（PST → mbox）

```
原始文件: Shen Wei 2025.pst (15GB)
    ↓
工具: readpst (macOS 已安装)
    ↓
输出: extracted_2025/Shen Wei 2025/*/mbox (30个文件夹)
时间: ~10-15 分钟
```

**关键点：**
- `readpst -S <pst_file> -o <output_dir>` 将 PST 按文件夹结构展开为 mbox 格式
- 每个 mbox 以 `From ` 行分隔邮件
- 原始 PST 完全未动

---

### 阶段二：建立索引（mbox → CSV）

```
原始 mbox (30个文件夹, 55,647封)
    ↓
Python: mailbox 模块 + parsedate_to_datetime
    ↓
输出: ~/pst-processing/2025/YYYY-MM.csv (83个月)
```

**CSV 字段：**

| 字段 | 说明 |
|------|------|
| folder | 文件夹路径（如 Inbox/SaaS Notification/AWS） |
| year_month | 年月（如 2025-01） |
| message_id | 邮件唯一标识（用于跨文件匹配） |
| subject | 主题（截断至80字符保唯一性） |
| sender | 发件人（完整显示名+邮箱） |
| recipient | 收件人 |
| date | 日期（RFC 2822 原始格式） |
| has_attachment | Y/N（检测 Content-Disposition: attachment） |
| attachment_size | 附件总字节数 |
| email_size | 整封邮件字节数 |

**处理速度：** ~4分钟（55,647封）

---

### 阶段三：定义删除规则

**规则文件：** `~/pst-processing/rules/delete_rules.json`

| # | 规则ID | 文件夹匹配 | 动作 | 说明 |
|---|--------|----------|------|------|
| 1 | aws_notification | 含 "AWS Notification" | keep_sample: 5 | 每 subject 保留1封，最多5封 |
| 2 | prisma_cloud | 含 "Prisma Cloud" | keep_sample: 5 | 每 subject 保留1封，最多5封 |
| 3 | x4x_tenant_provisioning | 含 "X4X-Tenant Provisioning" | keep_sample: 5 | 每 subject 保留1封，最多5封 |
| 4 | qualys | 含 "Qualys" | keep_sample: 5 | 每 subject 保留1封，最多5封 |
| 5 | teams_notification | 含 "Teams Notification" | keep_if_attachment | 有附件保留，无附件删 |
| 6 | sma_notification | 含 "SMA Notficiation" | keep_sample: 10 | 每 subject 保留1封，每月最多10封 |
| 7 | ppm_saas_change | 含 "PPM SaaS Change" | delete_all | 全部删除 |
| 8 | cloudhealth | 含 "CloudHealth" | keep | 全部保留 |
| 9 | saas_bi_report | 含 "SaaS BI Report" | keep | 全部保留 |
| 10 | x4x_decommissioning | 含 "X4X-Tenant Decommissioning" | delete_all | 全部删除 |
| 11 | x4x_license_renewal | 含 "X4X-License Renewal" | delete_all | 全部删除 |

**规则动作类型：**
- `keep`：全部保留
- `delete_all`：全部删除
- `keep_sample`：每 subject 保留1封，最多N封
- `keep_if_attachment`：有附件保留，无附件删除

**执行脚本：** `~/pst-processing/rules/apply_rules.py`

---

### 阶段四：过滤并组装新 mbox

```
原始 mbox (30个文件夹, 55,647封)
    ↓
按 message_id 匹配 delete_flag
    ↓
保留邮件: 29,088 封 (52%)
    ↓
提取 full content（含正文+附件）
    ↓
输出: shenwei2025-clean.mbox (9.6GB)
```

**关键发现：**
- 有117封邮件在原始 mbox 中匹配失败（PST→mbox 转换时的 ID 差异）
- SMA Notification 原始 6,681 封 → 规则处理后仅保留 40 封

---

## 💡 经验总结

### 1. 工具链

| 场景 | 工具 | 备注 |
|------|------|------|
| PST 读取 | `readpst` | macOS 已安装 (`/opt/homebrew/bin/readpst`) |
| PST Python 库 | ❌ pypff (PEP 668阻止安装) | 无需替代，readpst + mbox 够用 |
| mbox 处理 | Python `mailbox` | 原生支持，够用 |
| 日期解析 | `email.utils.parsedate_to_datetime` | 兼容 RFC 2822 |

### 2. CSV 索引优先于直接处理 mbox

- mbox 随机访问极慢（全量扫描）
- 先建索引，按 `message_id` 匹配，效率高
- CSV 可用 Excel/Numbers 查看，方便人工审阅

### 3. 删除规则设计原则

- **按文件夹**：系统通知类（AWS/Qualys/Prisma）→ 批量删除或采样
- **按附件有无**：Teams 通知 → 有附件才留
- **按 subject 采样**：保留不同类型的代表性样本，避免漏掉格式
- **按月配额**：高频通知类 → 每月最多留N封

### 4. 避免的坑

- `mailbox.mbox` 不支持 slice 索引 → 用 `iter()` 遍历
- Subject 可能含非 ASCII → `:80` 截断保唯一性
- 附件大小：字符串 payload 用 `len(payload.encode())`，二进制 payload 直接 `len(payload)`
- 日期解析失败 → 归入 "Unknown" 月份

---

## 📊 Shen Wei 2025 处理结果

| 指标 | 处理前 | 处理后 |
|------|--------|--------|
| 总邮件 | 55,647 | 29,088 |
| 删除 | — | 26,559 |
| 附件邮件 | — | 20,171 (69%) |
| 总附件大小 | — | 8.6 GB |

---

## 🔄 批量处理 SOP（待执行）

### 输入
- 新 PST 文件 → 复制到 `~/pst-processing/incoming/`
- 规则文件已就绪：`~/pst-processing/rules/delete_rules.json`

### 执行步骤

```bash
# 1. 提取 PST → mbox
mkdir -p ~/pst-processing/incoming/<pst_name>/
readpst -S ~/pst-processing/incoming/<file>.pst -o ~/pst-processing/incoming/<pst_name>/

# 2. 建立索引 CSV
python3 ~/pst-processing/rules/index_pst.py <source_dir> <output_csv_dir>

# 3. 应用删除规则（复用现有规则）
python3 ~/pst-processing/rules/apply_rules.py <csv_dir>

# 4. 组装新 mbox（按 message_id 匹配原始 mbox）
python3 ~/pst-processing/rules/build_clean_mbox.py <source_mbox_dir> <output_mbox>
```

### 待开发脚本

- [ ] `index_pst.py` — 通用 PST 索引脚本
- [ ] `batch_process.sh` — 批量处理 wrapper
- [ ] `rules/delete_rules.json` — 已有，可直接复用

---

## 📁 当前文件结构

```
~/pst-processing/
├── rules/
│   ├── delete_rules.json      # 规则定义
│   └── apply_rules.py         # 规则执行脚本
├── 2025/                      # 原始索引 CSV（83个月）
│   └── YYYY-MM.csv
├── shenwei2025-clean.mbox    # 清理后完整邮件 (9.6GB, 29,088封)
├── shenwei2025-clean-index.csv # 新索引 (12.3MB)
├── shenwei2025-new.mbox       # 旧版（仅 headers，已保留）
└── extracted_2025/           # 原始 mbox 提取物
    └── Shen Wei 2025/
        └── */mbox
```

---

## 📅 后续任务

- [ ] 开发通用 `index_pst.py` 脚本
- [ ] 开发 `build_clean_mbox.py` 脚本
- [ ] 批处理其他 PST 文件
- [ ] 同步笔记到 Git
