136 lines
5.1 KiB
Python
136 lines
5.1 KiB
Python
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)
|