From 5cce7b0e85fa17077533b8b82f5853801d949b58 Mon Sep 17 00:00:00 2001 From: mutantsan Date: Thu, 4 Jan 2024 14:22:20 +0200 Subject: [PATCH] feature: create config page, add redirect option part2 --- ckanext/mailcraft/config_declaration.yaml | 6 ++-- ckanext/mailcraft/logic/action.py | 9 ++++++ ckanext/mailcraft/mailer.py | 30 +++++++++++-------- ckanext/mailcraft/model.py | 18 ++++++----- .../mailcraft/templates/mailcraft/config.html | 2 +- .../templates/mailcraft/emails/test.html | 7 +++++ ckanext/mailcraft/types.py | 18 +++++++++++ 7 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 ckanext/mailcraft/templates/mailcraft/emails/test.html diff --git a/ckanext/mailcraft/config_declaration.yaml b/ckanext/mailcraft/config_declaration.yaml index 7c5477a..fc51162 100644 --- a/ckanext/mailcraft/config_declaration.yaml +++ b/ckanext/mailcraft/config_declaration.yaml @@ -22,7 +22,5 @@ groups: description: Specify a number of mails to show per page on a dashboard default: 20 - - key: ckanext.mailcraft.save_to_dashboard - type: bool - description: Specify do we need to save outgoing emails to dashboard - default: false + - key: ckanext.mailcraft.redirect_emails_to + description: Redirect outgoing emails to a specified email diff --git a/ckanext/mailcraft/logic/action.py b/ckanext/mailcraft/logic/action.py index 2120482..92efbd2 100644 --- a/ckanext/mailcraft/logic/action.py +++ b/ckanext/mailcraft/logic/action.py @@ -47,3 +47,12 @@ def mc_mail_delete(context, data_dict): context["session"].commit() return True + + +def mc_mail_clear(context, data_dict): + """Clear all stored mails""" + tk.check_access("mc_mail_delete", context, data_dict) + + emails_deleted = mc_model.Email.clear_emails() + + return {"deleted": emails_deleted} diff --git a/ckanext/mailcraft/mailer.py b/ckanext/mailcraft/mailer.py index 188c329..6b0bf05 100644 --- a/ckanext/mailcraft/mailer.py +++ b/ckanext/mailcraft/mailer.py @@ -20,6 +20,7 @@ Attachment, AttachmentWithoutType, AttachmentWithType, + EmailData, ) log = logging.getLogger(__name__) @@ -38,6 +39,8 @@ def __init__(self): self.site_url = tk.config["ckan.site_url"] self.conn_timeout = mc_config.get_conn_timeout() + self.stop_outgoing = mc_config.stop_outgoing_emails() + self.redirect_to = mc_config.get_redirect_email() @abstractmethod def mail_recipients( @@ -113,21 +116,23 @@ def mail_recipients( if attachments: self.add_attachments(msg, attachments) + email_data: EmailData = dict(msg.items()) # type: ignore + try: - # print(msg.get_body(("html",)).get_content()) # type: ignore - if mc_config.stop_outgoing_emails(): - self._save_email( - msg, body_html, mc_model.Email.State.stopped, dict(msg.items()) - ) + if self.stop_outgoing: + self._save_email(email_data, body_html, mc_model.Email.State.stopped) else: + if recipient := mc_config.get_redirect_email(): + email_data["redirected_from"] = recipients + recipients = [recipient] + email_data["To"] = email_data["Bcc"] = ", ".join(recipients) + self._send_email(recipients, msg) except MailerException: - self._save_email( - msg, body_html, mc_model.Email.State.failed, dict(msg.items()) - ) + self._save_email(email_data, body_html, mc_model.Email.State.failed) else: - if not mc_config.stop_outgoing_emails(): - self._save_email(msg, body_html) + if not self.stop_outgoing: + self._save_email(email_data, body_html) def add_attachments(self, msg: EmailMessage, attachments) -> None: """Add attachments on an email message @@ -186,12 +191,11 @@ def get_connection(self) -> smtplib.SMTP: def _save_email( self, - msg: EmailMessage, + email_data: EmailData, body_html: str, state: str = mc_model.Email.State.success, - extras: Optional[dict[str, Any]] = None, ) -> None: - mc_model.Email.save_mail(msg, body_html, state, extras or {}) + mc_model.Email.save_mail(email_data, body_html, state) def _send_email(self, recipients, msg: EmailMessage): conn = self.get_connection() diff --git a/ckanext/mailcraft/model.py b/ckanext/mailcraft/model.py index 9778f25..b03cc55 100644 --- a/ckanext/mailcraft/model.py +++ b/ckanext/mailcraft/model.py @@ -3,7 +3,6 @@ import logging from datetime import datetime from typing import Any -from email.message import EmailMessage from sqlalchemy import Column, DateTime, Integer, Text from sqlalchemy.orm import Query @@ -14,6 +13,8 @@ import ckan.model as model from ckan.plugins import toolkit as tk +from ckanext.mailcraft.types import EmailData + log = logging.getLogger(__name__) @@ -43,16 +44,19 @@ def all(cls) -> list[dict[str, Any]]: @classmethod def save_mail( - cls, msg: EmailMessage, body_html: str, state: str, extras: dict[str, Any] + cls, + email_data: EmailData, + body_html: str, + state: str, ) -> Email: mail = cls( - subject=msg["Subject"], - timestamp=msg["Date"], - sender=msg["From"], - recipient=msg["To"], + subject=email_data["Subject"], + timestamp=email_data["Date"], + sender=email_data["From"], + recipient=email_data["To"], message=body_html, state=state, - extras=extras, + extras=email_data, ) model.Session.add(mail) diff --git a/ckanext/mailcraft/templates/mailcraft/config.html b/ckanext/mailcraft/templates/mailcraft/config.html index 3106781..2cecedc 100644 --- a/ckanext/mailcraft/templates/mailcraft/config.html +++ b/ckanext/mailcraft/templates/mailcraft/config.html @@ -13,7 +13,7 @@

{{ _("Mailcraft configuration") }}

{% for _, config in configs.items() %} {% if config.type == "select" %} - {{ form.select(config.key, label=config.label, options=config.options, selected=data[config.key] | o if data else config.value, error=errors[config.key]) }} + {{ form.select(config.key, label=config.label, options=config.options, selected=data[config.key] | int if data else config.value, error=errors[config.key]) }} {% elif config.type in ("text", "number") %} {{ form.input(config.key, label=config.label, value=data[config.key] if data else config.value, error=errors[config.key], type=config.type) }} {% else %} diff --git a/ckanext/mailcraft/templates/mailcraft/emails/test.html b/ckanext/mailcraft/templates/mailcraft/emails/test.html new file mode 100644 index 0000000..b45fcc7 --- /dev/null +++ b/ckanext/mailcraft/templates/mailcraft/emails/test.html @@ -0,0 +1,7 @@ +{% extends "mailcraft/emails/base.html" %} + +{% block main_text %} + +Test + +{% endblock %} diff --git a/ckanext/mailcraft/types.py b/ckanext/mailcraft/types.py index c2668d3..a6c2c65 100644 --- a/ckanext/mailcraft/types.py +++ b/ckanext/mailcraft/types.py @@ -1,7 +1,25 @@ from __future__ import annotations from typing import IO, Tuple, Union +from typing_extensions import NotRequired, TypedDict + AttachmentWithType = Union[Tuple[str, IO[str], str], Tuple[str, IO[bytes], str]] AttachmentWithoutType = Union[Tuple[str, IO[str]], Tuple[str, IO[bytes]]] Attachment = Union[AttachmentWithType, AttachmentWithoutType] + + +EmailData = TypedDict( + "EmailData", + { + "Bcc": str, + "Content-Type": NotRequired[str], + "Date": str, + "From": str, + "MIME-Version": NotRequired[str], + "Subject": str, + "To": str, + "X-Mailer": NotRequired[str], + "redirected_from": NotRequired["list[str]"] + }, +)