mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-24 09:00:33 +00:00
convert between ibsn 10 and 13
This commit is contained in:
parent
90cccc455e
commit
7febcec229
7 changed files with 97 additions and 24 deletions
|
@ -52,11 +52,13 @@ class Connector(AbstractConnector):
|
||||||
|
|
||||||
|
|
||||||
def get_edition_from_work_data(self, data):
|
def get_edition_from_work_data(self, data):
|
||||||
return data['editions'][0]
|
''' we're served a list of edition urls '''
|
||||||
|
path = data['editions'][0]
|
||||||
|
return get_data(path)
|
||||||
|
|
||||||
|
|
||||||
def get_work_from_edition_date(self, data):
|
def get_work_from_edition_date(self, data):
|
||||||
return data['work']
|
return get_data(data['work'])
|
||||||
|
|
||||||
|
|
||||||
def get_authors_from_data(self, data):
|
def get_authors_from_data(self, data):
|
||||||
|
|
|
@ -135,7 +135,7 @@ class Work(Book):
|
||||||
@property
|
@property
|
||||||
def editions_path(self):
|
def editions_path(self):
|
||||||
''' it'd be nice to serialize the edition instead but, recursion '''
|
''' it'd be nice to serialize the edition instead but, recursion '''
|
||||||
return self.remote_id + '/editions'
|
return [e.remote_id for e in self.edition_set.all()]
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -174,6 +174,49 @@ class Edition(Book):
|
||||||
|
|
||||||
activity_serializer = activitypub.Edition
|
activity_serializer = activitypub.Edition
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
''' calculate isbn 10/13 '''
|
||||||
|
if self.isbn_13 and self.isbn_13[:3] == '978' and not self.isbn_10:
|
||||||
|
self.isbn_10 = isbn_13_to_10(self.isbn_13)
|
||||||
|
if self.isbn_10 and not self.isbn_13:
|
||||||
|
self.isbn_13 = isbn_10_to_13(self.isbn_10)
|
||||||
|
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def isbn_10_to_13(isbn_10):
|
||||||
|
''' convert an isbn 10 into an isbn 13 '''
|
||||||
|
# drop the last character of the isbn 10 number (the original checkdigit)
|
||||||
|
converted = isbn_10[:9]
|
||||||
|
# add "978" to the front
|
||||||
|
converted = '978' + converted
|
||||||
|
# add a check digit to the end
|
||||||
|
# multiply the odd digits by 1 and the even digits by 3 and sum them
|
||||||
|
checksum = sum(int(i) for i in converted[::2]) + \
|
||||||
|
sum(int(i) * 3 for i in converted[1::2])
|
||||||
|
# add the checksum mod 10 to the end
|
||||||
|
checkdigit = checksum % 10
|
||||||
|
if checkdigit != 0:
|
||||||
|
checkdigit = 10 - checkdigit
|
||||||
|
return converted + str(checkdigit)
|
||||||
|
|
||||||
|
|
||||||
|
def isbn_13_to_10(isbn_13):
|
||||||
|
''' convert isbn 13 to 10, if possible '''
|
||||||
|
if isbn_13[:3] != '978':
|
||||||
|
return None
|
||||||
|
|
||||||
|
# remove '978' and old checkdigit
|
||||||
|
converted = isbn_13[3:-1]
|
||||||
|
# calculate checkdigit
|
||||||
|
# multiple each digit by 10,9,8.. successively and sum them
|
||||||
|
checksum = sum(int(d) * (10 - idx) for (idx, d) in enumerate(converted))
|
||||||
|
checkdigit = checksum % 11
|
||||||
|
checkdigit = 11 - checkdigit
|
||||||
|
if checkdigit == 10:
|
||||||
|
checkdigit = 'X'
|
||||||
|
return converted + str(checkdigit)
|
||||||
|
|
||||||
|
|
||||||
class Author(ActivitypubMixin, BookWyrmModel):
|
class Author(ActivitypubMixin, BookWyrmModel):
|
||||||
''' copy of an author from OL '''
|
''' copy of an author from OL '''
|
||||||
|
|
|
@ -80,7 +80,10 @@ class ImportItem(models.Model):
|
||||||
)
|
)
|
||||||
search_result = books_manager.first_search_result(search_term)
|
search_result = books_manager.first_search_result(search_term)
|
||||||
if search_result:
|
if search_result:
|
||||||
return books_manager.get_or_create_book(search_result.key)
|
try:
|
||||||
|
return books_manager.get_or_create_book(search_result.key)
|
||||||
|
except ConnectorException:
|
||||||
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def isbn(self):
|
def isbn(self):
|
||||||
|
|
|
@ -55,6 +55,14 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% for readthrough in readthroughs %}
|
||||||
|
<div class="block">
|
||||||
|
{{ readthrough.start_date }}
|
||||||
|
{{ readthrough.finish_date }}
|
||||||
|
{{ readthrough.pages_read }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<div class="block">
|
<div class="block">
|
||||||
{% include 'snippets/create_status.html' with book=book hide_cover=True %}
|
{% include 'snippets/create_status.html' with book=book hide_cover=True %}
|
||||||
|
|
|
@ -34,16 +34,6 @@ class BookWyrmConnector(TestCase):
|
||||||
self.assertEqual(self.connector.is_work_data(self.edition_data), False)
|
self.assertEqual(self.connector.is_work_data(self.edition_data), False)
|
||||||
|
|
||||||
|
|
||||||
def test_get_edition_from_work_data(self):
|
|
||||||
edition = self.connector.get_edition_from_work_data(self.work_data)
|
|
||||||
self.assertEqual(edition['url'], 'https://example.com/book/122')
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_work_from_edition_data(self):
|
|
||||||
work = self.connector.get_work_from_edition_date(self.edition_data)
|
|
||||||
self.assertEqual(work['url'], 'https://example.com/book/121')
|
|
||||||
|
|
||||||
|
|
||||||
def test_format_search_result(self):
|
def test_format_search_result(self):
|
||||||
datafile = pathlib.Path(__file__).parent.joinpath('../data/fr_search.json')
|
datafile = pathlib.Path(__file__).parent.joinpath('../data/fr_search.json')
|
||||||
search_data = json.loads(datafile.read_bytes())
|
search_data = json.loads(datafile.read_bytes())
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from bookwyrm import models, settings
|
from bookwyrm import models, settings
|
||||||
|
from bookwyrm.models.book import isbn_10_to_13, isbn_13_to_10
|
||||||
|
|
||||||
|
|
||||||
class Book(TestCase):
|
class Book(TestCase):
|
||||||
|
@ -48,6 +49,16 @@ class Book(TestCase):
|
||||||
|
|
||||||
self.assertEqual(self.work.default_edition, self.second_edition)
|
self.assertEqual(self.work.default_edition, self.second_edition)
|
||||||
|
|
||||||
|
def test_isbn_10_to_13(self):
|
||||||
|
isbn_10 = '178816167X'
|
||||||
|
isbn_13 = isbn_10_to_13(isbn_10)
|
||||||
|
self.assertEqual(isbn_13, '9781788161671')
|
||||||
|
|
||||||
|
def test_isbn_13_to_10(self):
|
||||||
|
isbn_13 = '9781788161671'
|
||||||
|
isbn_10 = isbn_13_to_10(isbn_13)
|
||||||
|
self.assertEqual(isbn_10, '178816167X')
|
||||||
|
|
||||||
|
|
||||||
class Shelf(TestCase):
|
class Shelf(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
|
@ -112,26 +112,34 @@ def home_tab(request, tab):
|
||||||
def get_activity_feed(user, filter_level, model=models.Status):
|
def get_activity_feed(user, filter_level, model=models.Status):
|
||||||
''' get a filtered queryset of statuses '''
|
''' get a filtered queryset of statuses '''
|
||||||
# status updates for your follow network
|
# status updates for your follow network
|
||||||
following = models.User.objects.filter(
|
if user.is_anonymous:
|
||||||
Q(followers=user) | Q(id=user.id)
|
user = None
|
||||||
)
|
if user:
|
||||||
|
following = models.User.objects.filter(
|
||||||
|
Q(followers=user) | Q(id=user.id)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
following = []
|
||||||
|
|
||||||
activities = model
|
activities = model
|
||||||
if hasattr(model, 'objects'):
|
if hasattr(model, 'objects'):
|
||||||
activities = model.objects.filter(deleted=False)
|
activities = model.objects
|
||||||
|
|
||||||
activities = activities.order_by(
|
activities = activities.filter(
|
||||||
'-created_date'
|
deleted=False
|
||||||
|
).order_by(
|
||||||
|
'-published_date'
|
||||||
)
|
)
|
||||||
|
|
||||||
if hasattr(activities, 'select_subclasses'):
|
if hasattr(activities, 'select_subclasses'):
|
||||||
activities = activities.select_subclasses()
|
activities = activities.select_subclasses()
|
||||||
|
|
||||||
# TODO: privacy relationshup between request.user and user
|
|
||||||
if filter_level in ['friends', 'home']:
|
if filter_level in ['friends', 'home']:
|
||||||
# people you follow and direct mentions
|
# people you follow and direct mentions
|
||||||
activities = activities.filter(
|
activities = activities.filter(
|
||||||
Q(user__in=following, privacy__in=['public', 'unlisted', 'followers']) | \
|
Q(user__in=following, privacy__in=[
|
||||||
Q(mention_users=user) | Q(user=user)
|
'public', 'unlisted', 'followers'
|
||||||
|
]) | Q(mention_users=user) | Q(user=user)
|
||||||
)
|
)
|
||||||
elif filter_level == 'self':
|
elif filter_level == 'self':
|
||||||
activities = activities.filter(user=user, privacy='public')
|
activities = activities.filter(user=user, privacy='public')
|
||||||
|
@ -470,14 +478,21 @@ def book_page(request, book_id):
|
||||||
|
|
||||||
reviews = models.Review.objects.filter(
|
reviews = models.Review.objects.filter(
|
||||||
book__in=work.edition_set.all(),
|
book__in=work.edition_set.all(),
|
||||||
).order_by('-published_date')
|
)
|
||||||
|
reviews = get_activity_feed(request.user, 'federated', model=reviews)
|
||||||
|
|
||||||
user_tags = []
|
user_tags = []
|
||||||
|
readthroughs = []
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
user_tags = models.Tag.objects.filter(
|
user_tags = models.Tag.objects.filter(
|
||||||
book=book, user=request.user
|
book=book, user=request.user
|
||||||
).values_list('identifier', flat=True)
|
).values_list('identifier', flat=True)
|
||||||
|
|
||||||
|
readthroughs = models.ReadThrough.objects.filter(
|
||||||
|
user=request.user
|
||||||
|
).order_by('start_date')
|
||||||
|
|
||||||
|
|
||||||
rating = reviews.aggregate(Avg('rating'))
|
rating = reviews.aggregate(Avg('rating'))
|
||||||
tags = models.Tag.objects.filter(
|
tags = models.Tag.objects.filter(
|
||||||
book=book
|
book=book
|
||||||
|
@ -492,6 +507,7 @@ def book_page(request, book_id):
|
||||||
'rating': rating['rating__avg'],
|
'rating': rating['rating__avg'],
|
||||||
'tags': tags,
|
'tags': tags,
|
||||||
'user_tags': user_tags,
|
'user_tags': user_tags,
|
||||||
|
'readthroughs': readthroughs,
|
||||||
'review_form': forms.ReviewForm(),
|
'review_form': forms.ReviewForm(),
|
||||||
'quotation_form': forms.QuotationForm(),
|
'quotation_form': forms.QuotationForm(),
|
||||||
'comment_form': forms.CommentForm(),
|
'comment_form': forms.CommentForm(),
|
||||||
|
|
Loading…
Reference in a new issue