todonotifier.notifier

This module provides interface to define a notifier that notifies the users. It also provides an EmailNotifier to notify over email.

 1""" This module provides interface to define a notifier that notifies the users. It also
 2provides an EmailNotifier to notify over email.
 3"""
 4
 5import smtplib
 6import ssl
 7from abc import ABC, abstractmethod
 8from datetime import datetime
 9from email.mime.multipart import MIMEMultipart
10from email.mime.text import MIMEText
11from typing import List, Tuple, Union
12
13
14class BaseNotifier(ABC):
15    def __init__(self) -> None:
16        """Initializer for `BaseNotifier`"""
17        pass
18
19    def _aggregate_all_summaries(self, summary: List[Tuple[str, str]]) -> str:
20        """Abstract method allowing to aggregate all summaries together to be sent
21
22        Args:
23            summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
24
25        Returns:
26            str: Returns the string representing aggregation of all summaries in their html format
27        """
28        html = """\
29        <html>
30        <body>
31        """
32
33        for summary_name, summary_html in summary:
34            html += f"""
35            <h1>{summary_name}</h1>
36            <p>
37                {summary_html}
38            </p><br>
39            """
40
41        html += """
42        </body>
43        </html>
44        """
45
46        return html
47
48    @abstractmethod
49    def notify(self, summary: List[Tuple[str, str]]) -> None:
50        """Abstract method to send notification to users via method setup by users
51
52        Args:
53            summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
54        """
55        pass
56
57
58class EmailNotifier(BaseNotifier):
59    def __init__(self, sender_email: str, password: str, host: str, port: int, receivers: Union[List[str], None] = None) -> None:
60        """Initializer for `EmailNotifier` class
61
62        Args:
63            sender_email (str): Email id from which email needs to be sent
64            password (str): Password for email id `sender_email`
65            host (str): Host for sending email for e.g. `smtp.gmail.com` for Gmail
66            port (int): Port for sending email for e.g. `465` for Gmail
67            receivers (Union[List[str], None], optional): List of receivers. Defaults to None.
68        """
69        self._sender_email = sender_email
70        self._receivers = receivers or []
71        self._password = password
72        self._host = host
73        self._port = port
74        super().__init__()
75
76    def notify(self, summary: List[Tuple[str, str]]) -> None:
77        """Sends email to `receivers_list` with `html` content
78
79        Args:
80            summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
81        """
82        html = self._aggregate_all_summaries(summary)
83        receivers_str = ", ".join(self._receivers)
84
85        message = MIMEMultipart("alternative")
86        message["Subject"] = f"TODO Summary - {datetime.today().date()}"
87        message["From"] = self._sender_email
88        message["To"] = receivers_str
89
90        html = MIMEText(html, "html")
91        message.attach(html)
92        context = ssl.create_default_context()
93        with smtplib.SMTP_SSL(self._host, self._port, context=context) as server:
94            server.login(self._sender_email, self._password)
95            server.sendmail(self._sender_email, self._receivers, message.as_string())
class BaseNotifier(abc.ABC):
15class BaseNotifier(ABC):
16    def __init__(self) -> None:
17        """Initializer for `BaseNotifier`"""
18        pass
19
20    def _aggregate_all_summaries(self, summary: List[Tuple[str, str]]) -> str:
21        """Abstract method allowing to aggregate all summaries together to be sent
22
23        Args:
24            summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
25
26        Returns:
27            str: Returns the string representing aggregation of all summaries in their html format
28        """
29        html = """\
30        <html>
31        <body>
32        """
33
34        for summary_name, summary_html in summary:
35            html += f"""
36            <h1>{summary_name}</h1>
37            <p>
38                {summary_html}
39            </p><br>
40            """
41
42        html += """
43        </body>
44        </html>
45        """
46
47        return html
48
49    @abstractmethod
50    def notify(self, summary: List[Tuple[str, str]]) -> None:
51        """Abstract method to send notification to users via method setup by users
52
53        Args:
54            summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
55        """
56        pass

Helper class that provides a standard way to create an ABC using inheritance.

BaseNotifier()
16    def __init__(self) -> None:
17        """Initializer for `BaseNotifier`"""
18        pass

