diff --git a/fedireads/forms.py b/fedireads/forms.py new file mode 100644 index 000000000..25870fef8 --- /dev/null +++ b/fedireads/forms.py @@ -0,0 +1,43 @@ +''' usin django model forms ''' +from django.forms import ModelForm, PasswordInput + +from fedireads import models + + +class LoginForm(ModelForm): + class Meta: + model = models.User + fields = ['username', 'password'] + help_texts = {f: None for f in fields} + widgets = { + 'password': PasswordInput(), + } + + +class RegisterForm(ModelForm): + class Meta: + model = models.User + fields = ['username', 'email', 'password'] + help_texts = {f: None for f in fields} + widgets = { + 'password': PasswordInput(), + } + + +class ReviewForm(ModelForm): + class Meta: + model = models.Review + fields = ['name', 'review_content', 'rating'] + help_texts = {f: None for f in fields} + labels = { + 'name': 'Title', + 'review_content': 'Review', + 'rating': 'Rating (out of 5)', + } + + +class EditUserForm(ModelForm): + class Meta: + model = models.User + fields = ['avatar', 'name', 'summary'] + help_texts = {f: None for f in fields} diff --git a/fedireads/incoming.py b/fedireads/incoming.py index d5ebaf559..bb7b0fca4 100644 --- a/fedireads/incoming.py +++ b/fedireads/incoming.py @@ -193,7 +193,6 @@ def handle_incoming_create(activity): content=activity, activity_type='Article', book=book, - work=book.works.first(), name=activity['object']['name'], rating=activity['object']['rating'], review_content=activity['objet']['content'], diff --git a/fedireads/migrations/0001_initial.py b/fedireads/migrations/0001_initial.py index 5bbe22373..962fab954 100644 --- a/fedireads/migrations/0001_initial.py +++ b/fedireads/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.2 on 2020-01-29 07:36 +# Generated by Django 3.0.2 on 2020-01-29 09:04 from django.conf import settings import django.contrib.auth.models @@ -109,16 +109,6 @@ class Migration(migrations.Migration): ('updated_date', models.DateTimeField(auto_now=True)), ], ), - migrations.CreateModel( - name='Work', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('openlibrary_key', models.CharField(max_length=255)), - ('data', django.contrib.postgres.fields.jsonb.JSONField()), - ('added_date', models.DateTimeField(auto_now_add=True)), - ('updated_date', models.DateTimeField(auto_now=True)), - ], - ), migrations.CreateModel( name='Note', fields=[ @@ -154,11 +144,6 @@ class Migration(migrations.Migration): name='shelves', field=models.ManyToManyField(through='fedireads.ShelfBook', to='fedireads.Shelf'), ), - migrations.AddField( - model_name='book', - name='works', - field=models.ManyToManyField(to='fedireads.Work'), - ), migrations.CreateModel( name='ShelveActivity', fields=[ @@ -180,7 +165,6 @@ class Migration(migrations.Migration): ('rating', models.IntegerField(default=0)), ('review_content', models.TextField()), ('book', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fedireads.Book')), - ('work', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='fedireads.Work')), ], bases=('fedireads.activity',), ), diff --git a/fedireads/models.py b/fedireads/models.py index 7feecce68..47783ad1b 100644 --- a/fedireads/models.py +++ b/fedireads/models.py @@ -133,7 +133,6 @@ class FollowActivity(Activity): class Review(Activity): ''' a book review ''' book = models.ForeignKey('Book', on_delete=models.PROTECT) - work = models.ForeignKey('Work', on_delete=models.PROTECT) name = models.CharField(max_length=255) # TODO: validation rating = models.IntegerField(default=0) @@ -200,11 +199,10 @@ class ShelfBook(models.Model): class Book(models.Model): - ''' a non-canonical copy from open library ''' + ''' a non-canonical copy of a work (not book) from open library ''' activitypub_id = models.CharField(max_length=255) openlibrary_key = models.CharField(max_length=255, unique=True) data = JSONField() - works = models.ManyToManyField('Work') authors = models.ManyToManyField('Author') cover = models.ImageField(upload_to='covers/', blank=True, null=True) shelves = models.ManyToManyField( @@ -227,14 +225,6 @@ class Book(models.Model): super().save(*args, **kwargs) -class Work(models.Model): - ''' encompassses all editions of a book ''' - openlibrary_key = models.CharField(max_length=255) - data = JSONField() - added_date = models.DateTimeField(auto_now_add=True) - updated_date = models.DateTimeField(auto_now=True) - - class Author(models.Model): openlibrary_key = models.CharField(max_length=255) data = JSONField() diff --git a/fedireads/openlibrary.py b/fedireads/openlibrary.py index 964792bd7..94dcde77e 100644 --- a/fedireads/openlibrary.py +++ b/fedireads/openlibrary.py @@ -3,10 +3,27 @@ from django.core.exceptions import ObjectDoesNotExist from django.core.files.base import ContentFile import requests -from fedireads.models import Author, Book, Work +from fedireads.models import Author, Book from fedireads.settings import OL_URL +def book_search(query): + ''' look up a book ''' + response = requests.get('%s/search.json' % OL_URL, params={'q': query}) + if not response.ok: + response.raise_for_status() + data = response.json() + results = [] + for doc in data['docs'][:5]: + key = doc['key'].split('/')[-1] + results.append({ + 'title': doc['title'], + 'olkey': key, + 'year': doc['first_publish_year'], + 'author': doc['author_name'][0], + }) + return results + def get_or_create_book(olkey, user=None, update=False): ''' add a book ''' # TODO: check if this is a valid open library key, and a book @@ -36,13 +53,9 @@ def get_or_create_book(olkey, user=None, update=False): # great, we can update our book. book.save() - # we also need to know the author and works related to this book. - for work_id in data['works']: - work_id = work_id['key'] - book.works.add(get_or_create_work(work_id)) - - for author_id in data['authors']: - author_id = author_id['key'] + # we also need to know the author get the cover + for author_blob in data['authors']: + author_id = author_blob['author']['key'] book.authors.add(get_or_create_author(author_id)) if len(data['covers']): @@ -62,20 +75,6 @@ def get_cover(cover_id): return [image_name, image_content] -def get_or_create_work(olkey): - ''' load em up ''' - # TODO: validate that this is a work key - # TODO: error handling - try: - work = Work.objects.get(openlibrary_key=olkey) - except ObjectDoesNotExist: - response = requests.get(OL_URL + olkey + '.json') - data = response.json() - work = Work(openlibrary_key=olkey, data=data) - work.save() - return work - - def get_or_create_author(olkey): ''' load that author ''' # TODO: validate that this is an author key diff --git a/fedireads/outgoing.py b/fedireads/outgoing.py index ec9b8ea05..f645b7f00 100644 --- a/fedireads/outgoing.py +++ b/fedireads/outgoing.py @@ -188,7 +188,6 @@ def handle_review(user, book, name, content, rating): content=activity, activity_type='Article', book=book, - work=book.works.first(), name=name, rating=rating, review_content=content, diff --git a/fedireads/static/images/default_avi.jpg b/fedireads/static/images/default_avi.jpg new file mode 100644 index 000000000..80829abb8 Binary files /dev/null and b/fedireads/static/images/default_avi.jpg differ diff --git a/fedireads/static/images/no_cover.jpg b/fedireads/static/images/no_cover.jpg new file mode 100644 index 000000000..e6fbb3bca Binary files /dev/null and b/fedireads/static/images/no_cover.jpg differ diff --git a/fedireads/templates/book_results.html b/fedireads/templates/book_results.html new file mode 100644 index 000000000..d85eb7bde --- /dev/null +++ b/fedireads/templates/book_results.html @@ -0,0 +1,13 @@ +{% extends 'layout.html' %} +{% block content %} +
+
+

