Skip to content

Commit

Permalink
Merge pull request #3054 from bookwyrm-social/user-migration
Browse files Browse the repository at this point in the history
User migration via export file
  • Loading branch information
mouse-reeve authored Jan 2, 2024
2 parents 5647477 + 1649457 commit ca79cb1
Show file tree
Hide file tree
Showing 37 changed files with 3,549 additions and 214 deletions.
4 changes: 4 additions & 0 deletions bookwyrm/forms/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class ImportForm(forms.Form):
csv_file = forms.FileField()


class ImportUserForm(forms.Form):
archive_file = forms.FileField()


class ShelfForm(CustomForm):
class Meta:
model = models.Shelf
Expand Down
1 change: 1 addition & 0 deletions bookwyrm/importers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
""" import classes """

from .importer import Importer
from .bookwyrm_import import BookwyrmImporter
from .calibre_import import CalibreImporter
from .goodreads_import import GoodreadsImporter
from .librarything_import import LibrarythingImporter
Expand Down
24 changes: 24 additions & 0 deletions bookwyrm/importers/bookwyrm_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Import data from Bookwyrm export files"""
from django.http import QueryDict

from bookwyrm.models import User
from bookwyrm.models.bookwyrm_import_job import BookwyrmImportJob


class BookwyrmImporter:
"""Import a Bookwyrm User export file.
This is kind of a combination of an importer and a connector.
"""

# pylint: disable=no-self-use
def process_import(
self, user: User, archive_file: bytes, settings: QueryDict
) -> BookwyrmImportJob:
"""import user data from a Bookwyrm export file"""

required = [k for k in settings if settings.get(k) == "on"]

job = BookwyrmImportJob.objects.create(
user=user, archive_file=archive_file, required=required
)
return job
212 changes: 212 additions & 0 deletions bookwyrm/migrations/0186_auto_20231116_0048.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# Generated by Django 3.2.20 on 2023-11-16 00:48

from django.conf import settings
import django.contrib.postgres.fields
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
("bookwyrm", "0185_alter_notification_notification_type"),
]

operations = [
migrations.CreateModel(
name="ParentJob",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("task_id", models.UUIDField(blank=True, null=True, unique=True)),
(
"created_date",
models.DateTimeField(default=django.utils.timezone.now),
),
(
"updated_date",
models.DateTimeField(default=django.utils.timezone.now),
),
("complete", models.BooleanField(default=False)),
(
"status",
models.CharField(
choices=[
("pending", "Pending"),
("active", "Active"),
("complete", "Complete"),
("stopped", "Stopped"),
("failed", "Failed"),
],
default="pending",
max_length=50,
null=True,
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"abstract": False,
},
),
migrations.AddField(
model_name="sitesettings",
name="user_import_time_limit",
field=models.IntegerField(default=48),
),
migrations.AlterField(
model_name="notification",
name="notification_type",
field=models.CharField(
choices=[
("FAVORITE", "Favorite"),
("BOOST", "Boost"),
("REPLY", "Reply"),
("MENTION", "Mention"),
("TAG", "Tag"),
("FOLLOW", "Follow"),
("FOLLOW_REQUEST", "Follow Request"),
("IMPORT", "Import"),
("USER_IMPORT", "User Import"),
("USER_EXPORT", "User Export"),
("ADD", "Add"),
("REPORT", "Report"),
("LINK_DOMAIN", "Link Domain"),
("INVITE", "Invite"),
("ACCEPT", "Accept"),
("JOIN", "Join"),
("LEAVE", "Leave"),
("REMOVE", "Remove"),
("GROUP_PRIVACY", "Group Privacy"),
("GROUP_NAME", "Group Name"),
("GROUP_DESCRIPTION", "Group Description"),
("MOVE", "Move"),
],
max_length=255,
),
),
migrations.CreateModel(
name="BookwyrmExportJob",
fields=[
(
"parentjob_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="bookwyrm.parentjob",
),
),
("export_data", models.FileField(null=True, upload_to="")),
],
options={
"abstract": False,
},
bases=("bookwyrm.parentjob",),
),
migrations.CreateModel(
name="BookwyrmImportJob",
fields=[
(
"parentjob_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="bookwyrm.parentjob",
),
),
("archive_file", models.FileField(blank=True, null=True, upload_to="")),
("import_data", models.JSONField(null=True)),
(
"required",
django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(blank=True, max_length=50),
blank=True,
size=None,
),
),
],
options={
"abstract": False,
},
bases=("bookwyrm.parentjob",),
),
migrations.CreateModel(
name="ChildJob",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("task_id", models.UUIDField(blank=True, null=True, unique=True)),
(
"created_date",
models.DateTimeField(default=django.utils.timezone.now),
),
(
"updated_date",
models.DateTimeField(default=django.utils.timezone.now),
),
("complete", models.BooleanField(default=False)),
(
"status",
models.CharField(
choices=[
("pending", "Pending"),
("active", "Active"),
("complete", "Complete"),
("stopped", "Stopped"),
("failed", "Failed"),
],
default="pending",
max_length=50,
null=True,
),
),
(
"parent_job",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="child_jobs",
to="bookwyrm.parentjob",
),
),
],
options={
"abstract": False,
},
),
migrations.AddField(
model_name="notification",
name="related_user_export",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="bookwyrm.bookwyrmexportjob",
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 3.2.23 on 2023-11-22 10:16

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("bookwyrm", "0186_auto_20231116_0048"),
("bookwyrm", "0188_theme_loads"),
]

operations = []
45 changes: 45 additions & 0 deletions bookwyrm/migrations/0190_alter_notification_notification_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Generated by Django 3.2.23 on 2023-11-23 19:49

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("bookwyrm", "0189_merge_0186_auto_20231116_0048_0188_theme_loads"),
]

operations = [
migrations.AlterField(
model_name="notification",
name="notification_type",
field=models.CharField(
choices=[
("FAVORITE", "Favorite"),
("BOOST", "Boost"),
("REPLY", "Reply"),
("MENTION", "Mention"),
("TAG", "Tag"),
("FOLLOW", "Follow"),
("FOLLOW_REQUEST", "Follow Request"),
("IMPORT", "Import"),
("USER_IMPORT", "User Import"),
("USER_EXPORT", "User Export"),
("ADD", "Add"),
("REPORT", "Report"),
("LINK_DOMAIN", "Link Domain"),
("INVITE_REQUEST", "Invite Request"),
("INVITE", "Invite"),
("ACCEPT", "Accept"),
("JOIN", "Join"),
("LEAVE", "Leave"),
("REMOVE", "Remove"),
("GROUP_PRIVACY", "Group Privacy"),
("GROUP_NAME", "Group Name"),
("GROUP_DESCRIPTION", "Group Description"),
("MOVE", "Move"),
],
max_length=255,
),
),
]
2 changes: 2 additions & 0 deletions bookwyrm/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
from .group import Group, GroupMember, GroupMemberInvitation

from .import_job import ImportJob, ImportItem
from .bookwyrm_import_job import BookwyrmImportJob
from .bookwyrm_export_job import BookwyrmExportJob

from .move import MoveUser

Expand Down
Loading

0 comments on commit ca79cb1

Please sign in to comment.