Skip to content

Commit

Permalink
fixed not sending confirmation mail after subscription/unsubscription…
Browse files Browse the repository at this point in the history
… issue
  • Loading branch information
f-hein committed Mar 6, 2020
1 parent cb8c14d commit 16716ec
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 102 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ Used variables' names are: `WL_USERNAME, WL_PASSWORD, WG_USERNAME, WG_PASSWORD`.
- [ ] Add unit tests
- [ ] Send mail to a newly subscribed person IF foodletter was sent that day
- [ ] Add Meet&Eat Wroclaw to GTA/GTB
- [ ] Repair L87/mailer
- [ ] Add backup of subscribers lists to cloud
3 changes: 2 additions & 1 deletion emails/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .email_parts import footer, get_default_subject
from .mailer import MailCreator, MailSender, SubscriptionChecker
from .mailer import MailCreator, MailSender
from .mailing_list import MailingList
from .state import State
from .subscription_checker import SubscriptionChecker
71 changes: 6 additions & 65 deletions emails/mailer.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
# -*- coding: utf-8 -*-
import imaplib
import logging
import re
import smtplib
from datetime import date
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

from emails.email_parts import footer, get_default_subject
from emails.mailing_list import MailingList


class MailCreator:
def create_email(self, recipient: str, sender: str, subject=None, msg_body=None) -> MIMEMultipart:
def create_email(self, recipient: str, sender: str, subject=None, msg_body=None,
use_mail_template=True) -> MIMEMultipart:
msg = MIMEMultipart()
msg['From'] = f"FoodBot <{sender}>"
msg['To'] = recipient
msg['Subject'] = get_default_subject() if not subject else subject
msg.attach(MIMEText(self._get_body_with_added_date_and_footer(msg_body), 'plain'))
if use_mail_template:
msg.attach(MIMEText(self._get_body_with_added_date_and_footer(msg_body), 'plain'))
else:
msg.attach(MIMEText(msg_body, 'plain'))
return msg

@staticmethod
Expand Down Expand Up @@ -48,63 +49,3 @@ def _send_email(self, email_object: MIMEMultipart) -> None:
server.login(self.email, self.password)
server.send_message(email_object)
server.close()


class SubscriptionChecker:
def __init__(self, email, password, site, send_confirmation_mails=True):
self.email = email
self.password = password
self.site = site
self.send_confirmation_mails = send_confirmation_mails
self.imap = None

def check(self) -> None:
self._create_imap_connection_and_select_inbox()
unread_mails_ids = self._get_unread_mails_ids()
for email_id in unread_mails_ids:
sender_email, subject, body = self._get_core_data_by_email_id(email_id)
self._check_subscription_requests(sender_email, subject, body)
self._delete_imap_connection()

def _create_imap_connection_and_select_inbox(self):
self.imap = imaplib.IMAP4_SSL("imap.gmail.com", 993)
self.imap.login(self.email, self.password)
self.imap.select('INBOX')

def _delete_imap_connection(self):
self.imap.close()
del self.imap

@staticmethod
def _get_sender_mail(body) -> str:
return re.findall('<(.*)>', str(body[1][1]))[0]

@staticmethod
def _get_subject(body) -> str:
return re.findall('(?<=Subject: )[a-zA-Z ]*', str(body[1][1]))[0].upper()

def _check_subscription_requests(self, sender_email: str, subject: str, body: str) -> None:
key_words = ['SUBSCRIBE', 'UNSUBSCRIBE']
for key_word in key_words:
if key_word in subject or key_word in body:
MailingList(self.site).add(sender_email) if key_word == 'SUBSCRIBE' \
else MailingList(self.site).delete(sender_email)
if self.send_confirmation_mails:
self._send_confirmation_email(key_word, sender_email)

def _send_confirmation_email(self, subscribe_state, recipient) -> None:
subject = f"{subscribe_state.lower()}d"
body = f"You've been successfully {subscribe_state.lower()}d!"
email_object = MailCreator().create_email(self.email, recipient, subject=subject, msg_body=body)
MailSender(self.email, self.password).send_mail_to_one_recipient(recipient, email_object)

def _get_unread_mails_ids(self):
_, response = self.imap.search(None, '(UNSEEN)')
return response[0].split()

