Files
YYeTsBot/yyetsweb/common/utils.py

132 lines
3.9 KiB
Python
Raw Normal View History

2021-06-17 10:39:47 +08:00
#!/usr/local/bin/python3
# coding: utf-8
# YYeTsBot - utils.py
# 6/16/21 21:42
#
__author__ = "Benny <benny.think@gmail.com>"
2021-12-09 20:07:20 +08:00
import contextlib
2022-04-10 15:20:11 +08:00
import logging
2021-08-15 12:28:19 +08:00
import os
2023-02-06 22:07:51 +01:00
import pathlib
2021-08-15 12:28:19 +08:00
import smtplib
2021-06-17 10:39:47 +08:00
import time
2023-01-28 20:08:09 +01:00
from datetime import datetime
2021-08-15 12:28:19 +08:00
from email.header import Header
from email.mime.text import MIMEText
from email.utils import formataddr, parseaddr
2021-06-17 10:39:47 +08:00
2023-03-06 22:16:00 +01:00
import coloredlogs
2023-01-28 20:08:09 +01:00
import pytz
2022-04-10 15:20:11 +08:00
import requests
2021-12-09 20:07:20 +08:00
from akismet import Akismet
2023-02-06 22:07:51 +01:00
from jinja2 import Template
2023-03-06 22:16:00 +01:00
def setup_logger():
2023-03-11 11:30:58 +01:00
coloredlogs.install(
level=logging.INFO,
fmt="[%(asctime)s %(filename)s:%(lineno)d %(levelname).1s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
2021-12-09 20:07:20 +08:00
2021-06-17 10:39:47 +08:00
def ts_date(ts=None):
2023-03-19 17:35:39 +01:00
# Let's always set the timezone to CST
2023-01-28 20:08:09 +01:00
timestamp = ts or time.time()
2023-03-11 11:30:58 +01:00
return datetime.fromtimestamp(timestamp, pytz.timezone("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
2021-08-15 12:28:19 +08:00
def _format_addr(s):
name, addr = parseaddr(s)
2023-03-11 11:30:58 +01:00
return formataddr((Header(name, "utf-8").encode(), addr))
2021-08-15 12:28:19 +08:00
2023-02-06 22:07:51 +01:00
def generate_body(context):
2023-03-19 17:35:39 +01:00
template = pathlib.Path(__file__).parent.parent.joinpath("templates", "email_template.html")
2023-02-06 22:07:51 +01:00
with open(template) as f:
return Template(f.read()).render(**context)
def send_mail(to: str, subject: str, context: dict):
2021-08-15 12:28:19 +08:00
user = os.getenv("email_user")
password = os.getenv("email_password")
2023-03-07 19:27:20 +01:00
host = os.getenv("email_host", "localhost")
port = os.getenv("email_port", "1025") # mailhog
from_addr = os.getenv("from_addr", "yyets@dmesg.app")
2021-08-15 12:28:19 +08:00
2023-03-11 11:30:58 +01:00
msg = MIMEText(generate_body(context), "html", "utf-8")
msg["From"] = _format_addr("YYeTs <%s>" % from_addr)
msg["To"] = _format_addr(to)
msg["Subject"] = Header(subject, "utf-8").encode()
2021-08-15 12:28:19 +08:00
2023-02-06 22:07:51 +01:00
logging.info("logging to mail server...")
2021-08-15 12:28:19 +08:00
if port == "1025":
2021-12-09 20:07:20 +08:00
server = smtplib.SMTP(host, int(port))
2021-08-15 12:28:19 +08:00
else:
2021-12-09 20:07:20 +08:00
server = smtplib.SMTP_SSL(host, int(port))
2021-08-15 12:28:19 +08:00
server.login(user, password)
2023-02-06 22:07:51 +01:00
logging.info("sending email to %s", to)
2021-08-15 12:28:19 +08:00
server.sendmail(from_addr, [to], msg.as_string())
server.quit()
2021-12-09 20:07:20 +08:00
def check_spam(ip, ua, author, content) -> int:
# 0 means okay
token = os.getenv("askismet")
2022-01-14 20:07:29 +08:00
whitelist: "list" = os.getenv("whitelist", "").split(",")
if author in whitelist:
return 0
2021-12-09 20:07:20 +08:00
if token:
with contextlib.suppress(Exception):
akismet = Akismet(token, blog="https://yyets.dmesg.app/")
2023-03-11 11:30:58 +01:00
return akismet.check(
2023-03-19 17:35:39 +01:00
ip,
ua,
comment_author=author,
blog_lang="zh_cn",
comment_type="comment",
comment_content=content,
2023-03-11 11:30:58 +01:00
)
2021-12-09 20:07:20 +08:00
return 0
2022-09-09 18:07:55 +08:00
class Cloudflare:
def __init__(self):
self.zone_id = "b8e2d2fa75c6f7dc3c2e478e27f3061b"
self.filter_id = "9e1e9139bcbe400c8b2620ac117a77d8"
self.endpoint = f"https://api.cloudflare.com/client/v4/zones/{self.zone_id}/filters/{self.filter_id}"
self.session = requests.Session()
self.session.headers.update({"Authorization": "Bearer %s" % os.getenv("CF_TOKEN")})
def get_old_expr(self):
return self.session.get(self.endpoint).json()["result"]["expression"]
def ban_new_ip(self, ip):
2023-03-19 17:35:39 +01:00
logging.warning("Adding %s to cloudflare managed challenge list", ip)
2022-09-09 18:07:55 +08:00
expr = self.get_old_expr()
if ip not in expr:
2023-03-19 17:35:39 +01:00
body = {
"id": self.filter_id,
"paused": False,
"expression": f"{expr} or (ip.src eq {ip})",
}
2022-09-09 18:07:55 +08:00
resp = self.session.put(self.endpoint, json=body)
logging.info(resp.json())
def clear_fw(self):
logging.info("Clearing firewall rules")
2023-03-19 17:35:39 +01:00
body = {
"id": self.filter_id,
"paused": False,
"expression": "(ip.src eq 192.168.2.1)",
}
2022-09-09 18:07:55 +08:00
self.session.put(self.endpoint, json=body)
2022-04-10 15:20:11 +08:00
2023-03-11 11:30:58 +01:00
if __name__ == "__main__":
2023-02-06 22:07:51 +01:00
send_mail("benny.think@gmail.com", "主题", {"username": "test123", "text": "测试内容<b>不错</b>"})