Notify when import completes

This commit is contained in:
Mouse Reeve 2021-11-14 09:56:23 -08:00
parent 47b98ad0d9
commit f92863ad3e
6 changed files with 77 additions and 43 deletions

View file

@ -1,32 +0,0 @@
# Generated by Django 3.2.5 on 2021-11-14 17:00
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0115_importitem_linked_review'),
]
operations = [
migrations.RemoveField(
model_name='importjob',
name='complete',
),
migrations.RemoveField(
model_name='importjob',
name='task_id',
),
migrations.AddField(
model_name='importjob',
name='completed_count',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='importjob',
name='updated_date',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]

View file

@ -0,0 +1,23 @@
# Generated by Django 3.2.5 on 2021-11-14 17:34
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
("bookwyrm", "0115_importitem_linked_review"),
]
operations = [
migrations.RemoveField(
model_name="importjob",
name="task_id",
),
migrations.AddField(
model_name="importjob",
name="updated_date",
field=models.DateTimeField(default=django.utils.timezone.now),
),
]

View file

@ -38,13 +38,18 @@ class ImportJob(models.Model):
include_reviews = models.BooleanField(default=True)
mappings = models.JSONField()
updated_date = models.DateTimeField(default=timezone.now)
completed_count = models.IntegerField(default=0)
complete = models.BooleanField(default=False)
source = models.CharField(max_length=100)
privacy = models.CharField(
max_length=255, default="public", choices=PrivacyLevels.choices
)
retry = models.BooleanField(default=False)
@property
def pending_items(self):
"""items that haven't been processed yet"""
return self.items.filter(fail_reason__isnull=True, book__isnull=True)
class ImportItem(models.Model):
"""a single line of a csv being imported"""
@ -67,10 +72,13 @@ class ImportItem(models.Model):
)
def update_job(self):
"""this user is here! they are doing things!"""
self.job.completed_count += 1
self.job.updated_date = timezone.now()
self.job.save()
"""let the job know when the items get work done"""
job = self.job
job.updated_date = timezone.now()
job.save()
if not job.pending_items.exists() and not job.complete:
job.complete = True
job.save(update_fields=["complete"])
def resolve(self):
"""try various ways to lookup a book"""

View file

@ -157,9 +157,12 @@ def notify_user_on_unboost(sender, instance, *args, **kwargs):
@receiver(models.signals.post_save, sender=ImportJob)
# pylint: disable=unused-argument
def notify_user_on_import_complete(sender, instance, *args, **kwargs):
def notify_user_on_import_complete(
sender, instance, *args, update_fields=None, **kwargs
):
"""we imported your books! aren't you proud of us"""
if not instance.complete:
update_fields = update_fields or []
if not instance.complete or "complete" not in update_fields:
return
Notification.objects.create(
user=instance.user,

View file

@ -145,7 +145,40 @@ class GenericImporter(TestCase):
self.assertEqual(kwargs["queue"], "low_priority")
import_item.refresh_from_db()
self.assertEqual(import_item.book.id, self.book.id)
def test_complete_job(self, *_):
"""test notification"""
import_job = self.importer.create_job(
self.local_user, self.csv, False, "unlisted"
)
item = import_job.items[0]
item.update_job()
self.assertFalse(
models.Notification.objects.filter(
user=self.local_user,
related_import=import_job,
notification_type="IMPORT",
).exists()
)
item = import_job.items[1]
item.update_job()
self.assertFalse(
models.Notification.objects.filter(
user=self.local_user,
related_import=import_job,
notification_type="IMPORT",
).exists()
)
item = import_job.items[2]
item.update_job()
self.assertTrue(
models.Notification.objects.filter(
user=self.local_user,
related_import=import_job,
notification_type="IMPORT",
).exists()
)
def test_handle_imported_book(self, *_):
"""import added a book, this adds related connections"""

View file

@ -24,7 +24,6 @@ class ImportStatus(View):
raise PermissionDenied()
items = job.items.order_by("index")
pending_items = items.filter(fail_reason__isnull=True, book__isnull=True)
item_count = items.count() or 1
paginated = Paginator(items, PAGE_LENGTH)
@ -41,9 +40,9 @@ class ImportStatus(View):
"page_range": paginated.get_elided_page_range(
page.number, on_each_side=2, on_ends=1
),
"complete": not pending_items.exists(),
"complete": not job.pending_items.exists(),
"percent": math.floor( # pylint: disable=c-extension-no-member
(item_count - pending_items.count()) / item_count * 100
(item_count - job.pending_items.count()) / item_count * 100
),
}