================================================================================ GMAIL CLEANUP - CHALLENGE 1 SOLUTION Chapter 4: Building Email Utilities Challenge: Build GmailCleanup Class ================================================================================ PROBLEM: Create GmailCleanup class with methods: 1. find_emails(query, limit) 2. delete_email(message_id) 3. get_email_details(message_id) SOLUTION: ================================================================================ File: gmail_utils.py (GmailCleanup class) class GmailCleanup: """Reusable Gmail cleanup utilities.""" def __init__(self, service, config): self.service = service self.config = config self.deleted_count = 0 self.archived_count = 0 def find_emails(self, query: str, limit: int = 10) -> list: """Find emails matching query.""" try: results = self.service.users().messages().list( userId='me', q=query, maxResults=limit ).execute() return results.get('messages', []) except Exception as e: print(f"❌ Error finding emails: {e}") return [] def delete_email(self, message_id: str) -> bool: """Delete a single email.""" try: self.service.users().messages().delete( userId='me', id=message_id ).execute() self.deleted_count += 1 return True except Exception as e: print(f"❌ Error deleting email: {e}") return False def get_email_details(self, message_id: str) -> dict: """Get details about a single email.""" try: message = self.service.users().messages().get( userId='me', id=message_id ).execute() headers = message['payload']['headers'] subject = next((h['value'] for h in headers if h['name'] == 'Subject'), 'No Subject') sender = next((h['value'] for h in headers if h['name'] == 'From'), 'Unknown') date = next((h['value'] for h in headers if h['name'] == 'Date'), 'Unknown') size_mb = int(message.get('sizeEstimate', 0)) / 1024 / 1024 return { 'id': message_id, 'subject': subject, 'from': sender, 'date': date, 'size_mb': size_mb } except Exception as e: print(f"❌ Error getting details: {e}") return None USAGE EXAMPLE ================================================================================ from gmail_utils import get_gmail_service, GmailCleanup from config import Config # Setup config = Config() service = get_gmail_service() cleanup = GmailCleanup(service, config) # Find old emails emails = cleanup.find_emails("before:2020/01/01", limit=5) # Delete them for email in emails: cleanup.delete_email(email['id']) # Check deleted count print(f"Deleted: {cleanup.deleted_count}") KEY PATTERNS ================================================================================ ✅ Class-based organization (groups related functions) ✅ Service passed to __init__ (dependency injection) ✅ State tracking (deleted_count, archived_count) ✅ Error handling throughout ✅ Return types clearly specified This is reusable and testable! ================================================================================