From 7c7c0e1a9326672a8dce3621c410d22cf9c01caa Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 17 Nov 2022 14:22:45 -0800 Subject: [PATCH 1/3] Admin UI to enable and disable importing --- .../0166_sitesettings_imports_enabled.py | 18 +++++++ bookwyrm/models/site.py | 3 ++ .../templates/settings/imports/imports.html | 48 +++++++++++++++++++ bookwyrm/urls.py | 10 ++++ bookwyrm/views/__init__.py | 2 +- bookwyrm/views/admin/imports.py | 23 +++++++++ 6 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/migrations/0166_sitesettings_imports_enabled.py diff --git a/bookwyrm/migrations/0166_sitesettings_imports_enabled.py b/bookwyrm/migrations/0166_sitesettings_imports_enabled.py new file mode 100644 index 000000000..ccf4ef374 --- /dev/null +++ b/bookwyrm/migrations/0166_sitesettings_imports_enabled.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.16 on 2022-11-17 21:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0165_alter_inviterequest_answer"), + ] + + operations = [ + migrations.AddField( + model_name="sitesettings", + name="imports_enabled", + field=models.BooleanField(default=True), + ), + ] diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index 3c1494204..9e97ede9a 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -86,6 +86,9 @@ class SiteSettings(SiteModel): admin_email = models.EmailField(max_length=255, null=True, blank=True) footer_item = models.TextField(null=True, blank=True) + # controls + imports_enabled = models.BooleanField(default=True) + field_tracker = FieldTracker(fields=["name", "instance_tagline", "logo"]) @classmethod diff --git a/bookwyrm/templates/settings/imports/imports.html b/bookwyrm/templates/settings/imports/imports.html index c6e02f0e1..135af34ed 100644 --- a/bookwyrm/templates/settings/imports/imports.html +++ b/bookwyrm/templates/settings/imports/imports.html @@ -11,6 +11,54 @@ {% block panel %} +
+ {% if site.imports_enabled %} +
+ + + {% trans "Disable starting new imports" %} + + + +
+
+ {% trans "This is only intended to be used when things have gone very wrong with imports and you need to pause the feature while addressing issues." %} + {% trans "While imports are disabled, users will not be allowed to start new imports, but existing imports will not be effected." %} +
+ {% csrf_token %} +
+ +
+
+
+ {% else %} +
+
+ {% trans "Users are currently unable to start new imports" %} +
+ {% csrf_token %} +
+ +
+
+ {% endif %} +
+
    diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index a1e0ef844..daf05e10e 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -301,6 +301,16 @@ urlpatterns = [ views.ImportList.as_view(), name="settings-imports-complete", ), + re_path( + r"^settings/imports/disable/?$", + views.disable_imports, + name="settings-imports-disable", + ), + re_path( + r"^settings/imports/enable/?$", + views.enable_imports, + name="settings-imports-enable", + ), re_path( r"^settings/celery/?$", views.CeleryStatus.as_view(), name="settings-celery" ), diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index e5b772136..21e33450c 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -10,7 +10,7 @@ from .admin.federation import Federation, FederatedServer from .admin.federation import AddFederatedServer, ImportServerBlocklist from .admin.federation import block_server, unblock_server, refresh_server from .admin.email_blocklist import EmailBlocklist -from .admin.imports import ImportList +from .admin.imports import ImportList, disable_imports, enable_imports from .admin.ip_blocklist import IPBlocklist from .admin.invite import ManageInvites, Invite, InviteRequest from .admin.invite import ManageInviteRequests, ignore_invite_request diff --git a/bookwyrm/views/admin/imports.py b/bookwyrm/views/admin/imports.py index cdb8af751..fe04a0f2b 100644 --- a/bookwyrm/views/admin/imports.py +++ b/bookwyrm/views/admin/imports.py @@ -5,6 +5,7 @@ from django.shortcuts import get_object_or_404, redirect from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.views import View +from django.views.decorators.http import require_POST from bookwyrm import models from bookwyrm.settings import PAGE_LENGTH @@ -53,3 +54,25 @@ class ImportList(View): import_job = get_object_or_404(models.ImportJob, id=import_id) import_job.stop_job() return redirect("settings-imports") + + +@require_POST +@permission_required("bookwyrm.edit_instance_settings", raise_exception=True) +# pylint: disable=unused-argument +def disable_imports(request): + """When you just need people to please stop starting imports""" + site = models.SiteSettings.objects.get() + site.imports_enabled = False + site.save(update_fields=["imports_enabled"]) + return redirect("settings-imports") + + +@require_POST +@permission_required("bookwyrm.edit_instance_settings", raise_exception=True) +# pylint: disable=unused-argument +def enable_imports(request): + """When you just need people to please stop starting imports""" + site = models.SiteSettings.objects.get() + site.imports_enabled = True + site.save(update_fields=["imports_enabled"]) + return redirect("settings-imports") From 28567e2d8eb0ec69c100d7050e2f16e4f5ced32c Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 17 Nov 2022 15:19:42 -0800 Subject: [PATCH 2/3] Disable imports in the UI and view --- bookwyrm/templates/import/import.html | 157 ++++++++++++++------------ bookwyrm/views/imports/import_data.py | 5 + 2 files changed, 89 insertions(+), 73 deletions(-) diff --git a/bookwyrm/templates/import/import.html b/bookwyrm/templates/import/import.html index a2924703c..141e5671e 100644 --- a/bookwyrm/templates/import/import.html +++ b/bookwyrm/templates/import/import.html @@ -8,83 +8,94 @@

    {% trans "Import Books" %}

    - {% if recent_avg_hours or recent_avg_minutes %} -
    -

    - {% if recent_avg_hours %} - {% blocktrans trimmed with hours=recent_avg_hours|floatformat:0|intcomma %} - On average, recent imports have taken {{ hours }} hours. - {% endblocktrans %} - {% else %} - {% blocktrans trimmed with minutes=recent_avg_minutes|floatformat:0|intcomma %} - On average, recent imports have taken {{ minutes }} minutes. - {% endblocktrans %} + {% if site.imports_enabled %} + {% if recent_avg_hours or recent_avg_minutes %} +

    +

    + {% if recent_avg_hours %} + {% blocktrans trimmed with hours=recent_avg_hours|floatformat:0|intcomma %} + On average, recent imports have taken {{ hours }} hours. + {% endblocktrans %} + {% else %} + {% blocktrans trimmed with minutes=recent_avg_minutes|floatformat:0|intcomma %} + On average, recent imports have taken {{ minutes }} minutes. + {% endblocktrans %} + {% endif %} +

    +
    {% endif %} + +
    + {% csrf_token %} + +
    +
    +
    + + +
    + +
    + +

    + {% blocktrans trimmed %} + You can download your Goodreads data from the + Import/Export page + of your Goodreads account. + {% endblocktrans %} +

    +
    + +
    + + {{ import_form.csv_file }} +
    +
    + +
    +
    + +
    +
    + + {% include 'snippets/privacy_select.html' with no_label=True privacy_uuid="import" %} +
    +
    +
    + +
    + {% else %} +
    +

    + +

    +

    + {% trans "Imports are temporarily disabled; thank you for your patience." %}

    {% endif %} - -
    - {% csrf_token %} - -
    -
    -
    - - -
    - -
    - -

    - {% blocktrans trimmed %} - You can download your Goodreads data from the - Import/Export page - of your Goodreads account. - {% endblocktrans %} -

    -
    - -
    - - {{ import_form.csv_file }} -
    -
    - -
    -
    - -
    -
    - - {% include 'snippets/privacy_select.html' with no_label=True privacy_uuid="import" %} -
    -
    -
    - -
    diff --git a/bookwyrm/views/imports/import_data.py b/bookwyrm/views/imports/import_data.py index f9c62a15d..99fd7fc4c 100644 --- a/bookwyrm/views/imports/import_data.py +++ b/bookwyrm/views/imports/import_data.py @@ -4,6 +4,7 @@ import datetime from django.contrib.auth.decorators import login_required from django.db.models import Avg, ExpressionWrapper, F, fields +from django.core.exceptions import PermissionDenied from django.core.paginator import Paginator from django.http import HttpResponseBadRequest from django.shortcuts import redirect @@ -54,6 +55,10 @@ class Import(View): def post(self, request): """ingest a goodreads csv""" + site = models.Site.objects.get() + if not site.imports_enabled: + raise PermissionDenied() + form = forms.ImportForm(request.POST, request.FILES) if not form.is_valid(): return HttpResponseBadRequest() From 9c5fe7610b26b5fad636a433196c7c243209278c Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 17 Nov 2022 15:41:30 -0800 Subject: [PATCH 3/3] Fixes reference to site model --- bookwyrm/views/imports/import_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/views/imports/import_data.py b/bookwyrm/views/imports/import_data.py index 99fd7fc4c..4956bfb7d 100644 --- a/bookwyrm/views/imports/import_data.py +++ b/bookwyrm/views/imports/import_data.py @@ -55,7 +55,7 @@ class Import(View): def post(self, request): """ingest a goodreads csv""" - site = models.Site.objects.get() + site = models.SiteSettings.objects.get() if not site.imports_enabled: raise PermissionDenied()