#!/usr/bin/env python3 """ Email Queue Processor - Handle user commands for pending emails Reads pending_emails.json and executes user commands (archive/keep/reply) """ import json import imaplib import os import sys from datetime import datetime from pathlib import Path SCRIPT_DIR = Path(__file__).parent DATA_FILE = SCRIPT_DIR / "data" / "pending_emails.json" def load_pending(): """Load pending emails from JSON file""" if not DATA_FILE.exists(): return {} with open(DATA_FILE, 'r', encoding='utf-8') as f: return json.load(f) def save_pending(pending): """Save pending emails to JSON file""" DATA_FILE.parent.mkdir(exist_ok=True) with open(DATA_FILE, 'w', encoding='utf-8') as f: json.dump(pending, f, indent=2, ensure_ascii=False) def connect_imap(config): """Connect to IMAP server""" mail = imaplib.IMAP4_SSL(config['imap']['host'], config['imap']['port']) mail.login(config['imap']['email'], config['imap']['password']) return mail def show_pending_list(): """Display all pending emails""" pending = load_pending() if not pending: print("📭 没有待处理的邮件") return print(f"\n📧 待处理邮件列表 ({len(pending)} 封)") print("=" * 60) # Sort by email_date sorted_items = sorted( pending.items(), key=lambda x: x[1].get('email_date', '') ) for msg_id, data in sorted_items: if data.get('status') == 'pending': print(f"\n🆔 {msg_id}") print(f" 主题: {data.get('subject', 'N/A')[:50]}") print(f" 发件人: {data.get('sender', 'N/A')}") print(f" 收件人: {data.get('recipient', 'N/A')}") print(f" 时间: {data.get('email_date', 'N/A')}") print(f" 摘要: {data.get('summary', 'N/A')[:80]}") print("\n" + "=" * 60) print("\n可用指令:") print(" • 归档 [ID] - 移动到 Archive 文件夹") print(" • 保留 [ID] - 标记已读,留在收件箱") print(" • 删除 [ID] - 移动到 Trash") print(" • 全部处理 - 列出所有并批量操作") def archive_email(config, msg_id): """Archive a specific email by ID""" pending = load_pending() if msg_id not in pending: print(f"❌ 未找到邮件 ID: {msg_id}") return False email_data = pending[msg_id] uid = email_data.get('imap_uid') if not uid: print(f"❌ 邮件 {msg_id} 没有 UID") return False try: mail = connect_imap(config) mail.select('INBOX') # Copy to Archive result = mail.copy(uid, 'Archive') if result[0] == 'OK': # Mark original as deleted mail.store(uid, '+FLAGS', '\\Deleted') mail.expunge() # Update status pending[msg_id]['status'] = 'done' pending[msg_id]['action'] = 'archived' pending[msg_id]['processed_at'] = datetime.now().isoformat() save_pending(pending) print(f"✅ 已归档: {email_data.get('subject', 'N/A')[:40]}") return True else: print(f"❌ 归档失败: {result}") return False except Exception as e: print(f"❌ 错误: {e}") return False finally: try: mail.logout() except: pass def keep_email(config, msg_id): """Keep email in inbox, mark as read""" pending = load_pending() if msg_id not in pending: print(f"❌ 未找到邮件 ID: {msg_id}") return False email_data = pending[msg_id] uid = email_data.get('imap_uid') if not uid: print(f"❌ 邮件 {msg_id} 没有 UID") return False try: mail = connect_imap(config) mail.select('INBOX') # Mark as read (Seen) mail.store(uid, '+FLAGS', '\\Seen') # Update status pending[msg_id]['status'] = 'done' pending[msg_id]['action'] = 'kept' pending[msg_id]['processed_at'] = datetime.now().isoformat() save_pending(pending) print(f"✅ 已保留: {email_data.get('subject', 'N/A')[:40]}") return True except Exception as e: print(f"❌ 错误: {e}") return False finally: try: mail.logout() except: pass def delete_email(config, msg_id): """Move email to Trash""" pending = load_pending() if msg_id not in pending: print(f"❌ 未找到邮件 ID: {msg_id}") return False email_data = pending[msg_id] uid = email_data.get('imap_uid') if not uid: print(f"❌ 邮件 {msg_id} 没有 UID") return False try: mail = connect_imap(config) mail.select('INBOX') # Copy to Trash result = mail.copy(uid, 'Trash') if result[0] == 'OK': mail.store(uid, '+FLAGS', '\\Deleted') mail.expunge() # Update status pending[msg_id]['status'] = 'done' pending[msg_id]['action'] = 'deleted' pending[msg_id]['processed_at'] = datetime.now().isoformat() save_pending(pending) print(f"✅ 已删除: {email_data.get('subject', 'N/A')[:40]}") return True else: print(f"❌ 删除失败: {result}") return False except Exception as e: print(f"❌ 错误: {e}") return False finally: try: mail.logout() except: pass def main(): """Main function - show pending list""" import json # Load config config_file = Path(__file__).parent / "config.json" with open(config_file) as f: config = json.load(f) show_pending_list() if __name__ == "__main__": main()