Skip to content

Commit

Permalink
Merge pull request #442 from lars-devs/dev
Browse files Browse the repository at this point in the history
Implemented recipients per basket
  • Loading branch information
Der-Henning authored Jan 14, 2024
2 parents d1a53df + bc79e7c commit 9208a19
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
4 changes: 3 additions & 1 deletion config.sample.ini
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Enabled = false
## Subject and Body options are optional.
## Subject and Body options can use variables as described below
## The Body option is interpreted as HTML
## If "RecipientsPerItem" is included, multiple different recipients may be defined for notification. Notifications for items not listed in the JSON are sent to "Recipients".
Enabled = false
Host = smtp.gmail.com
Port = 587
Expand All @@ -106,6 +107,7 @@ TLS = true
SSL = false
Sender = max.mustermann@gmail.com
Recipients = max.mustermann@gmail.com
; RecipientsPerItem = {"123" : ["max.mustermann@example.com", "moritz.mustermann@example.com"], "456" : ["max.mustermann@example.com"], "789": "marta.mustermann@example.com"}
; Cron =
; Subject =
; Body =
Expand Down Expand Up @@ -146,7 +148,7 @@ Topic =
; Cron =

## To use Telegram notifications you have to create a bot using the @botfather
## If you only provide the token of the bot will use the last chat it reseived a message on
## If you only provide the token of the bot will use the last chat it received a message on
## You can add multiple chat ids as a comma seperated list
## The message body is optional and is interpreted as markdown text
## You can use the same variables as described for the Webhook notifier below
Expand Down
3 changes: 3 additions & 0 deletions tgtg_scanner/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ class SMTPConfig(NotifierConfig):
use_ssl: bool = False
sender: Union[str, None] = None
recipients: list[str] = field(default_factory=list)
recipients_per_item: Union[str, None] = None
subject: str = "New Magic Bags"
body: str = "<b>${{display_name}}</b> </br>New Amount: ${{items_available}}"

Expand All @@ -261,6 +262,7 @@ def _read_ini(self, parser: configparser.ConfigParser):
log.warning(DEPRECIATION_WARNING.format("[SMTP] Recipient", "Recipients"))
self._ini_get_list(parser, "SMTP", "Recipient", "recipients") # legacy support
self._ini_get_list(parser, "SMTP", "Recipients", "recipients")
self._ini_get(parser, "SMTP", "RecipientsPerItem", "recipients_per_item")
self._ini_get(parser, "SMTP", "Subject", "subject")
self._ini_get(parser, "SMTP", "Body", "body")

Expand All @@ -278,6 +280,7 @@ def _read_env(self):
log.warning(DEPRECIATION_WARNING.format("SMTP_RECIPIENT", "SMTP_RECIPIENTS"))
self._env_get_list("SMTP_RECIPIENT", "recipients") # legacy support
self._env_get_list("SMTP_RECIPIENTS", "recipients")
self._env_get("SMTP_RECIPIENTS_PER_ITEM", "recipients_per_item")
self._env_get("SMTP_SUBJECT", "subject")
self._env_get("SMTP_BODY", "body")

Expand Down
28 changes: 23 additions & 5 deletions tgtg_scanner/notifiers/smtp.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import logging
import smtplib
from email.mime.multipart import MIMEMultipart
Expand Down Expand Up @@ -29,6 +30,7 @@ def __init__(self, config: Config, reservations: Reservations, favorites: Favori
self.password = config.smtp.password
self.sender = config.smtp.sender
self.recipients = config.smtp.recipients
self.item_recipients: dict[str, list[str]] = {}
self.subject = config.smtp.subject
self.body = config.smtp.body
self.cron = config.smtp.cron
Expand All @@ -44,6 +46,17 @@ def __init__(self, config: Config, reservations: Reservations, favorites: Favori
self._connect()
except Exception as exc:
raise SMTPConfigurationError(exc) from exc
if config.smtp.recipients_per_item is not None:
item_recipients = None
try:
item_recipients = json.loads(config.smtp.recipients_per_item)
except json.decoder.JSONDecodeError:
raise SMTPConfigurationError("Recipients per Item is not a valid dictionary")
if not isinstance(item_recipients, dict) or any(
not isinstance(value, (list, str)) for value in item_recipients.values()
):
raise SMTPConfigurationError("Recipients per Item is not a valid dictionary")
self.item_recipients = {k: v if isinstance(v, list) else [v] for k, v in item_recipients.items()}

def __del__(self):
"""Closes SMTP connection when shutdown"""
Expand Down Expand Up @@ -79,29 +92,34 @@ def _stay_connected(self) -> None:
if status != 250:
self._connect()

def _send_mail(self, subject: str, html: str) -> None:
def _send_mail(self, subject: str, html: str, item_id: int) -> None:
"""Sends mail with html body"""
if self.server is None:
self._connect()
if self.sender is None or self.recipients is None or self.server is None:
raise SMTPConfigurationError()
message = MIMEMultipart("alternative")
message["From"] = self.sender
message["To"] = ", ".join(self.recipients)

# Contains either the main recipient(s) or recipient(s) that should be
# notified for the specific item. First, initalize with main recipient(s)
recipients = self.item_recipients.get(str(item_id), self.recipients)

message["To"] = ", ".join(recipients)
message["Subject"] = subject
message.attach(MIMEText(html, "html", "utf-8"))
body = message.as_string()
self._stay_connected()
try:
self.server.sendmail(self.sender, self.recipients, body)
self.server.sendmail(self.sender, recipients, body)
except SMTPException:
self._connect()
self.server.sendmail(self.sender, self.recipients, body)
self.server.sendmail(self.sender, recipients, body)

def _send(self, item: Union[Item, Reservation]) -> None:
"""Sends item information via Mail."""
if isinstance(item, Item):
self._send_mail(item.unmask(self.subject), item.unmask(self.body))
self._send_mail(item.unmask(self.subject), item.unmask(self.body), item.item_id)

def __repr__(self) -> str:
return f"SMTP: {self.recipients}"
1 change: 1 addition & 0 deletions wiki/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ You can combine multiple crons as semicolon separated list.
| Password | SMTP_PASSWORD | login password |
| Sender | SMTP_SENDER | email sender |
| Recipients | SMTP_RECIPIENTS | email recipients | | YES |
| RecipientsPerItem | SMTP_RECIPIENTS | email recipients per item as JSON | | |
| Subject | SMTP_SUBJECT | email subject | `New Magic Bags` | | YES |
| Body | SMTP_BODY | email html body | `<b>${{display_name}}</b> </br> New Amount: ${{items_available}}` | | YES |
| Cron | SMTP_CRON | enable notification only on schedule | `* * * * *` |
Expand Down

0 comments on commit 9208a19

Please sign in to comment.