97 lines
3.5 KiB
Python
97 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""全量拉取所有 IMAP 可见文件夹 · 支持进度写入"""
|
|
import json
|
|
import sys
|
|
import imaplib
|
|
import os
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from qq_mail_fetch import fetch_emails, list_folders, AUTH_CODE
|
|
|
|
OUT = Path("/Users/karuo/Documents/卡若Ai的文件夹/报告")
|
|
OUT.mkdir(parents=True, exist_ok=True)
|
|
PROGRESS_FILE = OUT / "qq_fetch_progress.json"
|
|
|
|
def count_folder(server, folder):
|
|
mb = f'"{folder}"' if " " in folder else folder
|
|
try:
|
|
typ, data = server.select(mb, readonly=True)
|
|
if typ == "OK" and data:
|
|
n = int(data[0].decode())
|
|
server.close()
|
|
return n
|
|
except Exception:
|
|
pass
|
|
return 0
|
|
|
|
def get_folder_counts(folders):
|
|
"""预扫各文件夹邮件数"""
|
|
from qq_mail_fetch import IMAP_HOST, IMAP_PORT, EMAIL
|
|
server = imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT)
|
|
server.login(EMAIL, AUTH_CODE)
|
|
counts = {f: count_folder(server, f) for f in folders}
|
|
server.logout()
|
|
return counts
|
|
|
|
def write_progress(progress):
|
|
progress["updated_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
with open(PROGRESS_FILE, "w", encoding="utf-8") as fp:
|
|
json.dump(progress, fp, ensure_ascii=False, indent=2)
|
|
|
|
def main():
|
|
if not AUTH_CODE:
|
|
print("无授权码")
|
|
return 1
|
|
folders = list_folders()
|
|
counts = get_folder_counts(folders)
|
|
total_emails = sum(counts.values())
|
|
start_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
all_emails = []
|
|
stats = {}
|
|
done_emails = 0
|
|
for i, f in enumerate(folders):
|
|
try:
|
|
emails = fetch_emails(days=365*20, limit=0, all_mail=True, progress=False, folder=f)
|
|
stats[f] = len(emails)
|
|
for e in emails:
|
|
e["_folder"] = f
|
|
all_emails.extend(emails)
|
|
done_emails += len(emails)
|
|
elapsed = (datetime.now() - datetime.strptime(start_at, "%Y-%m-%d %H:%M:%S")).total_seconds()
|
|
eta_sec = (elapsed / done_emails * (total_emails - done_emails)) if done_emails else 0
|
|
progress = {
|
|
"total_folders": len(folders),
|
|
"done_folders": i + 1,
|
|
"total_emails": total_emails,
|
|
"done_emails": done_emails,
|
|
"pct": round(done_emails / total_emails * 100, 1) if total_emails else 0,
|
|
"current_folder": f,
|
|
"start_at": start_at,
|
|
"eta_minutes": round(eta_sec / 60, 1),
|
|
}
|
|
write_progress(progress)
|
|
print(f" [{i+1}/{len(folders)}] {f}: {len(emails)} | 总进度 {done_emails}/{total_emails} ({progress['pct']}%) ETA {progress['eta_minutes']}min")
|
|
except Exception as ex:
|
|
print(f" {f}: 失败 {ex}")
|
|
stats[f] = 0
|
|
with open(OUT / "qq_all_folders_export.json", "w", encoding="utf-8") as fp:
|
|
json.dump(all_emails, fp, ensure_ascii=False, indent=None)
|
|
with open(OUT / "qq_folders_stats.json", "w", encoding="utf-8") as fp:
|
|
json.dump(stats, fp, ensure_ascii=False, indent=2)
|
|
write_progress({
|
|
"total_folders": len(folders),
|
|
"done_folders": len(folders),
|
|
"total_emails": total_emails,
|
|
"done_emails": len(all_emails),
|
|
"pct": 100,
|
|
"status": "completed",
|
|
"start_at": start_at,
|
|
"finished_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
"eta_minutes": 0,
|
|
})
|
|
print(f"\n合计: {len(all_emails)} 封")
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|