def _get_core_data_by_email_id(self, email_id) -> tuple:
_, body = self.imap.fetch(email_id, '(BODY[TEXT] BODY[HEADER.FIELDS (FROM SUBJECT)])')
sender_email = self._get_sender_mail(body)
subject = self._get_subject(body)
body = str(body[0][1]).upper()
return sender_email, subject, body
66 changes: 66 additions & 0 deletions emails/subscription_checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import imaplib
import re

from emails import MailingList, MailCreator, MailSender


class SubscriptionChecker:
def __init__(self, email, password, site, send_confirmation_mails=True):
self.email = email
self.password = password
self.site = site
self.send_confirmation_mails = send_confirmation_mails
self.imap = None

def check(self) -> None:
self._create_imap_connection_and_select_inbox()
unread_mails_ids = self._get_unread_mails_ids()
for email_id in unread_mails_ids:
sender_email, subject, body = self._get_core_data_by_email_id(email_id)
self._check_subscription_requests(sender_email, subject, body)
self._delete_imap_connection()

def _create_imap_connection_and_select_inbox(self):
self.imap = imaplib.IMAP4_SSL("imap.gmail.com", 993)
self.imap.login(self.email, self.password)
self.imap.select('INBOX')

def _delete_imap_connection(self):
self.imap.close()
del self.imap

@staticmethod
def _get_sender_mail(body) -> str:
return re.findall('<(.*)>', str(body[1][1]))[0]

@staticmethod
def _get_subject(body) -> str:
subject = re.findall('(?<=Subject: )[a-zA-Z ]*', str(body[1][1]))
return subject[0].upper() if subject else ''

def _check_subscription_requests(self, sender_email: str, subject: str, body: str) -> None:
key_words = ['UNSUBSCRIBE', 'SUBSCRIBE']
for key_word in key_words:
if key_word in subject or key_word in body:
MailingList(self.site).add(sender_email) if key_word == 'SUBSCRIBE' \
else MailingList(self.site).delete(sender_email)
if self.send_confirmation_mails:
self._send_confirmation_email(key_word, sender_email)

def _send_confirmation_email(self, subscribe_state, recipient) -> None:
subject = f"{subscribe_state.lower()}d".capitalize()
body = f"You've been successfully {subscribe_state.lower()}d!"
email_object = MailCreator().create_email(recipient, self.email, subject=subject, msg_body=body,
use_mail_template=False)
MailSender(self.email, self.password).send_mail_to_one_recipient(recipient, email_object)

def _get_unread_mails_ids(self):
_, response = self.imap.search(None, '(UNSEEN)')
return response[0].split()

def _get_core_data_by_email_id(self, email_id) -> tuple:
_, body = self.imap.fetch(email_id, '(BODY[TEXT] BODY[HEADER.FIELDS (FROM SUBJECT)])')
sender_email = self._get_sender_mail(body)
subject = self._get_subject(body)
body = str(body[0][1]).upper()
return sender_email, subject, body
4 changes: 2 additions & 2 deletions logic/sites.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import logging
from abc import ABC

from emails import SubscriptionChecker, MailSender, MailingList, MailCreator
from bot_credentials import WL_USERNAME, WL_PASSWORD, GT_USERNAME, GT_PASSWORD
from emails import State
from emails import SubscriptionChecker, MailSender, MailingList, MailCreator
from scrapers import AstraMenu, CockpeatMenu, ObiadeoMenu, KameMenu, GreenTowersBistroMenu
from bot_credentials import WL_USERNAME, WL_PASSWORD, GT_USERNAME, GT_PASSWORD


class Site(ABC):
Expand Down
2 changes: 1 addition & 1 deletion scrapers/FacebookPage.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
import re
from abc import ABC, abstractmethod
from abc import ABC
from datetime import datetime

import requests
Expand Down
3 changes: 2 additions & 1 deletion scrapers/KameMenu.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import re
import datetime
import re

from scrapers.FacebookPage import FacebookPage
from scrapers.IMenu import IMenu
from tools.levenshtein_distance import calc_levenshtein
Expand Down
31 changes: 0 additions & 31 deletions scrapers/all_scrapers.py

This file was deleted.

0 comments on commit 16716ec

Please sign in to comment.