import itertools import random import smtplib import threading from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from scraper.log import root_logger logger = root_logger.get_child('EMAIL_SENDER') class EmailWorker(threading.Thread): def __init__(self, queue, email_sender): threading.Thread.__init__(self) self.queue = queue self.email_sender = email_sender self.server = None self.daemon = True self.login() def run(self): while True: to, subject, msg, img_path = self.queue.get() try: self.send_email(to, subject, msg, img_path) finally: self.queue.task_done() def login(self): try: self.server = smtplib.SMTP_SSL('smtp.email.com', 465) self.server.login("youremailaddress@shit.fuck", "password123") logger.info(f'{self.email_sender} logged in to SMTP') except smtplib.SMTPAuthenticationError as e: logger.error(f'Failed to login - {e.__class__.__name__}. SMTP Code: {e.smtp_code}. Error: {e.smtp_error.decode()}') return None except Exception as e: logger.error(f'Failed to login - {e.__class__.__name__}: {e}') return None def send_email(self, to, subject, msg, img_path): msgRoot = MIMEMultipart('related') msgRoot['Subject'] = subject msgRoot['From'] = self.email_sender msgRoot['To'] = to msgRoot.preamble = 'This is a multi-part message in MIME format.' msgAlternative = MIMEMultipart('alternative') msgRoot.attach(msgAlternative) msgText = MIMEText('This is the alternative plain text message.') msgAlternative.attach(msgText) if img_path: img_html = '

' else: img_html = '' msgText = MIMEText(f'{msg}{img_html}', 'html') msgAlternative.attach(msgText) if img_path: with open(img_path, 'rb') as fp: msgImage = MIMEImage(fp.read()) msgImage.add_header('Content-ID', '') msgRoot.attach(msgImage) logger.debug(f'Sending to {to} from {self.email_sender}') try: if not self.server.noop()[0] == 250: self.login() result = self.server.sendmail(self.email_sender, to, msgRoot.as_string()) self.server.ehlo() # reset the SMTP session logger.info(f'Sent to {to} from {self.email_sender}') return result except smtplib.SMTPDataError as e: if e.smtp_code != 250: logger.error(f'Failed to send email to {to} - {e.__class__.__name__}. SMTP Code: {e.smtp_code}. Error: {e.smtp_error.decode()}') except Exception as e: logger.error(f'Failed to send email to {to} - {e.__class__.__name__}: {e}') return