fixes for bookwyrm csv import

- fix tests
- revert change to GenericImporter tests
- import the review name
- add extra properties to ImportItem
This commit is contained in:
Hugh Rundle 2024-08-10 16:37:30 +10:00
parent 8aba8caae9
commit 7fc54c509c
No known key found for this signature in database
GPG key ID: A7E35779918253F9
6 changed files with 55 additions and 30 deletions

View file

@ -29,10 +29,11 @@ class BookwyrmBooksImporter(Importer):
"""
Handle reading a csv from BookWyrm.
Goodreads is the default importer, we basically just use the same structure
But BookWyrm has a shelf.id (shelf) and a shelf.name (shelf_name)
But BookWyrm has additional attributes in the csv
"""
service = "BookWyrm"
row_mappings_guesses = Importer.row_mappings_guesses + [
("shelf_name", ["shelf_name"]),
("review_published", ["review_published"]),
]

View file

@ -45,6 +45,7 @@ class Importer:
"reading": ["currently-reading", "reading", "currently reading"],
}
# pylint: disable=too-many-arguments
def create_job(
self,
user: User,

View file

@ -257,6 +257,16 @@ class ImportItem(models.Model):
"""a user-written review, to be imported with the book data"""
return self.normalized_data.get("review_body")
@property
def review_name(self):
"""a user-written review name, to be imported with the book data"""
return self.normalized_data.get("review_name")
@property
def review_published(self):
"""date the review was published - included in BookWyrm export csv"""
return self.normalized_data.get("review_published", None)
@property
def rating(self):
"""x/5 star rating for a book"""
@ -435,17 +445,23 @@ def handle_imported_book(item): # pylint: disable=too-many-branches
if job.include_reviews and (item.rating or item.review) and not item.linked_review:
# we don't necessarily know the publication date of the review,
# but "now" is a bad guess unless we have no choice
published_date_guess = item.date_read or item.date_added or timezone.now()
published_date_guess = (
item.review_published or item.date_read or item.date_added or timezone.now()
)
if item.review:
# pylint: disable=consider-using-f-string
review_title = "Review of {!r} on {!r}".format(
item.book.title,
job.source,
)
review_name = getattr(item, "review_name", review_title)
review = Review.objects.filter(
user=user,
book=item.book,
name=review_title,
name=review_name,
rating=item.rating,
published_date=published_date_guess,
).first()
@ -453,7 +469,7 @@ def handle_imported_book(item): # pylint: disable=too-many-branches
review = Review(
user=user,
book=item.book,
name=review_title,
name=review_name,
content=item.review,
rating=item.rating,
published_date=published_date_guess,

View file

@ -1,4 +1,4 @@
title,author_text,remote_id,openlibrary_key,inventaire_id,librarything_key,goodreads_key,bnf_id,viaf,wikidata,asin,aasin,isfdb,isbn_10,isbn_13,oclc_number,start_date,finish_date,stopped_date,rating,review_name,review_cw,review_content,review_published,shelf,shelf_name,shelf_date
Gideon the Ninth (The Locked Tomb #1),Tamsyn Muir,https://example.com/book2,,,,,,,,,,,1250313198,9781250313195,,2020-10-21,2020-10-25,,3,,,,,read,Read,2020-10-21
Subcutanean,Aaron A. Reed,https://example.com/book3,,,,,,,,,,,,,,2020-03-05,2020-03-06,,0,,,,,read,Read,2020-03-05
Patisserie at Home,Mélanie Dupuis,https://example.com/book4,,,,,,,,,,,0062445316,9780062445315,,2019-07-08,,,2,,,mixed feelings,2019-07-08,cooking,Cooking,2019-07-08
我穿我自己,琅俨,https://example.com/book/2010,,,,,,,,,,,,,,,,,,,,,,to-read,To Read,2024-08-10
Ottolenghi Simple,Yotam Ottolenghi,https://example.com/book/2,OL43065148M,,,,,,,,,,0449017036,9780449017036,,2022-08-10,2022-10-10,,4,Too much tahini,,...in his hummus,2022-11-10,cooking-9,Cooking,2024-08-10
The Blue Bedspread,Raj Kamal Jha,https://example.com/book/270,OL7425890M,,,,,,,,,,0375503129,9780375503122,41754476,2001-06-01,2001-07-10,,5,,,,,read,Read,2024-08-10

1 title author_text remote_id openlibrary_key inventaire_id librarything_key goodreads_key bnf_id viaf wikidata asin aasin isfdb isbn_10 isbn_13 oclc_number start_date finish_date stopped_date rating review_name review_cw review_content review_published shelf shelf_name shelf_date
2 Gideon the Ninth (The Locked Tomb #1) 我穿我自己 Tamsyn Muir 琅俨 https://example.com/book2 https://example.com/book/2010 1250313198 9781250313195 2020-10-21 2020-10-25 3 read to-read Read To Read 2020-10-21 2024-08-10
3 Subcutanean Ottolenghi Simple Aaron A. Reed Yotam Ottolenghi https://example.com/book3 https://example.com/book/2 OL43065148M 0449017036 9780449017036 2020-03-05 2022-08-10 2020-03-06 2022-10-10 0 4 Too much tahini ...in his hummus 2022-11-10 read cooking-9 Read Cooking 2020-03-05 2024-08-10
4 Patisserie at Home The Blue Bedspread Mélanie Dupuis Raj Kamal Jha https://example.com/book4 https://example.com/book/270 OL7425890M 0062445316 0375503129 9780062445315 9780375503122 41754476 2019-07-08 2001-06-01 2001-07-10 2 5 mixed feelings 2019-07-08 cooking read Cooking Read 2019-07-08 2024-08-10

View file

@ -60,11 +60,19 @@ class BookwyrmBooksImport(TestCase):
import_items = models.ImportItem.objects.filter(job=import_job).all()
self.assertEqual(len(import_items), 3)
self.assertEqual(import_items[0].index, 0)
self.assertEqual(import_items[0].normalized_data["isbn_13"], "9781250313195")
self.assertEqual(import_items[0].normalized_data["isbn_10"], "1250313198")
self.assertEqual(import_items[0].normalized_data["isbn_13"], "")
self.assertEqual(import_items[0].normalized_data["isbn_10"], "")
self.assertEqual(import_items[0].shelf_name, "To Read")
self.assertEqual(import_items[1].index, 1)
self.assertEqual(import_items[1].normalized_data["isbn_13"], "9780449017036")
self.assertEqual(import_items[1].normalized_data["isbn_10"], "0449017036")
self.assertEqual(import_items[1].shelf_name, "Cooking")
self.assertEqual(import_items[2].index, 2)
self.assertEqual(import_items[2].shelf_name, "Cooking")
self.assertEqual(import_items[2].normalized_data["isbn_13"], "9780375503122")
self.assertEqual(import_items[2].normalized_data["isbn_10"], "0375503129")
self.assertEqual(import_items[2].shelf_name, "Read")
def test_create_retry_job(self, *_):
"""trying again with items that didn't import"""
@ -84,11 +92,9 @@ class BookwyrmBooksImport(TestCase):
retry_items = models.ImportItem.objects.filter(job=retry).all()
self.assertEqual(len(retry_items), 2)
self.assertEqual(retry_items[0].index, 0)
self.assertEqual(
retry_items[0].data["title"], "Gideon the Ninth (The Locked Tomb #1)"
)
self.assertEqual(retry_items[0].data["title"], "我穿我自己")
self.assertEqual(retry_items[1].index, 1)
self.assertEqual(retry_items[1].data["author_text"], "Aaron A. Reed")
self.assertEqual(retry_items[1].data["author_text"], "Yotam Ottolenghi")
def test_handle_imported_book(self, *_):
"""import added a book, this adds related connections"""
@ -100,7 +106,7 @@ class BookwyrmBooksImport(TestCase):
import_job = self.importer.create_job(
self.local_user, self.csv, False, "public"
)
import_item = import_job.items.first()
import_item = import_job.items.last()
import_item.book = self.book
import_item.save()
@ -110,13 +116,13 @@ class BookwyrmBooksImport(TestCase):
shelf.refresh_from_db()
self.assertEqual(shelf.books.first(), self.book)
self.assertEqual(
shelf.shelfbook_set.first().shelved_date, make_date(2020, 10, 21)
shelf.shelfbook_set.first().shelved_date, make_date(2024, 8, 10)
)
readthrough = models.ReadThrough.objects.get(user=self.local_user)
self.assertEqual(readthrough.book, self.book)
self.assertEqual(readthrough.start_date, make_date(2020, 10, 21))
self.assertEqual(readthrough.finish_date, make_date(2020, 10, 25))
self.assertEqual(readthrough.start_date, make_date(2001, 6, 1))
self.assertEqual(readthrough.finish_date, make_date(2001, 7, 10))
def test_create_new_shelf(self, *_):
"""import added a book, was a new shelf created?"""
@ -126,14 +132,14 @@ class BookwyrmBooksImport(TestCase):
import_job = self.importer.create_job(
self.local_user, self.csv, False, "public"
)
import_item = models.ImportItem.objects.filter(job=import_job).all()[2]
import_item = models.ImportItem.objects.filter(job=import_job).all()[1]
import_item.book = self.book
import_item.save()
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"):
handle_imported_book(import_item)
shelf_after = self.local_user.shelf_set.filter(identifier="cooking").first()
shelf_after = self.local_user.shelf_set.filter(identifier="cooking-9").first()
self.assertEqual(shelf_after.books.first(), self.book)
@patch("bookwyrm.activitystreams.add_status_task.delay")
@ -142,7 +148,7 @@ class BookwyrmBooksImport(TestCase):
import_job = self.importer.create_job(
self.local_user, self.csv, True, "unlisted"
)
import_item = import_job.items.get(index=2)
import_item = import_job.items.get(index=1)
import_item.book = self.book
import_item.save()
@ -150,18 +156,19 @@ class BookwyrmBooksImport(TestCase):
handle_imported_book(import_item)
review = models.Review.objects.get(book=self.book, user=self.local_user)
self.assertEqual(review.content, "mixed feelings")
self.assertEqual(review.rating, 2)
self.assertEqual(review.published_date, make_date(2019, 7, 8))
self.assertEqual(review.name, "Too much tahini")
self.assertEqual(review.content, "...in his hummus")
self.assertEqual(review.rating, 4)
self.assertEqual(review.published_date, make_date(2022, 11, 10))
self.assertEqual(review.privacy, "unlisted")
@patch("bookwyrm.activitystreams.add_status_task.delay")
def test_handle_imported_book_rating(self, *_):
"""rating import"""
import_job = self.importer.create_job(
self.local_user, self.csv, True, "unlisted"
self.local_user, self.csv, True, "followers"
)
import_item = import_job.items.filter(index=0).first()
import_item = import_job.items.filter(index=2).first()
import_item.book = self.book
import_item.save()
@ -170,6 +177,6 @@ class BookwyrmBooksImport(TestCase):
review = models.ReviewRating.objects.get(book=self.book, user=self.local_user)
self.assertIsInstance(review, models.ReviewRating)
self.assertEqual(review.rating, 3)
self.assertEqual(review.published_date, make_date(2020, 10, 25))
self.assertEqual(review.privacy, "unlisted")
self.assertEqual(review.rating, 5)
self.assertEqual(review.published_date, make_date(2001, 7, 10))
self.assertEqual(review.privacy, "followers")

View file

@ -100,7 +100,7 @@ class GenericImporter(TestCase):
self.assertEqual(retry.include_reviews, False)
self.assertEqual(retry.privacy, "unlisted")
retry_items = models.ImportItem.objects.filter(job=retry).order_by("index")
retry_items = models.ImportItem.objects.filter(job=retry).all()
self.assertEqual(len(retry_items), 2)
self.assertEqual(retry_items[0].index, 0)
self.assertEqual(retry_items[0].normalized_data["id"], "38")