Merge pull request #1620 from bookwyrm-social/email-reports

Email admins when a moderation report is created
This commit is contained in:
Mouse Reeve 2021-11-18 15:02:39 -08:00 committed by GitHub
commit f4ad1dbbdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 71 additions and 21 deletions

View file

@ -10,14 +10,9 @@ from bookwyrm.settings import DOMAIN
def email_data():
"""fields every email needs"""
site = models.SiteSettings.objects.get()
if site.logo_small:
logo_path = f"/images/{site.logo_small.url}"
else:
logo_path = "/static/images/logo-small.png"
return {
"site_name": site.name,
"logo": logo_path,
"logo": site.logo_small_url,
"domain": DOMAIN,
"user": None,
}
@ -46,6 +41,18 @@ def password_reset_email(reset_code):
send_email.delay(reset_code.user.email, *format_email("password_reset", data))
def moderation_report_email(report):
"""a report was created"""
data = email_data()
data["reporter"] = report.reporter.localname or report.reporter.username
data["reportee"] = report.user.localname or report.user.username
data["report_link"] = report.remote_id
for admin in models.User.objects.filter(groups__name="moderator"):
data["user"] = admin.display_name
send_email.delay(admin.email, *format_email("moderation_report", data))
def format_email(email_name, data):
"""render the email templates"""
subject = get_template(f"email/{email_name}/subject.html").render(data).strip()

View file

@ -1,5 +1,6 @@
""" the particulars for this instance of BookWyrm """
import datetime
from urllib.parse import urljoin
from django.db import models, IntegrityError
from django.dispatch import receiver
@ -7,9 +8,10 @@ from django.utils import timezone
from model_utils import FieldTracker
from bookwyrm.preview_images import generate_site_preview_image_task
from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES
from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES, STATIC_FULL_URL
from .base_model import BookWyrmModel, new_access_code
from .user import User
from .fields import get_absolute_url
class SiteSettings(models.Model):
@ -66,6 +68,28 @@ class SiteSettings(models.Model):
default_settings.save()
return default_settings
@property
def logo_url(self):
"""helper to build the logo url"""
return self.get_url("logo", "images/logo.png")
@property
def logo_small_url(self):
"""helper to build the logo url"""
return self.get_url("logo_small", "images/logo-small.png")
@property
def favicon_url(self):
"""helper to build the logo url"""
return self.get_url("favicon", "images/favicon.png")
def get_url(self, field, default_path):
"""get a media url or a default static path"""
uploaded = getattr(self, field, None)
if uploaded:
return get_absolute_url(uploaded)
return urljoin(STATIC_FULL_URL, default_path)
class SiteInvite(models.Model):
"""gives someone access to create an account on the instance"""

View file

@ -2,7 +2,7 @@
<div style="font-family: BlinkMacSystemFont,-apple-system,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Fira Sans','Droid Sans','Helvetica Neue',Helvetica,Arial,sans-serif; border-radius: 6px; background-color: #efefef; max-width: 632px;">
<div style="padding: 1rem; overflow: auto;">
<div style="float: left; margin-right: 1rem;">
<a style="color: #3273dc;" href="https://{{ domain }}" style="text-decoration: none;"><img src="https://{{ domain }}/{{ logo }}" alt="logo"></a>
<a style="color: #3273dc;" href="https://{{ domain }}" style="text-decoration: none;"><img src="{{ logo }}" alt="logo"></a>
</div>
<div>
<a style="color: black; text-decoration: none" href="https://{{ domain }}" style="text-decoration: none;"><strong>{{ site_name }}</strong><br>

View file

@ -0,0 +1,11 @@
{% extends 'email/html_layout.html' %}
{% load i18n %}
{% block content %}
<p>
{% blocktrans %}@{{ reporter }} has flagged behavior by @{{ reportee }} for moderation. {% endblocktrans %}
</p>
{% trans "View report" as text %}
{% include 'email/snippets/action.html' with path=report_link text=text %}
{% endblock %}

View file

@ -0,0 +1,2 @@
{% load i18n %}
{% blocktrans %}New report for {{ site_name }}{% endblocktrans %}

View file

@ -0,0 +1,9 @@
{% extends 'email/text_layout.html' %}
{% load i18n %}
{% block content %}
{% blocktrans %}@{{ reporter}} has flagged behavior by @{{ reportee }} for moderation. {% endblocktrans %}
{% trans "View report" %}
{{ report_link }}
{% endblock %}

View file

@ -1,4 +1,4 @@
<html lang="{% get_lang %}">
<html lang="en">
<body>
<div>
<strong>Subject:</strong> {% include subject_path %}

View file

@ -7,7 +7,7 @@ from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.http import require_POST
from bookwyrm import forms, models
from bookwyrm import emailing, forms, models
# pylint: disable=no-self-use
@ -142,5 +142,6 @@ def make_report(request):
if not form.is_valid():
raise ValueError(form.errors)
form.save()
report = form.save()
emailing.moderation_report_email(report)
return redirect(request.headers.get("Referer", "/"))

View file

@ -48,4 +48,7 @@ def email_preview(request):
data["invite_link"] = "https://example.com/link"
data["confirmation_link"] = "https://example.com/link"
data["confirmation_code"] = "AKJHKDGKJSDFG"
data["reporter"] = "ConcernedUser"
data["reportee"] = "UserName"
data["report_link"] = "https://example.com/link"
return TemplateResponse(request, "email/preview.html", data)

View file

@ -9,7 +9,7 @@ from django.utils import timezone
from django.views.decorators.http import require_GET
from bookwyrm import models
from bookwyrm.settings import DOMAIN, VERSION, MEDIA_FULL_URL, STATIC_FULL_URL
from bookwyrm.settings import DOMAIN, VERSION
@require_GET
@ -93,7 +93,7 @@ def instance_info(_):
status_count = models.Status.objects.filter(user__local=True, deleted=False).count()
site = models.SiteSettings.get()
logo = get_image_url(site.logo, "logo.png")
logo = site.logo_url
return JsonResponse(
{
"uri": DOMAIN,
@ -134,14 +134,7 @@ def host_meta(request):
def opensearch(request):
"""Open Search xml spec"""
site = models.SiteSettings.get()
image = get_image_url(site.favicon, "favicon.png")
image = site.favicon_url
return TemplateResponse(
request, "opensearch.xml", {"image": image, "DOMAIN": DOMAIN}
)
def get_image_url(obj, fallback):
"""helper for loading the full path to an image"""
if obj:
return f"{MEDIA_FULL_URL}{obj}"
return f"{STATIC_FULL_URL}images/{fallback}"