mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-26 11:31:08 +00:00
Merge pull request #1620 from bookwyrm-social/email-reports
Email admins when a moderation report is created
This commit is contained in:
commit
f4ad1dbbdf
10 changed files with 71 additions and 21 deletions
|
@ -10,14 +10,9 @@ from bookwyrm.settings import DOMAIN
|
||||||
def email_data():
|
def email_data():
|
||||||
"""fields every email needs"""
|
"""fields every email needs"""
|
||||||
site = models.SiteSettings.objects.get()
|
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 {
|
return {
|
||||||
"site_name": site.name,
|
"site_name": site.name,
|
||||||
"logo": logo_path,
|
"logo": site.logo_small_url,
|
||||||
"domain": DOMAIN,
|
"domain": DOMAIN,
|
||||||
"user": None,
|
"user": None,
|
||||||
}
|
}
|
||||||
|
@ -46,6 +41,18 @@ def password_reset_email(reset_code):
|
||||||
send_email.delay(reset_code.user.email, *format_email("password_reset", data))
|
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):
|
def format_email(email_name, data):
|
||||||
"""render the email templates"""
|
"""render the email templates"""
|
||||||
subject = get_template(f"email/{email_name}/subject.html").render(data).strip()
|
subject = get_template(f"email/{email_name}/subject.html").render(data).strip()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
""" the particulars for this instance of BookWyrm """
|
""" the particulars for this instance of BookWyrm """
|
||||||
import datetime
|
import datetime
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
from django.db import models, IntegrityError
|
from django.db import models, IntegrityError
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
@ -7,9 +8,10 @@ from django.utils import timezone
|
||||||
from model_utils import FieldTracker
|
from model_utils import FieldTracker
|
||||||
|
|
||||||
from bookwyrm.preview_images import generate_site_preview_image_task
|
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 .base_model import BookWyrmModel, new_access_code
|
||||||
from .user import User
|
from .user import User
|
||||||
|
from .fields import get_absolute_url
|
||||||
|
|
||||||
|
|
||||||
class SiteSettings(models.Model):
|
class SiteSettings(models.Model):
|
||||||
|
@ -66,6 +68,28 @@ class SiteSettings(models.Model):
|
||||||
default_settings.save()
|
default_settings.save()
|
||||||
return default_settings
|
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):
|
class SiteInvite(models.Model):
|
||||||
"""gives someone access to create an account on the instance"""
|
"""gives someone access to create an account on the instance"""
|
||||||
|
|
|
@ -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="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="padding: 1rem; overflow: auto;">
|
||||||
<div style="float: left; margin-right: 1rem;">
|
<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>
|
||||||
<div>
|
<div>
|
||||||
<a style="color: black; text-decoration: none" href="https://{{ domain }}" style="text-decoration: none;"><strong>{{ site_name }}</strong><br>
|
<a style="color: black; text-decoration: none" href="https://{{ domain }}" style="text-decoration: none;"><strong>{{ site_name }}</strong><br>
|
||||||
|
|
11
bookwyrm/templates/email/moderation_report/html_content.html
Normal file
11
bookwyrm/templates/email/moderation_report/html_content.html
Normal 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 %}
|
2
bookwyrm/templates/email/moderation_report/subject.html
Normal file
2
bookwyrm/templates/email/moderation_report/subject.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{% load i18n %}
|
||||||
|
{% blocktrans %}New report for {{ site_name }}{% endblocktrans %}
|
|
@ -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 %}
|
|
@ -1,4 +1,4 @@
|
||||||
<html lang="{% get_lang %}">
|
<html lang="en">
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<strong>Subject:</strong> {% include subject_path %}
|
<strong>Subject:</strong> {% include subject_path %}
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.utils.decorators import method_decorator
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.views.decorators.http import require_POST
|
from django.views.decorators.http import require_POST
|
||||||
|
|
||||||
from bookwyrm import forms, models
|
from bookwyrm import emailing, forms, models
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=no-self-use
|
# pylint: disable=no-self-use
|
||||||
|
@ -142,5 +142,6 @@ def make_report(request):
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
raise ValueError(form.errors)
|
raise ValueError(form.errors)
|
||||||
|
|
||||||
form.save()
|
report = form.save()
|
||||||
|
emailing.moderation_report_email(report)
|
||||||
return redirect(request.headers.get("Referer", "/"))
|
return redirect(request.headers.get("Referer", "/"))
|
||||||
|
|
|
@ -48,4 +48,7 @@ def email_preview(request):
|
||||||
data["invite_link"] = "https://example.com/link"
|
data["invite_link"] = "https://example.com/link"
|
||||||
data["confirmation_link"] = "https://example.com/link"
|
data["confirmation_link"] = "https://example.com/link"
|
||||||
data["confirmation_code"] = "AKJHKDGKJSDFG"
|
data["confirmation_code"] = "AKJHKDGKJSDFG"
|
||||||
|
data["reporter"] = "ConcernedUser"
|
||||||
|
data["reportee"] = "UserName"
|
||||||
|
data["report_link"] = "https://example.com/link"
|
||||||
return TemplateResponse(request, "email/preview.html", data)
|
return TemplateResponse(request, "email/preview.html", data)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django.utils import timezone
|
||||||
from django.views.decorators.http import require_GET
|
from django.views.decorators.http import require_GET
|
||||||
|
|
||||||
from bookwyrm import models
|
from bookwyrm import models
|
||||||
from bookwyrm.settings import DOMAIN, VERSION, MEDIA_FULL_URL, STATIC_FULL_URL
|
from bookwyrm.settings import DOMAIN, VERSION
|
||||||
|
|
||||||
|
|
||||||
@require_GET
|
@require_GET
|
||||||
|
@ -93,7 +93,7 @@ def instance_info(_):
|
||||||
status_count = models.Status.objects.filter(user__local=True, deleted=False).count()
|
status_count = models.Status.objects.filter(user__local=True, deleted=False).count()
|
||||||
|
|
||||||
site = models.SiteSettings.get()
|
site = models.SiteSettings.get()
|
||||||
logo = get_image_url(site.logo, "logo.png")
|
logo = site.logo_url
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
{
|
{
|
||||||
"uri": DOMAIN,
|
"uri": DOMAIN,
|
||||||
|
@ -134,14 +134,7 @@ def host_meta(request):
|
||||||
def opensearch(request):
|
def opensearch(request):
|
||||||
"""Open Search xml spec"""
|
"""Open Search xml spec"""
|
||||||
site = models.SiteSettings.get()
|
site = models.SiteSettings.get()
|
||||||
image = get_image_url(site.favicon, "favicon.png")
|
image = site.favicon_url
|
||||||
return TemplateResponse(
|
return TemplateResponse(
|
||||||
request, "opensearch.xml", {"image": image, "DOMAIN": DOMAIN}
|
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}"
|
|
||||||
|
|
Loading…
Reference in a new issue