cooldown period for user exports

add USER_EXPORT_COOLDOWN_HOURS setting for controlling user exports and imports
This commit is contained in:
Hugh Rundle 2023-10-22 10:49:13 +11:00
parent 20114b0059
commit 836127f369
No known key found for this signature in database
GPG key ID: A7E35779918253F9
5 changed files with 32 additions and 23 deletions

View file

@ -423,3 +423,6 @@ if HTTP_X_FORWARDED_PROTO:
# Do not change this setting unless you already have an existing # Do not change this setting unless you already have an existing
# user with the same username - in which case you should change it! # user with the same username - in which case you should change it!
INSTANCE_ACTOR_USERNAME = "bookwyrm.instance.actor" INSTANCE_ACTOR_USERNAME = "bookwyrm.instance.actor"
# exports
USER_EXPORT_COOLDOWN_HOURS = 48

View file

@ -15,28 +15,12 @@
{% endif %} {% endif %}
{% if import_size_limit and import_limit_reset %} {% if next_available %}
<div class="notification"> <div class="notification is-warning">
<p>{% blocktrans %}Currently you are allowed to import one user every {{ user_import_limit_reset }} days.{% endblocktrans %}</p> <p>{% blocktrans %}Currently you are allowed to import one user every {{ user_import_hours }} hours.{% endblocktrans %}</p>
<p>{% blocktrans %}You have {{ allowed_imports }} left.{% endblocktrans %}</p> <p>{% blocktrans %}You will next be able to import a user file at {{ next_available }}{% endblocktrans %}</p>
</div> </div>
{% endif %} {% else %}
{% if recent_avg_hours or recent_avg_minutes %}
<div class="notification">
<p>
{% 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 %}
</p>
</div>
{% endif %}
<form class="box" name="import-user" action="/user-import" method="post" enctype="multipart/form-data"> <form class="box" name="import-user" action="/user-import" method="post" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
@ -100,6 +84,7 @@
<p>{% trans "You've reached the import limit." %}</p> <p>{% trans "You've reached the import limit." %}</p>
{% endif%} {% endif%}
</form> </form>
{% endif %}
</div> </div>

View file

@ -9,6 +9,13 @@
{% block panel %} {% block panel %}
<div class="block content"> <div class="block content">
{% if next_available %}
<p class="notification is-warning">
{% blocktrans %}
You will be able to create a new export file at {{ next_available }}
{% endblocktrans %}
</p>
{% else %}
<p class="notification"> <p class="notification">
{% trans "Your exported archive file will include all user data for import into another Bookwyrm server" %} {% trans "Your exported archive file will include all user data for import into another Bookwyrm server" %}
</p> </p>
@ -19,6 +26,8 @@
<span>{% trans "Create user export file" %}</span> <span>{% trans "Create user export file" %}</span>
</button> </button>
</form> </form>
{% endif %}
</div> </div>
<div class="content block"> <div class="content block">
<h2 class="title">{% trans "Recent Exports" %}</h2> <h2 class="title">{% trans "Recent Exports" %}</h2>

View file

@ -23,7 +23,7 @@ from bookwyrm.importers import (
OpenLibraryImporter, OpenLibraryImporter,
) )
from bookwyrm.models.bookwyrm_import_job import BookwyrmImportJob from bookwyrm.models.bookwyrm_import_job import BookwyrmImportJob
from bookwyrm.settings import PAGE_LENGTH from bookwyrm.settings import PAGE_LENGTH, USER_EXPORT_COOLDOWN_HOURS
from bookwyrm.utils.cache import get_or_set from bookwyrm.utils.cache import get_or_set
# pylint: disable= no-self-use # pylint: disable= no-self-use
@ -142,11 +142,16 @@ class UserImport(View):
jobs = BookwyrmImportJob.objects.filter(user=request.user).order_by( jobs = BookwyrmImportJob.objects.filter(user=request.user).order_by(
"-created_date" "-created_date"
) )
hours = USER_EXPORT_COOLDOWN_HOURS
allowed = jobs.first().created_date < timezone.now() - datetime.timedelta(hours=hours)
next_available = jobs.first().created_date + datetime.timedelta(hours=hours) if not allowed else False
paginated = Paginator(jobs, PAGE_LENGTH) paginated = Paginator(jobs, PAGE_LENGTH)
page = paginated.get_page(request.GET.get("page")) page = paginated.get_page(request.GET.get("page"))
data = { data = {
"import_form": forms.ImportUserForm(), "import_form": forms.ImportUserForm(),
"jobs": page, "jobs": page,
"user_import_hours": hours,
"next_available": next_available,
"page_range": paginated.get_elided_page_range( "page_range": paginated.get_elided_page_range(
page.number, on_each_side=2, on_ends=1 page.number, on_each_side=2, on_ends=1
), ),

View file

@ -1,4 +1,5 @@
""" Let users export their book data """ """ Let users export their book data """
from datetime import timedelta
import csv import csv
import io import io
@ -7,11 +8,12 @@ from django.core.paginator import Paginator
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponse from django.http import HttpResponse
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.utils import timezone
from django.views import View from django.views import View
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.shortcuts import redirect from django.shortcuts import redirect
from bookwyrm import models from bookwyrm import models, settings
from bookwyrm.models.bookwyrm_export_job import BookwyrmExportJob from bookwyrm.models.bookwyrm_export_job import BookwyrmExportJob
from bookwyrm.settings import PAGE_LENGTH from bookwyrm.settings import PAGE_LENGTH
@ -101,10 +103,15 @@ class ExportUser(View):
jobs = BookwyrmExportJob.objects.filter(user=request.user).order_by( jobs = BookwyrmExportJob.objects.filter(user=request.user).order_by(
"-created_date" "-created_date"
) )
hours = settings.USER_EXPORT_COOLDOWN_HOURS
allowed = jobs.first().created_date < timezone.now() - timedelta(hours=hours)
next_available = jobs.first().created_date + timedelta(hours=hours) if not allowed else False
paginated = Paginator(jobs, PAGE_LENGTH) paginated = Paginator(jobs, PAGE_LENGTH)
page = paginated.get_page(request.GET.get("page")) page = paginated.get_page(request.GET.get("page"))
data = { data = {
"jobs": page, "jobs": page,
"next_available": next_available,
"page_range": paginated.get_elided_page_range( "page_range": paginated.get_elided_page_range(
page.number, on_each_side=2, on_ends=1 page.number, on_each_side=2, on_ends=1
), ),