import imaplib import email import re import os import datetime from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas from argparse import ArgumentParser def extract_text_from_email(email_message): """Extract the text from an email message. This function extracts the text from an email message by recursively searching through the email parts. """ text = "" for part in email_message.walk(): if part.get_content_type() == "text/plain": text += part.get_payload() return text def extract_client_name(text): """Extract the client name from the email text. This function extracts the client name from the email text by searching for a pattern that looks like "Bill To: Client Name". """ pattern = r"Bill To: (.+)" match = re.search(pattern, text, re.IGNORECASE) if match: return match.group(1) else: return None def create_client_folder(output_dir, client_name): """Create a folder for the client if it does not exist. """ client_dir = os.path.join(output_dir, client_name) if not os.path.exists(client_dir): os.mkdir(client_dir) return client_dir def save_attachment(attachment, output_filename): """Save an email attachment to a file. """ with open(output_filename, "wb") as f: f.write(attachment.get_payload(decode=True)) def process_email(email_message, keywords, output_dir): """Process an email message and save any invoices to the output directory. """ text = extract_text_from_email(email_message) client_name = extract_client_name(text) if client_name: client_dir = create_client_folder(output_dir, client_name) for part in email_message.walk(): filename = part.get_filename() if filename and any(keyword in filename.lower() or keyword in text.lower() for keyword in keywords): output_filename = os.path.join(client_dir, filename) save_attachment(part, output_filename) def search_emails(server, username, password, keywords): """Search for emails with the specified keywords. This function connects to the email server and searches for emails with the specified keywords in the subject line or body of the email. It then processes any emails with invoices. """ imap = imaplib.IMAP4_SSL(server) imap.login(username, password) imap.select("INBOX") # Search for emails with the specified keywords for keyword in keywords: result, data = imap.search(None, f'(OR SUBJECT "{keyword}" BODY "{keyword}")') if result == "OK": for email_id in data[0].split(): result, data = imap.fetch(email_id, "(RFC822)") if result == "OK": email_message = email.message_from_bytes(data[0][1]) process_email(email_message, keywords, output_dir) imap.logout() def generate_report(output_dir): """Generate a PDF report of the invoices processed. This function generates a PDF report that lists the number of invoices processed and the number of invoices for each client. """ # Get the current date and time now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Get a list of all client folders in the output directory clients = os.listdir(output_dir) # Create a new PDF file pdf_filename = "report.pdf" pdf = canvas.Canvas(pdf_filename, pagesize=letter) # Add a title to the first page of the PDF pdf.setFont("Helvetica-Bold", 16) pdf.drawString(100, 700, "Invoice Report") pdf.setFont("Helvetica", 12) pdf.drawString(100, 670, f"Generated on: {now}") pdf.drawString(100, 640, f"Number of invoices processed: {len(clients)}") # Add a table of clients and the number of invoices for each client y = 600 for client in clients: invoices = os.listdir(os.path.join(output_dir, client)) pdf.drawString(100, y, f"{client}: {len(invoices)} invoices") y -= 20 # Save the PDF file pdf.save() # Print the report to the console print(f"Report generated on {now}") print(f"Number of invoices processed: {len(clients)}") for client in clients: invoices = os.listdir(os.path.join(output_dir, client)) print(f"{client}: {len(invoices)} invoices")