diff options
-rw-r--r-- | sendmail2.py | 151 | ||||
-rw-r--r--[-rwxr-xr-x] | sjdbmk/inspire_approve.py (renamed from inspire_approve.py) | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sjdbmk/inspire_dl.py (renamed from inspire_dl.py) | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sjdbmk/legacy_wikipedia.py (renamed from legacy_wikipedia.py) | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sjdbmk/sendmail.py (renamed from sendmail.py) | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | sjdbmk/serve.py (renamed from serve.py) | 0 |
6 files changed, 0 insertions, 151 deletions
diff --git a/sendmail2.py b/sendmail2.py deleted file mode 100644 index 749eb23..0000000 --- a/sendmail2.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env python3 -# -# Send the Daily Bulletin the next morning -# Copyright (C) 2024 Runxi Yu <https://runxiyu.org> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -# -# **TODO:** Send MIME rather than JSON -# - -from __future__ import annotations -import os -import datetime -import zoneinfo -import argparse -from configparser import ConfigParser -from typing import Optional -import msal # type: ignore -import requests - - -def acquire_token(app: msal.PublicClientApplication, config: ConfigParser) -> str: - result = app.acquire_token_by_username_password( - config["credentials"]["username"], - config["credentials"]["password"], - scopes=config["credentials"]["scope"].split(" "), - ) - - if "access_token" in result: - assert isinstance(result["access_token"], str) - return result["access_token"] - raise ValueError("Authentication error in password login") - - -def sendmail( - token: str, - subject: str, - body: str, - to: list[str], - bcc: list[str], - cc: list[str], - when: Optional[datetime.datetime] = None, - content_type: str = "HTML", - importance: str = "Normal", -) -> None: - data = { - "subject": subject, - "importance": importance, - "body": {"contentType": content_type, "content": body}, - "toRecipients": [{"emailAddress": {"address": a}} for a in to], - "ccRecipients": [{"emailAddress": {"address": a}} for a in cc], - "bccRecipients": [{"emailAddress": {"address": a}} for a in bcc], - } - - if when is not None: - if when.tzinfo is None: - raise TypeError("Naive datetimes are no longer supported") - utcwhen = when.astimezone(datetime.timezone.utc) - isoval = utcwhen.isoformat(timespec="seconds").replace("+00:00", "Z") - data["singleValueExtendedProperties"] = [{"id": "SystemTime 0x3FEF", "value": isoval}] - - response = requests.post( - "https://graph.microsoft.com/v1.0/me/messages", - json=data, - headers={"Authorization": "Bearer " + token}, - timeout=20, - ).json() - response2 = requests.post( - "https://graph.microsoft.com/v1.0/me/messages/%s/send" % response["id"], - headers={"Authorization": "Bearer " + token}, - timeout=20, - ) - if response2.status_code != 202: - print(response2.content) - raise ValueError( - "Graph response to messages/%s/send returned something other than 202 Accepted" % response["id"], - response2, - ) - # TODO: Handle more errors - - -def main() -> None: - parser = argparse.ArgumentParser(description="Daily Bulletin Sender") - parser.add_argument( - "--date", - default=None, - help="the date of the bulletin to send, in local time, in YYYY-MM-DD; defaults to tomorrow", - ) - parser.add_argument("--config", default="config.ini", help="path to the configuration file") - args = parser.parse_args() - config = ConfigParser() - config.read(args.config) - if args.date: - date = datetime.datetime.strptime(args.date, "%Y-%m-%d").replace(tzinfo=zoneinfo.ZoneInfo(config["general"]["timezone"])) - else: - date = datetime.datetime.now(zoneinfo.ZoneInfo(config["general"]["timezone"])) + datetime.timedelta(days=1) - - os.chdir(config["general"]["build_path"]) - - html_filename = "sjdb-%s.html" % date.strftime("%Y%m%d") - with open(html_filename, "r", encoding="utf-8") as html_fd: - html = html_fd.read() - - app = msal.PublicClientApplication( - config["credentials"]["client_id"], - authority=config["credentials"]["authority"], - ) - token = acquire_token(app, config) - - common = { - "when": date.replace( - hour=int(config["sendmail"]["hour"]), - minute=int(config["sendmail"]["minute"]), - second=0, - microsecond=0, - ), - "content_type": "HTML", - "importance": "Normal", - "subject": config["sendmail"]["subject_format"] % date.strftime(config["sendmail"]["subject_date_format"]), - "body": html, - } - - sendmail( - token, - to=config["sendmail"]["to_1"].split(" "), - cc=config["sendmail"]["cc_1"].split(" "), - bcc=config["sendmail"]["bcc_1"].split(" "), - **common, # type: ignore - ) - sendmail( - token, - to=config["sendmail"]["to_2"].split(" "), - cc=config["sendmail"]["cc_2"].split(" "), - bcc=config["sendmail"]["bcc_2"].split(" "), - **common, # type: ignore - ) - - -if __name__ == "__main__": - main() diff --git a/inspire_approve.py b/sjdbmk/inspire_approve.py index 98d202c..98d202c 100755..100644 --- a/inspire_approve.py +++ b/sjdbmk/inspire_approve.py diff --git a/inspire_dl.py b/sjdbmk/inspire_dl.py index 94fd994..94fd994 100755..100644 --- a/inspire_dl.py +++ b/sjdbmk/inspire_dl.py diff --git a/legacy_wikipedia.py b/sjdbmk/legacy_wikipedia.py index 2d66b20..2d66b20 100755..100644 --- a/legacy_wikipedia.py +++ b/sjdbmk/legacy_wikipedia.py diff --git a/sendmail.py b/sjdbmk/sendmail.py index 35b1639..35b1639 100755..100644 --- a/sendmail.py +++ b/sjdbmk/sendmail.py diff --git a/serve.py b/sjdbmk/serve.py index 411a5b2..411a5b2 100755..100644 --- a/serve.py +++ b/sjdbmk/serve.py |