1
0
Fork 0

Implement self-contained archives to import and export entire users between instances (#38)

Co-authored-by: Daniel Burgess <developerdannymate@gmail.com>
Co-authored-by: Hugh Rundle <hugh@hughrundle.net>
Co-authored-by: dannymate <dannymate@noreply.codeberg.org>
Co-authored-by: hughrun <hughrun@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/GuildAlpha/bookwyrm/pulls/38
Co-authored-by: CSDUMMI <csdummi.misquality@simplelogin.co>
Co-committed-by: CSDUMMI <csdummi.misquality@simplelogin.co>
This commit is contained in:
Joris Gutjahr 2023-09-05 22:35:26 +00:00
parent bc870a305f
commit 688978369f
25 changed files with 2819 additions and 7 deletions

View file

@ -36,7 +36,7 @@ from .admin.user_admin import UserAdmin, UserAdminList, ActivateUserAdmin
# user preferences
from .preferences.change_password import ChangePassword
from .preferences.edit_user import EditUser
from .preferences.export import Export
from .preferences.export import Export, ExportUser, ExportArchive
from .preferences.delete_user import DeleteUser, DeactivateUser, ReactivateUser
from .preferences.block import Block, unblock
from .preferences.two_factor_auth import (
@ -80,7 +80,7 @@ from .shelf.shelf_actions import create_shelf, delete_shelf
from .shelf.shelf_actions import shelve, unshelve
# csv import
from .imports.import_data import Import
from .imports.import_data import Import, UserImport
from .imports.import_status import ImportStatus, retry_item, stop_import
from .imports.troubleshoot import ImportTroubleshoot
from .imports.manually_review import (

View file

@ -15,12 +15,14 @@ from django.views import View
from bookwyrm import forms, models
from bookwyrm.importers import (
BookwyrmImporter,
CalibreImporter,
LibrarythingImporter,
GoodreadsImporter,
StorygraphImporter,
OpenLibraryImporter,
)
from bookwyrm.models.bookwyrm_import_job import BookwyrmImportJob
from bookwyrm.settings import PAGE_LENGTH
from bookwyrm.utils.cache import get_or_set
@ -127,3 +129,47 @@ def get_average_import_time() -> float:
if recent_avg:
return recent_avg.total_seconds()
return None
# pylint: disable= no-self-use
@method_decorator(login_required, name="dispatch")
class UserImport(View):
"""import user view"""
def get(self, request, invalid=False):
"""load user import page"""
jobs = BookwyrmImportJob.objects.filter(user=request.user).order_by(
"-created_date"
)
paginated = Paginator(jobs, PAGE_LENGTH)
page = paginated.get_page(request.GET.get("page"))
data = {
"import_form": forms.ImportUserForm(),
"jobs": page,
"page_range": paginated.get_elided_page_range(
page.number, on_each_side=2, on_ends=1
),
"invalid": invalid,
}
return TemplateResponse(request, "import/import_user.html", data)
def post(self, request):
"""ingest a Bookwyrm json file"""
importer = BookwyrmImporter()
form = forms.ImportUserForm(request.POST, request.FILES)
if not form.is_valid():
return HttpResponseBadRequest()
job = importer.process_import(
user=request.user,
archive_file=request.FILES["archive_file"],
settings=request.POST,
)
job.start_job()
return redirect("user-import")

View file

@ -3,13 +3,17 @@ import csv
import io
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models import Q
from django.http import HttpResponse
from django.template.response import TemplateResponse
from django.views import View
from django.utils.decorators import method_decorator
from django.shortcuts import redirect
from bookwyrm import models
from bookwyrm.models.bookwyrm_export_job import BookwyrmExportJob
from bookwyrm.settings import PAGE_LENGTH
# pylint: disable=no-self-use
@method_decorator(login_required, name="dispatch")
@ -84,3 +88,49 @@ class Export(View):
"Content-Disposition": 'attachment; filename="bookwyrm-export.csv"'
},
)
# pylint: disable=no-self-use
@method_decorator(login_required, name="dispatch")
class ExportUser(View):
"""Let users export user data to import into another Bookwyrm instance"""
def get(self, request):
"""Request tar file"""
jobs = BookwyrmExportJob.objects.filter(user=request.user).order_by(
"-created_date"
)
paginated = Paginator(jobs, PAGE_LENGTH)
page = paginated.get_page(request.GET.get("page"))
data = {
"jobs": page,
"page_range": paginated.get_elided_page_range(
page.number, on_each_side=2, on_ends=1
),
}
return TemplateResponse(request, "preferences/export-user.html", data)
def post(self, request):
"""Download the json file of a user's data"""
job = BookwyrmExportJob.objects.create(user=request.user)
job.start_job()
return redirect("prefs-user-export")
@method_decorator(login_required, name="dispatch")
class ExportArchive(View):
"""Serve the archive file"""
def get(self, request, archive_id):
export = BookwyrmExportJob.objects.get(task_id=archive_id, user=request.user)
return HttpResponse(
export.export_data,
content_type="application/gzip",
headers={
"Content-Disposition": 'attachment; filename="bookwyrm-account-export.tar.gz"'
},
)