import time import arrow from typing import TypeVar from config import Config from redbox import EmailBox from redbox.query import FROM, UNSEEN, OR from Services.MongoService.provider import MongoProvider from Configs.mongo import MongoConfig host = Config.EMAIL_HOST port = Config.EMAIL_PORT username = Config.EMAIL_USERNAME password = Config.EMAIL_PASSWORD authorized_iban = Config.AUTHORIZE_IBAN authorized_iban_cleaned = authorized_iban.replace("-", "") mongo_prefix = "CollectedData" delimiter = "|" # banks_mails = mailbox.search(from_=filter_mail, unseen=True) bununla denemeyin # banks_mails = mailbox.search(FROM(filter_mail) & UNSEEN) T = TypeVar("T") def check_payload_already_exists_mongo_database(filename: str, mongo_provider) -> bool: find_one_result = mongo_provider.find_one(filter_query={ "filename": filename }) if find_one_result: return True return False def write_payload_to_mongo_database(payload, filename: str, mail_info:dict, mongo_provider) -> bool: insert_one_result = mongo_provider.insert_one(document={ "filename": filename, "payload": payload, "stage": "read", "created_at": str(arrow.now()), **mail_info }) if insert_one_result.acknowledged: return True return False def read_email_and_write_to_mongo_database(email_message, mail_info: dict) -> bool: with MongoProvider.mongo_client() as mongo_client: mongo_provider = MongoProvider( client=mongo_client, database=MongoConfig.DATABASE_NAME, storage_reason=[mongo_prefix, str(arrow.now().date())], ) if email_message.is_multipart(): # Check if email has multipart content for part in email_message.walk(): # Each part can be an attachment content_disposition = part.get("Content-Disposition") if content_disposition and "attachment" in content_disposition: if filename := part.get_filename(): file_exists = not check_payload_already_exists_mongo_database( filename=filename, mongo_provider=mongo_provider ) is_iban_in_filename = authorized_iban_cleaned in str(filename) if is_iban_in_filename and file_exists: if payload := part.get_payload(decode=True): return write_payload_to_mongo_database( payload=payload, filename=filename, mongo_provider=mongo_provider, mail_info=mail_info ) else: # Handle non-multipart email, though this is rare for emails with attachments content_disposition = email_message.get("Content-Disposition") if content_disposition and "attachment" in content_disposition: if filename := email_message.get_filename(): file_exists = not check_payload_already_exists_mongo_database( filename=filename, mongo_provider=mongo_provider, ) is_iban_in_filename= authorized_iban_cleaned in str(filename) if is_iban_in_filename and file_exists: payload = email_message.get_payload(decode=True) return write_payload_to_mongo_database( payload=payload, filename=filename, mongo_provider=mongo_provider, mail_info=mail_info, ) return False def app(): box = EmailBox(host=host, port=port, username=username, password=password) if not box: return Exception("Mailbox not found") box.connect() mail_folders = box.mailfolders filter_mail = OR(FROM(Config.MAILBOX), FROM(Config.MAIN_MAIL)) filter_print = f"{Config.MAILBOX} & {Config.MAIN_MAIL}" for folder in mail_folders: if folder.name == "INBOX": banks_mails = folder.search(filter_mail & UNSEEN) print( f"Service is reading mailbox [{username}] with mail sender [{filter_print}] with count : {len(banks_mails)}" ) for banks_mail in banks_mails or []: if email_message := banks_mail.email: headers = {k.lower(): v for k, v in banks_mail.headers.items()} mail_info = { "from": headers['from'], "to": headers['to'], "subject": headers['subject'], "date": str(headers['date']), } read_email_and_write_to_mongo_database( email_message=email_message, mail_info=mail_info ) if __name__ == "__main__": while True: print('Running email service...') app() time.sleep(Config.EMAIL_SLEEP)