Search results

+ {% for result in results %} +
+ {{ result.title }} by {{ result.author }} ({{ result.year }}) +
+ {% endfor %} +
+
+{% endblock %} diff --git a/fedireads/templates/feed.html b/fedireads/templates/feed.html index 51ae43f1c..dcfea25bf 100644 --- a/fedireads/templates/feed.html +++ b/fedireads/templates/feed.html @@ -82,6 +82,7 @@ {{ activity.book.data.title }} by {{ activity.book.authors.first.data.name }} +
{{ book.data.description }}

{% elif activity.fedireads_type == 'Review' %} @@ -94,6 +95,7 @@ {{ activity.book.data.title }} by {{ activity.book.authors.first.data.name }} +
{{ book.data.description }}

{{ activity.name }}

diff --git a/fedireads/templates/results.html b/fedireads/templates/user_results.html similarity index 100% rename from fedireads/templates/results.html rename to fedireads/templates/user_results.html diff --git a/fedireads/urls.py b/fedireads/urls.py index 7aad76632..c551871f3 100644 --- a/fedireads/urls.py +++ b/fedireads/urls.py @@ -23,7 +23,7 @@ urlpatterns = [ path('logout/', views.user_logout), path('user/', views.user_profile), path('user//edit/', views.user_profile_edit), - path('book/', views.book_page), + path('work/', views.book_page), # internal action endpoints path('review/', views.review), diff --git a/fedireads/views.py b/fedireads/views.py index 271176be1..563dd1d4a 100644 --- a/fedireads/views.py +++ b/fedireads/views.py @@ -26,7 +26,7 @@ def home(request): user_books = models.Book.objects.filter(shelves__user=request.user).all() recent_books = models.Book.objects.order_by( 'added_date' - )[:10] + )[:5] following = models.User.objects.filter( Q(followers=request.user) | Q(id=request.user.id) @@ -163,10 +163,8 @@ def edit_profile(request): @login_required def book_page(request, book_identifier): ''' info about a book ''' - book = openlibrary.get_or_create_book('/book/' + book_identifier) - reviews = models.Review.objects.filter( - Q(work=book.works.first()) | Q(book=book) - ) + book = openlibrary.get_or_create_book('/work/' + book_identifier) + reviews = models.Review.objects.filter(book=book) rating = reviews.aggregate(Avg('rating')) review_form = forms.ReviewForm() data = { @@ -244,9 +242,10 @@ def search(request): query = request.GET.get('q') if re.match(r'\w+@\w+.\w+', query): results = [api.handle_account_search(query)] + template = 'user_results.html' else: - # TODO: book search - results = [] + results = openlibrary.book_search(query) + template = 'book_results.html' - return TemplateResponse(request, 'results.html', {'results': results}) + return TemplateResponse(request, template, {'results': results}) diff --git a/rebuilddb.sh b/rebuilddb.sh index 9792e8335..6ac61b478 100755 --- a/rebuilddb.sh +++ b/rebuilddb.sh @@ -12,6 +12,6 @@ echo "from fedireads.models import User User.objects.create_user('rat', 'rat@rat.com', 'ratword') User.objects.get(id=1).followers.add(User.objects.get(id=2))" | python manage.py shell echo "from fedireads.openlibrary import get_or_create_book -get_or_create_book('/book/OL13549170M') -get_or_create_book('/book/OL24738110M')" | python manage.py shell +get_or_create_book('/work/OL1715344W') +get_or_create_book('/work/OL102749W')" | python manage.py shell python manage.py runserver