Comment system for Hugo
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
4.2 KiB

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# /**********************************************************************************
# * _author : Domeniko Gentner
# * _mail :
# * _repo :
# * _license : This project is under MIT License
# *********************************************************************************/
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from json import load as j_load
from pathlib import Path
from platform import system
from smtplib import SMTP_SSL, SMTPHeloError, SMTPAuthenticationError, SMTPException
from ssl import create_default_context
from validate_email import validate_email_or_fail
from secrets import token_urlsafe
from labertasche.models import TProjects
from labertasche.database import labertasche_db as db
from labertasche.settings import Settings
from flask import render_template
class mail:
def __init__(self):
path = Path("/etc/labertasche/mail_credentials.json")
if system().lower() == "windows":
path = Path("mail_credentials.json")
with"r") as fp:
self.credentials = j_load(fp)
def send(self, txt_what: str, html_what: str, to: str):
if not self.credentials['enable']:
txtmail = MIMEText(txt_what, "plain", _charset='utf8')
multimime = MIMEMultipart('alternative')
multimime['Subject'] = "Comment confirmation pending"
multimime['From'] = self.credentials['email-sendfrom']
multimime['To'] = to
# Only send HTML if needed
if html_what is not None:
htmlmail = MIMEText(html_what, "html", _charset='utf8')
with SMTP_SSL(host=self.credentials['smtp-server'],
context=create_default_context()) as server:
server.login(user=self.credentials['email-user'], password=self.credentials['email-password'])
except SMTPHeloError as helo:
print(f"SMTPHeloError: {helo}")
except SMTPAuthenticationError as auth_error:
print(f"Authentication Error: {auth_error}")
except SMTPException as e:
print(f"SMTPException: {e}")
def send_confirmation_link(self, email: str, name: str) -> tuple:
Send confirmation link after entering a comment
:param email: The address to send the mail to
:param name: The name of the project
:return: A tuple with the confirmation token and the deletion token, in this order
project = db.session.query(TProjects).filter( == name).first()
if not project:
return None, None
settings = Settings()
confirm_digest = token_urlsafe(48)
delete_digest = token_urlsafe(48)
confirm_url = f"{settings.weburl}/comments/{}/confirm/{confirm_digest}"
delete_url = f"{settings.weburl}/comments/{}/delete/{delete_digest}"
txt_what = f"Hey there. You have made a comment on {project.blogurl}. Please confirm it by " \
f"copying this link into your browser:\n{confirm_url}\n" \
f"If you want to delete your comment for whatever reason, please use this link:\n{delete_url}"
html_what = render_template("comment_confirmation.html",
self.send(txt_what, html_what, email)
return confirm_digest, delete_digest
def validate(self, addr):
# validate email
is_valid = validate_email_or_fail(email_address=addr, check_regex=True, check_mx=False,
dns_timeout=10, use_blacklist=True, debug=False)
return is_valid