From e3a803b907c501fcd871248588a16876bba38595 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 13 Nov 2020 09:02:41 -0800 Subject: [PATCH] Allow import retry --- bookwyrm/goodreads_import.py | 12 ++++- bookwyrm/migrations/0010_importjob_retry.py | 18 ++++++++ bookwyrm/models/import_job.py | 11 +++++ bookwyrm/templates/import_status.html | 51 +++++++++++++++++---- bookwyrm/urls.py | 7 +-- bookwyrm/view_actions.py | 19 +++++++- 6 files changed, 103 insertions(+), 15 deletions(-) create mode 100644 bookwyrm/migrations/0010_importjob_retry.py diff --git a/bookwyrm/goodreads_import.py b/bookwyrm/goodreads_import.py index d5c0ad420..1582c37a2 100644 --- a/bookwyrm/goodreads_import.py +++ b/bookwyrm/goodreads_import.py @@ -1,6 +1,5 @@ ''' handle reading a csv from goodreads ''' import csv -from requests import HTTPError from bookwyrm import outgoing from bookwyrm.tasks import app @@ -24,6 +23,17 @@ def create_job(user, csv_file, include_reviews, privacy): ImportItem(job=job, index=index, data=entry).save() return job +def create_retry_job(user, original_job, items): + ''' retry items that didn't import ''' + job = ImportJob.objects.create( + user=user, + include_reviews=original_job.include_reviews, + privacy=original_job.privacy, + retry=True + ) + for item in items: + ImportItem(job=job, index=item.index, data=item.data).save() + return job def start_import(job): ''' initalizes a csv import job ''' diff --git a/bookwyrm/migrations/0010_importjob_retry.py b/bookwyrm/migrations/0010_importjob_retry.py new file mode 100644 index 000000000..21296cc45 --- /dev/null +++ b/bookwyrm/migrations/0010_importjob_retry.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-11-13 15:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bookwyrm', '0009_shelf_privacy'), + ] + + operations = [ + migrations.AddField( + model_name='importjob', + name='retry', + field=models.BooleanField(default=False), + ), + ] diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 891bfd1b7..3c0cfd86a 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -48,6 +48,7 @@ class ImportJob(models.Model): default='public', choices=PrivacyLevels.choices ) + retry = models.BooleanField(default=False) class ImportItem(models.Model): @@ -100,6 +101,16 @@ class ImportItem(models.Model): return None + @property + def title(self): + ''' get the book title ''' + return self.data['Title'] + + @property + def author(self): + ''' get the book title ''' + return self.data['Author'] + @property def isbn(self): ''' pulls out the isbn13 field from the csv line data ''' diff --git a/bookwyrm/templates/import_status.html b/bookwyrm/templates/import_status.html index c1dbb26e2..1c7da0036 100644 --- a/bookwyrm/templates/import_status.html +++ b/bookwyrm/templates/import_status.html @@ -29,16 +29,47 @@ {% if failed_items %}

Failed to load

- + {% if not job.retry %} +
+ {% csrf_token %} + +
    +
    + {% for item in failed_items %} +
  • + + +

    + {{ item.fail_reason }}. + Manually add book +

    +
  • + {% endfor %} +
    +
+ + {% else %} +
    + {% for item in failed_items %} +
  • +

    + Line {{ item.index }}: + {{ item.data|dict_key:'Title' }} by + {{ item.data|dict_key:'Author' }} +

    +

    + {{ item.fail_reason }}. + Manually add book +

    +
  • + {% endfor %} +
+ {% endif %} +
{% endif %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 8fa3bc1b8..1b81c601f 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -54,9 +54,9 @@ urlpatterns = [ path('', views.home), re_path(r'^(?Phome|local|federated)/?$', views.home_tab), re_path(r'^notifications/?', views.notifications_page), - re_path(r'import/?$', views.import_page), - re_path(r'import-status/(\d+)/?$', views.import_status), - re_path(r'user-edit/?$', views.edit_profile_page), + re_path(r'^import/?$', views.import_page), + re_path(r'^import-status/(\d+)/?$', views.import_status), + re_path(r'^user-edit/?$', views.edit_profile_page), # should return a ui view or activitypub json blob as requested # users @@ -98,6 +98,7 @@ urlpatterns = [ re_path(r'^edit-profile/?$', actions.edit_profile), re_path(r'^import-data/?', actions.import_data), + re_path(r'^retry-import/?', actions.retry_import), re_path(r'^resolve-book/?', actions.resolve_book), re_path(r'^edit-book/(?P\d+)/?', actions.edit_book), re_path(r'^upload-cover/(?P\d+)/?', actions.upload_cover), diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py index cf9af2a33..b7e92c89f 100644 --- a/bookwyrm/view_actions.py +++ b/bookwyrm/view_actions.py @@ -662,10 +662,27 @@ def import_data(request): except (UnicodeDecodeError, ValueError): return HttpResponseBadRequest('Not a valid csv file') goodreads_import.start_import(job) - return redirect('/import-status/%d' % (job.id,)) + return redirect('/import-status/%d' % job.id) return HttpResponseBadRequest() +@login_required +def retry_import(request): + ''' ingest a goodreads csv ''' + job = get_object_or_404(models.ImportJob, id=request.POST.get('import_job')) + items = [] + for item in request.POST.getlist('import_item'): + items.append(get_object_or_404(models.ImportItem, id=item)) + + job = goodreads_import.create_retry_job( + request.user, + job, + items, + ) + goodreads_import.start_import(job) + return redirect('/import-status/%d' % job.id) + + @login_required @permission_required('bookwyrm.create_invites', raise_exception=True) def create_invite(request):