From c4b8e7949d661c0e6d6a4d78d83e7712c82f037a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 30 Jan 2022 11:41:06 -0800 Subject: [PATCH 001/105] Add more book identifier fields --- bookwyrm/activitypub/book.py | 1 + .../migrations/0132_auto_20220130_1938.py | 42 +++++++++++++++++++ bookwyrm/models/book.py | 6 +++ 3 files changed, 49 insertions(+) create mode 100644 bookwyrm/migrations/0132_auto_20220130_1938.py diff --git a/bookwyrm/activitypub/book.py b/bookwyrm/activitypub/book.py index 2238e3a87..7401a1346 100644 --- a/bookwyrm/activitypub/book.py +++ b/bookwyrm/activitypub/book.py @@ -16,6 +16,7 @@ class BookData(ActivityObject): librarythingKey: str = None goodreadsKey: str = None bnfId: str = None + viaf: str = None lastEditedBy: str = None links: List[str] = field(default_factory=lambda: []) fileLinks: List[str] = field(default_factory=lambda: []) diff --git a/bookwyrm/migrations/0132_auto_20220130_1938.py b/bookwyrm/migrations/0132_auto_20220130_1938.py new file mode 100644 index 000000000..a83ac2909 --- /dev/null +++ b/bookwyrm/migrations/0132_auto_20220130_1938.py @@ -0,0 +1,42 @@ +# Generated by Django 3.2.10 on 2022-01-30 19:38 + +import bookwyrm.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0131_merge_20220125_1644"), + ] + + operations = [ + migrations.AddField( + model_name="author", + name="viaf", + field=bookwyrm.models.fields.CharField( + blank=True, max_length=255, null=True + ), + ), + migrations.AddField( + model_name="author", + name="wikidata", + field=bookwyrm.models.fields.CharField( + blank=True, max_length=255, null=True + ), + ), + migrations.AddField( + model_name="book", + name="viaf", + field=bookwyrm.models.fields.CharField( + blank=True, max_length=255, null=True + ), + ), + migrations.AddField( + model_name="book", + name="wikidata", + field=bookwyrm.models.fields.CharField( + blank=True, max_length=255, null=True + ), + ), + ] diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index ffc03d3e6..c796b7d24 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -46,6 +46,12 @@ class BookDataModel(ObjectMixin, BookWyrmModel): bnf_id = fields.CharField( # Bibliothèque nationale de France max_length=255, blank=True, null=True, deduplication_field=True ) + viaf = fields.CharField( + max_length=255, blank=True, null=True, deduplication_field=True + ) + wikidata = fields.CharField( + max_length=255, blank=True, null=True, deduplication_field=True + ) search_vector = SearchVectorField(null=True) last_edited_by = fields.ForeignKey( From 44dad43f366ed6a014fdbcc4f86913e2765e16d1 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 30 Jan 2022 11:41:33 -0800 Subject: [PATCH 002/105] Load new fields via connector --- bookwyrm/connectors/openlibrary.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index c15277f84..5a94a16c1 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -68,7 +68,26 @@ class Connector(AbstractConnector): Mapping("born", remote_field="birth_date"), Mapping("died", remote_field="death_date"), Mapping("bio", formatter=get_description), - Mapping("isni", remote_field="remote_ids", formatter=get_isni), + Mapping( + "isni", + remote_field="remote_ids", + formatter=lambda b: get_dict_field(b, "isni"), + ), + Mapping( + "asin", + remote_field="remote_ids", + formatter=lambda b: get_dict_field(b, "amazon"), + ), + Mapping( + "viaf", + remote_field="remote_ids", + formatter=lambda b: get_dict_field(b, "viaf"), + ), + Mapping( + "wikidata", + remote_field="remote_ids", + formatter=lambda b: get_dict_field(b, "wikidata"), + ), ] def get_book_data(self, remote_id): @@ -227,11 +246,11 @@ def get_languages(language_blob): return langs -def get_isni(remote_ids_blob): +def get_dict_field(blob, field_name): """extract the isni from the remote id data for the author""" - if not remote_ids_blob or not isinstance(remote_ids_blob, dict): + if not blob or not isinstance(blob, dict): return None - return remote_ids_blob.get("isni") + return blob.get(field_name) def pick_default_edition(options): From 9611815b44267682bd482ec8ce8b6f5069aa10e4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 30 Jan 2022 12:02:18 -0800 Subject: [PATCH 003/105] Extract wikipedia and inventaire ids --- bookwyrm/connectors/openlibrary.py | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index 5a94a16c1..118222a16 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -88,6 +88,10 @@ class Connector(AbstractConnector): remote_field="remote_ids", formatter=lambda b: get_dict_field(b, "wikidata"), ), + Mapping( + "wikipedia_link", remote_field="links", formatter=get_wikipedia_link + ), + Mapping("inventaire_id", remote_field="links", formatter=get_inventaire_id), ] def get_book_data(self, remote_id): @@ -253,6 +257,33 @@ def get_dict_field(blob, field_name): return blob.get(field_name) +def get_wikipedia_link(links): + """extract wikipedia links""" + if not isinstance(links, list): + return None + + for link in links: + if not isinstance(link, dict): + continue + if link.get("title") == "wikipedia": + return link.get("url") + return None + + +def get_inventaire_id(links): + """extract and format inventaire ids""" + if not isinstance(links, list): + return None + + for link in links: + if not isinstance(link, dict): + continue + if link.get("title") == "inventaire.io": + iv_link = link.get("url") + return iv_link.split("/")[-1] + return None + + def pick_default_edition(options): """favor physical copies with covers in english""" if not options: From 7811a9920e27ac2be5d3d8e6e9676603f875ffaf Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 4 Feb 2022 18:34:17 -0800 Subject: [PATCH 004/105] Copy config from prod branch to main --- .env.example | 16 ++++++++++++++ bookwyrm/apps.py | 5 +++++ bookwyrm/management/commands/erase_streams.py | 1 + bookwyrm/settings.py | 4 ++++ bookwyrm/telemetry/open_telemetry.py | 22 +++++++++++++++++++ celerywyrm/apps.py | 13 +++++++++++ certbot.sh | 19 ---------------- docker-compose.yml | 10 ++++----- requirements.txt | 5 +++++ 9 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 bookwyrm/telemetry/open_telemetry.py create mode 100644 celerywyrm/apps.py delete mode 100644 certbot.sh diff --git a/.env.example b/.env.example index ca6f65bb7..7769a67b1 100644 --- a/.env.example +++ b/.env.example @@ -89,3 +89,19 @@ PREVIEW_TEXT_COLOR=#363636 PREVIEW_IMG_WIDTH=1200 PREVIEW_IMG_HEIGHT=630 PREVIEW_DEFAULT_COVER_COLOR=#002549 + +# Below are example keys if you want to enable automatically +# sending telemetry to an OTLP-compatible service. Many of +# the main monitoring apps have OLTP collectors, including +# NewRelic, DataDog, and Honeycomb.io - consult their +# documentation for setup instructions, and what exactly to +# put below! +# +# Service name is an arbitrary tag that is attached to any +# data sent, used to distinguish different sources. Useful +# for sending prod and dev metrics to the same place and +# keeping them separate, for instance! + +OTEL_EXPORTER_OTLP_ENDPOINT= # API endpoint for your provider +OTEL_EXPORTER_OTLP_HEADERS= # Any headers required, usually authentication info +OTEL_SERVICE_NAME= # Service name to identify your app diff --git a/bookwyrm/apps.py b/bookwyrm/apps.py index 8940edccc..af3b064e9 100644 --- a/bookwyrm/apps.py +++ b/bookwyrm/apps.py @@ -33,6 +33,11 @@ class BookwyrmConfig(AppConfig): verbose_name = "BookWyrm" def ready(self): + if settings.OTEL_EXPORTER_OTLP_ENDPOINT: + from bookwyrm.telemetry import open_telemetry + + open_telemetry.instrumentDjango() + if settings.ENABLE_PREVIEW_IMAGES and settings.FONTS: # Download any fonts that we don't have yet logger.debug("Downloading fonts..") diff --git a/bookwyrm/management/commands/erase_streams.py b/bookwyrm/management/commands/erase_streams.py index 7b8074029..9d971d699 100644 --- a/bookwyrm/management/commands/erase_streams.py +++ b/bookwyrm/management/commands/erase_streams.py @@ -7,6 +7,7 @@ from bookwyrm import settings r = redis.Redis( host=settings.REDIS_ACTIVITY_HOST, port=settings.REDIS_ACTIVITY_PORT, + password=settings.REDIS_ACTIVITY_PASSWORD, db=settings.REDIS_ACTIVITY_DB_INDEX, ) diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index e8cbe344b..e9f3d0585 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -333,3 +333,7 @@ else: MEDIA_URL = "/images/" MEDIA_FULL_URL = f"{PROTOCOL}://{DOMAIN}{MEDIA_URL}" STATIC_FULL_URL = f"{PROTOCOL}://{DOMAIN}{STATIC_URL}" + +OTEL_EXPORTER_OTLP_ENDPOINT = env("OTEL_EXPORTER_OTLP_ENDPOINT", None) +OTEL_EXPORTER_OTLP_HEADERS = env("OTEL_EXPORTER_OTLP_HEADERS", None) +OTEL_SERVICE_NAME = env("OTEL_SERVICE_NAME", None) diff --git a/bookwyrm/telemetry/open_telemetry.py b/bookwyrm/telemetry/open_telemetry.py new file mode 100644 index 000000000..0b38a04b1 --- /dev/null +++ b/bookwyrm/telemetry/open_telemetry.py @@ -0,0 +1,22 @@ +from opentelemetry import trace +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor + +trace.set_tracer_provider(TracerProvider()) +trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(OTLPSpanExporter())) + + +def instrumentDjango(): + from opentelemetry.instrumentation.django import DjangoInstrumentor + + DjangoInstrumentor().instrument() + + +def instrumentCelery(): + from opentelemetry.instrumentation.celery import CeleryInstrumentor + from celery.signals import worker_process_init + + @worker_process_init.connect(weak=False) + def init_celery_tracing(*args, **kwargs): + CeleryInstrumentor().instrument() diff --git a/celerywyrm/apps.py b/celerywyrm/apps.py new file mode 100644 index 000000000..6aae849cd --- /dev/null +++ b/celerywyrm/apps.py @@ -0,0 +1,13 @@ +from django.apps import AppConfig +from celerywyrm import settings + + +class CelerywyrmConfig(AppConfig): + name = "celerywyrm" + verbose_name = "BookWyrm Celery" + + def ready(self): + if settings.OTEL_EXPORTER_OTLP_ENDPOINT: + from bookwyrm.telemetry import open_telemetry + + open_telemetry.instrumentCelery() diff --git a/certbot.sh b/certbot.sh deleted file mode 100644 index 6d2c3cd90..000000000 --- a/certbot.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash -source .env; - -if [ "$CERTBOT_INIT" = "true" ] -then - certonly \ - --webroot \ - --webroot-path=/var/www/certbot \ - --email ${EMAIL} \ - --agree-tos \ - --no-eff-email \ - -d ${DOMAIN} \ - -d www.${DOMAIN} -else - renew \ - --webroot \ - --webroot-path \ - /var/www/certbot -fi diff --git a/docker-compose.yml b/docker-compose.yml index fa28dbee6..d3b47467c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -49,15 +49,13 @@ services: redis_broker: image: redis command: redis-server --requirepass ${REDIS_BROKER_PASSWORD} --appendonly yes --port ${REDIS_BROKER_PORT} - env_file: .env - ports: - - 6379 - networks: - - main - restart: on-failure volumes: - ./redis.conf:/etc/redis/redis.conf - redis_broker_data:/data + env_file: .env + networks: + - main + restart: on-failure celery_worker: env_file: .env build: . diff --git a/requirements.txt b/requirements.txt index 4bda6bd5a..638ed91b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,6 +18,11 @@ pytz>=2021.1 boto3==1.17.88 django-storages==1.11.1 django-redis==5.2.0 +opentelemetry-api==1.8.0 +opentelemetry-sdk==1.8.0 +opentelemetry-exporter-otlp-proto-grpc==1.8.0 +opentelemetry-instrumentation-django==0.27b0 +opentelemetry-instrumentation-celery==0.27b0 # Dev black==21.4b2 From bc7aa91b97d7bf89feb3787c731ab76b1bd65e9d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 4 Feb 2022 18:50:57 -0800 Subject: [PATCH 005/105] Fixes pylint complaints --- bookwyrm/apps.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bookwyrm/apps.py b/bookwyrm/apps.py index af3b064e9..d494877d6 100644 --- a/bookwyrm/apps.py +++ b/bookwyrm/apps.py @@ -32,8 +32,11 @@ class BookwyrmConfig(AppConfig): name = "bookwyrm" verbose_name = "BookWyrm" + # pylint: disable=no-self-use def ready(self): + """set up OTLP and preview image files, if desired""" if settings.OTEL_EXPORTER_OTLP_ENDPOINT: + # pylint: disable=import-outside-toplevel from bookwyrm.telemetry import open_telemetry open_telemetry.instrumentDjango() From 74fd13fb22e60913f376c9c2bdc34db69a086d53 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 6 Feb 2022 06:37:03 -0800 Subject: [PATCH 006/105] Consistent ordering of items in docker-compose file --- docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index d3b47467c..672ea4c1a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,13 +39,13 @@ services: redis_activity: image: redis command: redis-server --requirepass ${REDIS_ACTIVITY_PASSWORD} --appendonly yes --port ${REDIS_ACTIVITY_PORT} + volumes: + - ./redis.conf:/etc/redis/redis.conf + - redis_activity_data:/data env_file: .env networks: - main restart: on-failure - volumes: - - ./redis.conf:/etc/redis/redis.conf - - redis_activity_data:/data redis_broker: image: redis command: redis-server --requirepass ${REDIS_BROKER_PASSWORD} --appendonly yes --port ${REDIS_BROKER_PORT} From e9e4f70ae4ff11329be0e5dc667f39bcd2941201 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 8 Feb 2022 09:17:42 -0500 Subject: [PATCH 007/105] Refresh web and celery in update command --- bw-dev | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bw-dev b/bw-dev index 11977ad07..ded796b84 100755 --- a/bw-dev +++ b/bw-dev @@ -143,6 +143,8 @@ case "$CMD" in runweb python manage.py migrate runweb python manage.py collectstatic --no-input docker-compose up -d + docker-compose restart web + docker-compose restart celery_worker ;; populate_streams) runweb python manage.py populate_streams "$@" From 6323b0e7005218c35a88f28d3067af8227347f61 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 9 Feb 2022 12:20:11 -0500 Subject: [PATCH 008/105] Use correct model type for federated links --- bookwyrm/activitypub/base_activity.py | 4 ++-- bookwyrm/tests/views/books/test_links.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index 15ca5a938..7d2796eff 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -227,7 +227,7 @@ def set_related_field( model_field = getattr(model, related_field_name) if hasattr(model_field, "activitypub_field"): setattr(activity, getattr(model_field, "activitypub_field"), instance.remote_id) - item = activity.to_model() + item = activity.to_model(model=model) # if the related field isn't serialized (attachments on Status), then # we have to set it post-creation @@ -298,6 +298,7 @@ class Link(ActivityObject): mediaType: str = None id: str = None attributedTo: str = None + availability: str = None type: str = "Link" def serialize(self, **kwargs): @@ -305,7 +306,6 @@ class Link(ActivityObject): omit = ("id", "type", "@context") return super().serialize(omit=omit) - @dataclass(init=False) class Mention(Link): """a subtype of Link for mentioning an actor""" diff --git a/bookwyrm/tests/views/books/test_links.py b/bookwyrm/tests/views/books/test_links.py index 2aee5aed9..d98e95dae 100644 --- a/bookwyrm/tests/views/books/test_links.py +++ b/bookwyrm/tests/views/books/test_links.py @@ -80,6 +80,17 @@ class LinkViews(TestCase): activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Update") self.assertEqual(activity["object"]["type"], "Edition") + self.assertIsInstance(activity["object"]["fileLinks"], list) + self.assertEqual( + activity["object"]["fileLinks"][0]["href"], "https://www.example.com" + ) + self.assertEqual( + activity["object"]["fileLinks"][0]["mediaType"], "HTML" + ) + self.assertEqual( + activity["object"]["fileLinks"][0]["attributedTo"], + self.local_user.remote_id + ) link = models.FileLink.objects.get() self.assertEqual(link.name, "www.example.com") From c06817e9ff8212c7bf5de413a4b4470aeed842f4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 9 Feb 2022 12:23:01 -0500 Subject: [PATCH 009/105] Python formatting --- bookwyrm/activitypub/base_activity.py | 1 + bookwyrm/tests/models/test_book_model.py | 1 - bookwyrm/tests/views/books/test_links.py | 6 ++---- bookwyrm/tests/views/inbox/test_inbox_update.py | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index 7d2796eff..6bee25f62 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -306,6 +306,7 @@ class Link(ActivityObject): omit = ("id", "type", "@context") return super().serialize(omit=omit) + @dataclass(init=False) class Mention(Link): """a subtype of Link for mentioning an actor""" diff --git a/bookwyrm/tests/models/test_book_model.py b/bookwyrm/tests/models/test_book_model.py index d74fa4ca3..d4f59fa58 100644 --- a/bookwyrm/tests/models/test_book_model.py +++ b/bookwyrm/tests/models/test_book_model.py @@ -1,7 +1,6 @@ """ testing models """ from dateutil.parser import parse -from imagekit.models import ImageSpecField from django.test import TestCase from django.utils import timezone diff --git a/bookwyrm/tests/views/books/test_links.py b/bookwyrm/tests/views/books/test_links.py index d98e95dae..3379786b0 100644 --- a/bookwyrm/tests/views/books/test_links.py +++ b/bookwyrm/tests/views/books/test_links.py @@ -84,12 +84,10 @@ class LinkViews(TestCase): self.assertEqual( activity["object"]["fileLinks"][0]["href"], "https://www.example.com" ) - self.assertEqual( - activity["object"]["fileLinks"][0]["mediaType"], "HTML" - ) + self.assertEqual(activity["object"]["fileLinks"][0]["mediaType"], "HTML") self.assertEqual( activity["object"]["fileLinks"][0]["attributedTo"], - self.local_user.remote_id + self.local_user.remote_id, ) link = models.FileLink.objects.get() diff --git a/bookwyrm/tests/views/inbox/test_inbox_update.py b/bookwyrm/tests/views/inbox/test_inbox_update.py index 963742c83..18b2e5d59 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_update.py +++ b/bookwyrm/tests/views/inbox/test_inbox_update.py @@ -6,7 +6,6 @@ from unittest.mock import patch from django.test import TestCase from bookwyrm import models, views -from bookwyrm.activitypub.base_activity import set_related_field # pylint: disable=too-many-public-methods From 046f51609123799aa4fd90196053f8fded836af1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Feb 2022 13:02:16 +0000 Subject: [PATCH 010/105] Bump django from 3.2.11 to 3.2.12 Bumps [django](https://github.com/django/django) from 3.2.11 to 3.2.12. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.11...3.2.12) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4bda6bd5a..191a6a92a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ celery==5.2.2 colorthief==0.2.1 -Django==3.2.11 +Django==3.2.12 django-imagekit==4.1.0 django-model-utils==4.0.0 environs==9.3.4 From 059fd84d06a3af1e385e1b0490803d158c4ad7ec Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 11 Feb 2022 13:33:42 -0500 Subject: [PATCH 011/105] Adds delete button to announcements list view It's handy to have it there --- .../settings/announcements/announcements.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bookwyrm/templates/settings/announcements/announcements.html b/bookwyrm/templates/settings/announcements/announcements.html index c86ecf3e8..d60ef3761 100644 --- a/bookwyrm/templates/settings/announcements/announcements.html +++ b/bookwyrm/templates/settings/announcements/announcements.html @@ -38,6 +38,9 @@ {% trans "Status" as text %} {% include 'snippets/table-sort-header.html' with field="active" sort=sort text=text %} + + {% trans "Actions" %} + {% for announcement in announcements %} @@ -46,6 +49,15 @@ {{ announcement.start_date|naturaltime|default:'' }} {{ announcement.end_date|naturaltime|default:'' }} {% if announcement.active %}{% trans "active" %}{% else %}{% trans "inactive" %}{% endif %} + +
+ {% csrf_token %} + +
+ {% endfor %} {% if not announcements %} From 62741a5d2e9a9872ccca2cff349f9f50035a28e2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 11 Feb 2022 13:36:08 -0500 Subject: [PATCH 012/105] Allow html in announcement header --- bookwyrm/templates/snippets/announcement.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/templates/snippets/announcement.html b/bookwyrm/templates/snippets/announcement.html index 8b8563191..62dd4ea78 100644 --- a/bookwyrm/templates/snippets/announcement.html +++ b/bookwyrm/templates/snippets/announcement.html @@ -9,7 +9,7 @@ {% if announcement.event_date %} {{ announcement.event_date|naturalday|title }}: {% endif %} - {{ announcement.preview }} + {{ announcement.preview|safe }} {% if announcement.content %}
From ee23aba9946361dc391891510d5f411ebc617299 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 11 Feb 2022 13:50:55 -0500 Subject: [PATCH 013/105] Use details and summary for announcement panel --- bookwyrm/static/css/bookwyrm.css | 4 +-- bookwyrm/templates/snippets/announcement.html | 29 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/bookwyrm/static/css/bookwyrm.css b/bookwyrm/static/css/bookwyrm.css index f05ea3c91..669493877 100644 --- a/bookwyrm/static/css/bookwyrm.css +++ b/bookwyrm/static/css/bookwyrm.css @@ -319,7 +319,7 @@ details.details-panel summary { position: relative; } -details.details-panel summary .details-close { +details summary .details-close { position: absolute; right: 0; top: 0; @@ -327,7 +327,7 @@ details.details-panel summary .details-close { transition: transform 0.2s ease; } -details[open].details-panel summary .details-close { +details[open] summary .details-close { transform: rotate(0deg); } diff --git a/bookwyrm/templates/snippets/announcement.html b/bookwyrm/templates/snippets/announcement.html index 62dd4ea78..c8eca6ad1 100644 --- a/bookwyrm/templates/snippets/announcement.html +++ b/bookwyrm/templates/snippets/announcement.html @@ -4,29 +4,26 @@ class="notification mb-1 p-3{% if not admin_mode %} is-hidden{% endif %} transition-y" {% if not admin_mode %}data-hide="hide_announcement_{{ announcement.id }}"{% endif %} > -
-
+
+ {% if announcement.event_date %} {{ announcement.event_date|naturalday|title }}: {% endif %} + {{ announcement.preview|safe }} -
+ + {% if announcement.content %} + + {% endif %} + {% if announcement.content %} -
- {% trans "Open" as button_text %} - {% include 'snippets/toggle/open_button.html' with text=button_text controls_text="announcement" class="is-small" controls_uid=uuid icon_with_text="arrow-down" %} - {% trans "Close" as button_text %} - {% include 'snippets/toggle/close_button.html' with text=button_text controls_text="announcement" class="is-small" controls_uid=uuid icon_with_text="arrow-up" %} +
+
+ {{ announcement.content|safe }} +
{% endif %} -
- {% if announcement.content %} -
-
- {{ announcement.content|safe }} -
-
- {% endif %} +

{% blocktrans with user_path=announcement.user.local_path username=announcement.user.display_name %}Posted by {{ username }}{% endblocktrans %}

{% if not admin_mode %} From cfa91e25704d8a0c73a6648761824e734458e6be Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 11 Feb 2022 14:00:01 -0500 Subject: [PATCH 014/105] Adds color options to announcements --- .../0134_announcement_display_type.py | 29 +++++++++++++++++++ bookwyrm/models/announcement.py | 18 ++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 bookwyrm/migrations/0134_announcement_display_type.py diff --git a/bookwyrm/migrations/0134_announcement_display_type.py b/bookwyrm/migrations/0134_announcement_display_type.py new file mode 100644 index 000000000..ba8450123 --- /dev/null +++ b/bookwyrm/migrations/0134_announcement_display_type.py @@ -0,0 +1,29 @@ +# Generated by Django 3.2.11 on 2022-02-11 18:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0133_alter_listitem_notes"), + ] + + operations = [ + migrations.AddField( + model_name="announcement", + name="display_type", + field=models.CharField( + choices=[ + ("white-ter", "None"), + ("primary-light", "Primary"), + ("success-light", "Success"), + ("link-light", "Link"), + ("warning-light", "Warning"), + ("danger-light", "Danger"), + ], + default="white-ter", + max_length=20, + ), + ), + ] diff --git a/bookwyrm/models/announcement.py b/bookwyrm/models/announcement.py index 498d50418..cbed38aee 100644 --- a/bookwyrm/models/announcement.py +++ b/bookwyrm/models/announcement.py @@ -2,10 +2,21 @@ from django.db import models from django.db.models import Q from django.utils import timezone +from django.utils.translation import gettext_lazy as _ from .base_model import BookWyrmModel +DisplayTypes = [ + ("white-ter", _("None")), + ("primary-light", _("Primary")), + ("success-light", _("Success")), + ("link-light", _("Link")), + ("warning-light", _("Warning")), + ("danger-light", _("Danger")), +] + + class Announcement(BookWyrmModel): """The admin has something to say""" @@ -16,6 +27,13 @@ class Announcement(BookWyrmModel): start_date = models.DateTimeField(blank=True, null=True) end_date = models.DateTimeField(blank=True, null=True) active = models.BooleanField(default=True) + display_type = models.CharField( + max_length=20, + blank=False, + null=False, + choices=DisplayTypes, + default="white-ter", + ) @classmethod def active_announcements(cls): From 01b52f023a19e20dd1c2af63a844c48de1d64eff Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 11 Feb 2022 14:38:13 -0500 Subject: [PATCH 015/105] Adds edit announcement view --- .../settings/announcements/announcement.html | 14 +-- .../announcements/announcement_form.html | 80 ------------- .../settings/announcements/announcements.html | 13 +-- .../announcements/edit_announcement.html | 105 ++++++++++++++++++ bookwyrm/urls.py | 10 ++ bookwyrm/views/__init__.py | 3 +- bookwyrm/views/admin/announcements.py | 62 ++++++----- 7 files changed, 165 insertions(+), 122 deletions(-) delete mode 100644 bookwyrm/templates/settings/announcements/announcement_form.html create mode 100644 bookwyrm/templates/settings/announcements/edit_announcement.html diff --git a/bookwyrm/templates/settings/announcements/announcement.html b/bookwyrm/templates/settings/announcements/announcement.html index 8b49f4f48..095013822 100644 --- a/bookwyrm/templates/settings/announcements/announcement.html +++ b/bookwyrm/templates/settings/announcements/announcement.html @@ -1,5 +1,7 @@ {% extends 'settings/layout.html' %} -{% load i18n %}{% load humanize %} +{% load i18n %} +{% load humanize %} + {% block title %}{% trans "Announcement" %} - {{ announcement.preview }}{% endblock %} {% block header %} @@ -8,10 +10,12 @@ {% endblock %} {% block edit-button %} -{% trans "Edit Announcement" as button_text %}
- {% include 'snippets/toggle/open_button.html' with controls_text="edit_announcement" icon_with_text="pencil" text=button_text focus="edit_announcement_header" %} + + + {% trans "Edit Announcement" %} +
{% csrf_token %} @@ -25,10 +29,6 @@ {% block panel %} - - {% include 'settings/announcements/announcement_form.html' with controls_text="edit_announcement" %} -
-
{% trans "Visible:" %}
diff --git a/bookwyrm/templates/settings/announcements/announcement_form.html b/bookwyrm/templates/settings/announcements/announcement_form.html deleted file mode 100644 index 8f68e2555..000000000 --- a/bookwyrm/templates/settings/announcements/announcement_form.html +++ /dev/null @@ -1,80 +0,0 @@ -{% extends 'components/inline_form.html' %} -{% load i18n %} - -{% block header %} -{% if announcement %} -{% trans "Edit Announcement" %} -{% else %} -{% trans "Create Announcement" %} -{% endif %} -{% endblock %} - -{% block form %} -{% csrf_token %} - -

- - {{ form.preview }} - - {% include 'snippets/form_errors.html' with errors_list=form.preview.errors id="desc_preview" %} -

-

- - {{ form.content }} - - {% include 'snippets/form_errors.html' with errors_list=form.content.errors id="desc_content" %} -

-

- - - - {% include 'snippets/form_errors.html' with errors_list=form.event_date.errors id="desc_event_date" %} -

- -
-
-

- - - - {% include 'snippets/form_errors.html' with errors_list=form.start_date.errors id="desc_start_date" %} -

-
-
-

- - - - {% include 'snippets/form_errors.html' with errors_list=form.end_date.errors id="desc_end_date" %} -

-
-
-

- - {{ form.active }} - - {% include 'snippets/form_errors.html' with errors_list=form.active.errors id="desc_active" %} -

-
-
- -
-
- -
-
-{% endblock %} diff --git a/bookwyrm/templates/settings/announcements/announcements.html b/bookwyrm/templates/settings/announcements/announcements.html index d60ef3761..6299ba3d9 100644 --- a/bookwyrm/templates/settings/announcements/announcements.html +++ b/bookwyrm/templates/settings/announcements/announcements.html @@ -5,16 +5,15 @@ {% block header %}{% trans "Announcements" %}{% endblock %} {% block edit-button %} -{% trans "Create Announcement" as button_text %} -{% include 'snippets/toggle/open_button.html' with controls_text="create_announcement" icon_with_text="plus" text=button_text focus="create_announcement_header" %} + + {% trans "Create Announcement" as text %} + + {{ text }} + {% endblock %} {% block panel %} -
- {% include 'settings/announcements/announcement_form.html' with controls_text="create_announcement" %} -
- -
+
From 1aa6b99d1fb49e691fae925f491fe4643795bd1f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 24 Feb 2022 17:33:05 -0800 Subject: [PATCH 102/105] Adds tests --- bookwyrm/tests/models/test_automod.py | 75 ++++++++++++++++++++++ bookwyrm/tests/views/admin/test_automod.py | 58 +++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 bookwyrm/tests/models/test_automod.py create mode 100644 bookwyrm/tests/views/admin/test_automod.py diff --git a/bookwyrm/tests/models/test_automod.py b/bookwyrm/tests/models/test_automod.py new file mode 100644 index 000000000..abb9aa559 --- /dev/null +++ b/bookwyrm/tests/models/test_automod.py @@ -0,0 +1,75 @@ +""" test for app action functionality """ +from unittest.mock import patch + +from django.test import TestCase +from django.test.client import RequestFactory + +from bookwyrm import models +from bookwyrm.models.antispam import automod_task + + +@patch("bookwyrm.models.Status.broadcast") +@patch("bookwyrm.activitystreams.add_status_task.delay") +@patch("bookwyrm.activitystreams.remove_status_task.delay") +class AutomodModel(TestCase): + """every response to a get request, html or json""" + + def setUp(self): + """we need basic test data and mocks""" + self.factory = RequestFactory() + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ), patch("bookwyrm.lists_stream.populate_lists_task.delay"): + self.local_user = models.User.objects.create_user( + "mouse@local.com", + "mouse@mouse.mouse", + "password", + local=True, + localname="mouse", + ) + + def test_automod_task_no_rules(self, *_): + """nothing to see here""" + self.assertFalse(models.Report.objects.exists()) + automod_task() + self.assertFalse(models.Report.objects.exists()) + + def test_automod_task_user(self, *_): + """scan activity""" + self.assertFalse(models.Report.objects.exists()) + models.AutoMod.objects.create( + string_match="hi", + flag_users=True, + flag_statuses=True, + created_by=self.local_user, + ) + + self.local_user.name = "okay hi" + self.local_user.save(broadcast=False, update_fields=["name"]) + + automod_task() + + reports = models.Report.objects.all() + self.assertEqual(reports.count(), 1) + self.assertEqual(reports.first().user, self.local_user) + + def test_automod_status(self, *_): + """scan activity""" + self.assertFalse(models.Report.objects.exists()) + models.AutoMod.objects.create( + string_match="hi", + flag_users=True, + flag_statuses=True, + created_by=self.local_user, + ) + + status = models.Status.objects.create( + user=self.local_user, content="hello", content_warning="hi" + ) + + automod_task() + + reports = models.Report.objects.all() + self.assertEqual(reports.count(), 1) + self.assertEqual(reports.first().status, status) + self.assertEqual(reports.first().user, self.local_user) diff --git a/bookwyrm/tests/views/admin/test_automod.py b/bookwyrm/tests/views/admin/test_automod.py new file mode 100644 index 000000000..1ed36caf5 --- /dev/null +++ b/bookwyrm/tests/views/admin/test_automod.py @@ -0,0 +1,58 @@ +""" test for app action functionality """ +from unittest.mock import patch + +from django.template.response import TemplateResponse +from django.test import TestCase +from django.test.client import RequestFactory + +from bookwyrm import forms, models, views +from bookwyrm.tests.validate_html import validate_html + + +class AutomodViews(TestCase): + """every response to a get request, html or json""" + + def setUp(self): + """we need basic test data and mocks""" + self.factory = RequestFactory() + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ), patch("bookwyrm.lists_stream.populate_lists_task.delay"): + self.local_user = models.User.objects.create_user( + "mouse@local.com", + "mouse@mouse.mouse", + "password", + local=True, + localname="mouse", + ) + models.SiteSettings.objects.create() + + def test_automod_rules_get(self): + """there are so many views, this just makes sure it LOADS""" + view = views.AutoMod.as_view() + request = self.factory.get("") + request.user = self.local_user + request.user.is_superuser = True + + result = view(request) + self.assertIsInstance(result, TemplateResponse) + validate_html(result.render()) + self.assertEqual(result.status_code, 200) + + def test_automod_rules_post(self): + """there are so many views, this just makes sure it LOADS""" + form = forms.AutoModRuleForm() + form.data["string_match"] = "hello" + form.data["flag_users"] = True + form.data["flag_statuses"] = False + form.data["created_by"] = self.local_user + + view = views.AutoMod.as_view() + request = self.factory.post("", form.data) + request.user = self.local_user + request.user.is_superuser = True + + result = view(request) + self.assertIsInstance(result, TemplateResponse) + validate_html(result.render()) + self.assertEqual(result.status_code, 200) From eb8b9fdaed85ee56743f6a6c2352a0e3a3af6e7f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 24 Feb 2022 17:33:22 -0800 Subject: [PATCH 103/105] Fixes bugs in model task --- bookwyrm/models/antispam.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/bookwyrm/models/antispam.py b/bookwyrm/models/antispam.py index 4632c64ee..b894ade77 100644 --- a/bookwyrm/models/antispam.py +++ b/bookwyrm/models/antispam.py @@ -84,19 +84,17 @@ def automod_users(reporter): user_rules = AutoMod.objects.filter(flag_users=True).values_list( "string_match", flat=True ) + if not user_rules: + return [] filters = [] for field in ["username", "summary", "name"]: filters += [{f"{field}__icontains": r} for r in user_rules] - users = ( - User.objects.filter( - reduce(operator.or_, (Q(**f) for f in filters)), - is_active=True, - report__isnull=True, # don't flag users that already have reports - ) - .distinct() - .values_list("id", flat=True) - ) + users = User.objects.filter( + reduce(operator.or_, (Q(**f) for f in filters)), + is_active=True, + report__isnull=True, # don't flag users that already have reports + ).distinct() report_model = apps.get_model("bookwyrm", "Report", require_ready=True) @@ -118,6 +116,9 @@ def automod_statuses(reporter): "string_match", flat=True ) + if not status_rules: + return [] + filters = [] for field in ["content", "content_warning", "quotation__quote", "review__name"]: filters += [{f"{field}__icontains": r} for r in status_rules] From 84ef214ca16ab46fb6585b67a02071cfcfe06b28 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 24 Feb 2022 17:34:02 -0800 Subject: [PATCH 104/105] Valid template markup --- .../templates/settings/automod/rules.html | 141 +++++++++++------- 1 file changed, 88 insertions(+), 53 deletions(-) diff --git a/bookwyrm/templates/settings/automod/rules.html b/bookwyrm/templates/settings/automod/rules.html index 78b88ebad..5585dfde5 100644 --- a/bookwyrm/templates/settings/automod/rules.html +++ b/bookwyrm/templates/settings/automod/rules.html @@ -33,63 +33,98 @@ {% endif %} -
-
diff --git a/bookwyrm/templates/settings/announcements/edit_announcement.html b/bookwyrm/templates/settings/announcements/edit_announcement.html new file mode 100644 index 000000000..ef10c2a02 --- /dev/null +++ b/bookwyrm/templates/settings/announcements/edit_announcement.html @@ -0,0 +1,105 @@ +{% extends 'settings/layout.html' %} +{% load i18n %} + +{% block header %} +{% if announcement %} +{% trans "Edit Announcement" %} +{% else %} +{% trans "Create Announcement" %} +{% endif %} +{% endblock %} + +{% block panel %} +
+ {% csrf_token %} + +

{% trans "Announcement content" %}

+
+

+ + {{ form.preview }} + + {% include 'snippets/form_errors.html' with errors_list=form.preview.errors id="desc_preview" %} +

+

+ + {{ form.content }} + + {% include 'snippets/form_errors.html' with errors_list=form.content.errors id="desc_content" %} +

+

+ + + + {% include 'snippets/form_errors.html' with errors_list=form.event_date.errors id="desc_event_date" %} +

+
+ +

{% trans "Display settings" %}

+
+
+
+

+ + + + {% include 'snippets/form_errors.html' with errors_list=form.start_date.errors id="desc_start_date" %} +

+
+
+

+ + + + {% include 'snippets/form_errors.html' with errors_list=form.end_date.errors id="desc_end_date" %} +

+
+
+ +
+ {{ form.display_type }} +
+ + {% include 'snippets/form_errors.html' with errors_list=form.active.errors id="desc_display_type" %} +
+
+

+ + + {% include 'snippets/form_errors.html' with errors_list=form.active.errors id="desc_active" %} +

+
+ +
+
+ +
+
+
+{% endblock %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 79d868c95..5ee09a3a4 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -93,6 +93,16 @@ urlpatterns = [ views.Announcement.as_view(), name="settings-announcements", ), + re_path( + r"^settings/announcements/create/?$", + views.EditAnnouncement.as_view(), + name="settings-announcements-edit", + ), + re_path( + r"^settings/announcements/(?P\d+)/edit/?$", + views.EditAnnouncement.as_view(), + name="settings-announcements-edit", + ), re_path( r"^settings/announcements/(?P\d+)/delete/?$", views.delete_announcement, diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 359bee827..579e89cbc 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -1,6 +1,7 @@ """ make sure all our nice views are available """ # site admin -from .admin.announcements import Announcements, Announcement, delete_announcement +from .admin.announcements import Announcements, Announcement +from .admin.announcements import EditAnnouncement, delete_announcement from .admin.dashboard import Dashboard from .admin.federation import Federation, FederatedServer from .admin.federation import AddFederatedServer, ImportServerBlocklist diff --git a/bookwyrm/views/admin/announcements.py b/bookwyrm/views/admin/announcements.py index 92ec1766c..dd0ce862f 100644 --- a/bookwyrm/views/admin/announcements.py +++ b/bookwyrm/views/admin/announcements.py @@ -45,23 +45,6 @@ class Announcements(View): request, "settings/announcements/announcements.html", data ) - def post(self, request): - """edit the site settings""" - form = forms.AnnouncementForm(request.POST) - if form.is_valid(): - form.save() - # reset the create form - form = forms.AnnouncementForm() - data = { - "announcements": Paginator( - models.Announcement.objects.order_by("-created_date"), PAGE_LENGTH - ).get_page(request.GET.get("page")), - "form": form, - } - return TemplateResponse( - request, "settings/announcements/announcements.html", data - ) - @method_decorator(login_required, name="dispatch") @method_decorator( @@ -76,27 +59,52 @@ class Announcement(View): announcement = get_object_or_404(models.Announcement, id=announcement_id) data = { "announcement": announcement, - "form": forms.AnnouncementForm(instance=announcement), } return TemplateResponse( request, "settings/announcements/announcement.html", data ) - def post(self, request, announcement_id): - """edit announcement""" - announcement = get_object_or_404(models.Announcement, id=announcement_id) - form = forms.AnnouncementForm(request.POST, instance=announcement) - if form.is_valid(): - announcement = form.save() - form = forms.AnnouncementForm(instance=announcement) + + +@method_decorator(login_required, name="dispatch") +@method_decorator( + permission_required("bookwyrm.edit_instance_settings", raise_exception=True), + name="dispatch", +) +class EditAnnouncement(View): + """Create of edit an announcement""" + def get(self, request, announcement_id=None): + """announcement forms""" + announcement = None + if announcement_id: + announcement = get_object_or_404(models.Announcement, id=announcement_id) + data = { "announcement": announcement, - "form": form, + "form": forms.AnnouncementForm(instance=announcement), } return TemplateResponse( - request, "settings/announcements/announcement.html", data + request, "settings/announcements/edit_announcement.html", data ) + def post(self, request, announcement_id=None): + """edit announcement""" + announcement = None + if announcement_id: + announcement = get_object_or_404(models.Announcement, id=announcement_id) + + form = forms.AnnouncementForm(request.POST, instance=announcement) + if not form.is_valid(): + data = { + "announcement": announcement, + "form": form, + } + return TemplateResponse( + request, "settings/announcements/edit_announcement.html", data + ) + announcement = form.save() + return redirect("settings-announcements", announcement.id) + @login_required @permission_required("bookwyrm.edit_instance_settings", raise_exception=True) From b95f0ed287a9f3dcd25932060c79e3e9d4b0bd36 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 11 Feb 2022 14:43:37 -0500 Subject: [PATCH 016/105] Use color in announcement --- bookwyrm/templates/snippets/announcement.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/templates/snippets/announcement.html b/bookwyrm/templates/snippets/announcement.html index c8eca6ad1..ec1555d8f 100644 --- a/bookwyrm/templates/snippets/announcement.html +++ b/bookwyrm/templates/snippets/announcement.html @@ -1,7 +1,7 @@ {% load humanize %}{% load i18n %}{% load utilities %} {% with announcement.id|uuid as uuid %}
- +
+
+

{% trans "Add Rule" %}

+
{% csrf_token %} -
- - - - - - - - - - - + +
+
+
+ + {{ form.string_match }} + {% include 'snippets/form_errors.html' with errors_list=form.string_match.errors id="desc_string_match" %} +
+
+ +
+
+ +
+ +
+ +
+
+
+ +
+ +
- {% for rule in rules %} - - - - - - - {% endfor %} -
- - - - - - -
- {{ form.string_match }} - {% include 'snippets/form_errors.html' with errors_list=form.string_match.errors id="desc_string_match" %} - - {{ form.flag_users }} - - {{ form.flag_statuses }} - - -
- {{ rule.string_match }} - - {{ rule.flag_users|yesno }} - - {{ rule.flag_statuses|yesno }} - -
- {% csrf_token %} - -
-
+
+
+ +
+

{% trans "Current Rules" %}

+
+ + + {% trans "Show rules" %} ({{ rules.count }}) + + + + +
+ + + + + + + + {% for rule in rules %} + + + + + + + {% endfor %} +
+ + + + + + +
+ {{ rule.string_match }} + + {{ rule.flag_users|yesno }} + + {{ rule.flag_statuses|yesno }} + +
+ {% csrf_token %} +
+ +
+
+
+
+
{% endblock %} From 689be8c94bcfd13c0a2ab4640c70b795cdfce4fb Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 24 Feb 2022 17:42:28 -0800 Subject: [PATCH 105/105] Only scan local data --- bookwyrm/models/antispam.py | 2 ++ bookwyrm/templates/settings/automod/rules.html | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bookwyrm/models/antispam.py b/bookwyrm/models/antispam.py index b894ade77..f506b6f19 100644 --- a/bookwyrm/models/antispam.py +++ b/bookwyrm/models/antispam.py @@ -93,6 +93,7 @@ def automod_users(reporter): users = User.objects.filter( reduce(operator.or_, (Q(**f) for f in filters)), is_active=True, + local=True, report__isnull=True, # don't flag users that already have reports ).distinct() @@ -127,6 +128,7 @@ def automod_statuses(reporter): statuses = status_model.objects.filter( reduce(operator.or_, (Q(**f) for f in filters)), deleted=False, + local=True, report__isnull=True, # don't flag statuses that already have reports ).distinct() diff --git a/bookwyrm/templates/settings/automod/rules.html b/bookwyrm/templates/settings/automod/rules.html index 5585dfde5..8205b3d71 100644 --- a/bookwyrm/templates/settings/automod/rules.html +++ b/bookwyrm/templates/settings/automod/rules.html @@ -14,7 +14,7 @@

- {% trans "Auto-moderation rules will create reports for any user or status with fields matching the provided string." %} + {% trans "Auto-moderation rules will create reports for any local user or status with fields matching the provided string." %} {% trans "Users or statuses that have already been reported (regardless of whether the report was resolved) will not be flagged." %} {% trans "At this time, reports are not being generated automatically, and you must manually trigger a scan." %}