wag-services-and-backend-la.../BankServices/EmailService/app.py

136 lines
5.1 KiB
Python

import time
import arrow
from typing import TypeVar
from ApiLayers.AllConfigs.Email.configs 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)