Initializer for BaseNotifier

@abstractmethod
def notify(self, summary: List[Tuple[str, str]]) -> None:
49    @abstractmethod
50    def notify(self, summary: List[Tuple[str, str]]) -> None:
51        """Abstract method to send notification to users via method setup by users
52
53        Args:
54            summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
55        """
56        pass

Abstract method to send notification to users via method setup by users

Arguments:
  • summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
class EmailNotifier(BaseNotifier):
59class EmailNotifier(BaseNotifier):
60    def __init__(self, sender_email: str, password: str, host: str, port: int, receivers: Union[List[str], None] = None) -> None:
61        """Initializer for `EmailNotifier` class
62
63        Args:
64            sender_email (str): Email id from which email needs to be sent
65            password (str): Password for email id `sender_email`
66            host (str): Host for sending email for e.g. `smtp.gmail.com` for Gmail
67            port (int): Port for sending email for e.g. `465` for Gmail
68            receivers (Union[List[str], None], optional): List of receivers. Defaults to None.
69        """
70        self._sender_email = sender_email
71        self._receivers = receivers or []
72        self._password = password
73        self._host = host
74        self._port = port
75        super().__init__()
76
77    def notify(self, summary: List[Tuple[str, str]]) -> None:
78        """Sends email to `receivers_list` with `html` content
79
80        Args:
81            summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
82        """
83        html = self._aggregate_all_summaries(summary)
84        receivers_str = ", ".join(self._receivers)
85
86        message = MIMEMultipart("alternative")
87        message["Subject"] = f"TODO Summary - {datetime.today().date()}"
88        message["From"] = self._sender_email
89        message["To"] = receivers_str
90
91        html = MIMEText(html, "html")
92        message.attach(html)
93        context = ssl.create_default_context()
94        with smtplib.SMTP_SSL(self._host, self._port, context=context) as server:
95            server.login(self._sender_email, self._password)
96            server.sendmail(self._sender_email, self._receivers, message.as_string())

Helper class that provides a standard way to create an ABC using inheritance.

EmailNotifier( sender_email: str, password: str, host: str, port: int, receivers: Optional[List[str]] = None)
60    def __init__(self, sender_email: str, password: str, host: str, port: int, receivers: Union[List[str], None] = None) -> None:
61        """Initializer for `EmailNotifier` class
62
63        Args:
64            sender_email (str): Email id from which email needs to be sent
65            password (str): Password for email id `sender_email`
66            host (str): Host for sending email for e.g. `smtp.gmail.com` for Gmail
67            port (int): Port for sending email for e.g. `465` for Gmail
68            receivers (Union[List[str], None], optional): List of receivers. Defaults to None.
69        """
70        self._sender_email = sender_email
71        self._receivers = receivers or []
72        self._password = password
73        self._host = host
74        self._port = port
75        super().__init__()

Initializer for EmailNotifier class

Arguments:
  • sender_email (str): Email id from which email needs to be sent
  • password (str): Password for email id sender_email
  • host (str): Host for sending email for e.g. smtp.gmail.com for Gmail
  • port (int): Port for sending email for e.g. 465 for Gmail
  • receivers (Union[List[str], None], optional): List of receivers. Defaults to None.
def notify(self, summary: List[Tuple[str, str]]) -> None:
77    def notify(self, summary: List[Tuple[str, str]]) -> None:
78        """Sends email to `receivers_list` with `html` content
79
80        Args:
81            summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html
82        """
83        html = self._aggregate_all_summaries(summary)
84        receivers_str = ", ".join(self._receivers)
85
86        message = MIMEMultipart("alternative")
87        message["Subject"] = f"TODO Summary - {datetime.today().date()}"
88        message["From"] = self._sender_email
89        message["To"] = receivers_str
90
91        html = MIMEText(html, "html")
92        message.attach(html)
93        context = ssl.create_default_context()
94        with smtplib.SMTP_SSL(self._host, self._port, context=context) as server:
95            server.login(self._sender_email, self._password)
96            server.sendmail(self._sender_email, self._receivers, message.as_string())

Sends email to receivers_list with html content

Arguments:
  • summary (List[Tuple[str, str]]): List of tuples where each tuple consists of summary name and generated summary html