Merge pull request #122 from cthulahoops/import_reviews

Import reviews
This commit is contained in:
Mouse Reeve 2020-04-02 09:15:18 -07:00 committed by GitHub
commit 6ad8d8662c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 23 deletions

View file

@ -25,12 +25,17 @@ def get_comment(comment):
def get_review_article(review):
''' a book review formatted for a non-fedireads isntance (mastodon) '''
status = get_status(review)
if review.rating:
if review.rating and review.name:
name = 'Review of "%s" (%d stars): %s' % (
review.book.title,
review.rating,
review.name
)
elif review.rating:
name = 'Rated "%s" (%d stars)' % (
review.book.title,
review.rating,
)
else:
name = 'Review of "%s": %s' % (
review.book.title,

View file

@ -22,8 +22,7 @@ def unquote_string(text):
match = re.match(r'="([^"]*)"', text)
if match:
return match.group(1)
else:
return text
return text
def construct_search_term(title, author):
@ -36,7 +35,7 @@ def construct_search_term(title, author):
return ' '.join([title, author])
class GoodreadsCsv(object):
class GoodreadsCsv:
''' define a goodreads csv '''
def __init__(self, csv_file):
self.reader = csv.DictReader(csv_file)
@ -51,7 +50,7 @@ class GoodreadsCsv(object):
yield entry
class GoodreadsItem(object):
class GoodreadsItem:
''' a processed line in a goodreads csv '''
def __init__(self, line):
self.line = line
@ -89,9 +88,16 @@ class GoodreadsItem(object):
if self.line['Exclusive Shelf']:
return GOODREADS_SHELVES[self.line['Exclusive Shelf']]
@property
def review(self):
return self.line['My Review']
@property
def rating(self):
return int(self.line['My Rating'])
def __repr__(self):
return "<GoodreadsItem {!r}>".format(self.line['Title'])
def __str__(self):
return "{} by {}".format(self.line['Title'], self.line['Author'])

View file

@ -1,9 +1,10 @@
''' handles all the activity coming out of the server '''
from urllib.parse import urlencode
from django.db import IntegrityError, transaction
from django.http import HttpResponseNotFound, JsonResponse
from django.views.decorators.csrf import csrf_exempt
import requests
from urllib.parse import urlencode
from fedireads import activitypub
from fedireads import models

View file

@ -8,14 +8,16 @@ from fedireads.sanitize_html import InputHtmlParser
def create_review_from_activity(author, activity):
''' parse an activity json blob into a status '''
book = activity['inReplyToBook']
book = book.split('/')[-1]
book_id = activity['inReplyToBook']
book_id = book_id.split('/')[-1]
name = activity.get('name')
rating = activity.get('rating')
content = activity.get('content')
published = activity.get('published')
remote_id = activity['id']
book = get_or_create_book(book_id)
review = create_review(author, book, name, content, rating)
review.published_date = published
review.remote_id = remote_id
@ -23,18 +25,15 @@ def create_review_from_activity(author, activity):
return review
def create_review(user, possible_book, name, content, rating):
def create_review(user, book, name, content, rating):
''' a book review has been added '''
# throws a value error if the book is not found
book = get_or_create_book(possible_book)
name = sanitize(name)
content = sanitize(content)
# no ratings outside of 0-5
try:
rating = int(rating)
if rating:
rating = rating if 1 <= rating <= 5 else None
except ValueError:
else:
rating = None
return models.Review.objects.create(

View file

@ -19,6 +19,8 @@ def stars(number):
number = int(number)
except (ValueError, TypeError):
number = 0
if not number:
return ''
return ('' * number) + '' * (5 - number)

View file

@ -1,16 +1,18 @@
''' views for actions you can take in the application '''
from io import TextIOWrapper
import re
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseBadRequest, HttpResponseNotFound
from django.shortcuts import redirect
from django.template.response import TemplateResponse
from io import TextIOWrapper
import re
from fedireads import forms, models, books_manager, outgoing
from fedireads.goodreads_import import GoodreadsCsv
from fedireads.settings import DOMAIN
from fedireads.views import get_user_from_username
from fedireads.books_manager import get_or_create_book
def user_login(request):
@ -170,9 +172,12 @@ def review(request):
# TODO: validation, htmlification
name = form.data.get('name')
content = form.data.get('content')
rating = form.data.get('rating')
rating = form.cleaned_data.get('rating')
outgoing.handle_review(request.user, book_identifier, name, content, rating)
# throws a value error if the book is not found
book = get_or_create_book(book_identifier)
outgoing.handle_review(request.user, book, name, content, rating)
return redirect('/book/%s' % book_identifier)
@ -352,20 +357,32 @@ def import_data(request):
form = forms.ImportForm(request.POST, request.FILES)
if form.is_valid():
results = []
reviews = []
failures = []
for item in GoodreadsCsv(TextIOWrapper(
request.FILES['csv_file'],
encoding=request.encoding)):
if item.book:
results.append(item)
if item.rating or item.review:
reviews.append(item)
else:
failures.append(item)
outgoing.handle_import_books(request.user, results)
for item in reviews:
review_title = "Review of {!r} on Goodreads".format(
item.book.title,
) if item.review else ""
outgoing.handle_review(
request.user,
item.book,
review_title,
item.review,
item.rating,
)
return TemplateResponse(request, 'import_results.html', {
'success_count': len(results),
'failures': failures,
})
else:
return HttpResponseBadRequest()
return HttpResponseBadRequest()