mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-15 13:24:04 +00:00
Full add author flow
This commit is contained in:
parent
b2d1384bc5
commit
5c089db086
5 changed files with 96 additions and 57 deletions
|
@ -8,7 +8,7 @@
|
|||
<header class="block">
|
||||
<h1 class="title level-left">
|
||||
{% if book %}
|
||||
{% blocktrans with book_title=book.title %}Edit "{{ book.title }}"{% endblocktrans %}
|
||||
{% blocktrans with book_title=book.title %}Edit "{{ book_title }}"{% endblocktrans %}
|
||||
{% else %}
|
||||
{% trans "Add Book" %}
|
||||
{% endif %}
|
||||
|
@ -26,9 +26,46 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form class="block" name="edit-book" action="{{ book.local_path }}/edit#deduplication" method="post" enctype="multipart/form-data">
|
||||
<fieldset {% if confirm_mode %}disabled{% endif %}>
|
||||
<form class="block" name="edit-book" action="{{ book.local_path }}/{% if confirm_mode %}confirm{% else %}edit{% endif %}" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{% if confirm_mode %}
|
||||
<div class="box">
|
||||
<h2 class="title is-4">{% trans "Confirm Book Info" %}</h2>
|
||||
<div class="columns">
|
||||
{% if author_matches.exists %}
|
||||
<fieldset class="column is-half">
|
||||
<legend class="label">{% blocktrans with name=add_author %}Is "{{ name }}" an existing author?{% endblocktrans %}</legend>
|
||||
{% for match in author_matches %}
|
||||
<label><input type="radio" name="author_match" value="{{ match.id }}" required> {{ match.name }}</label>
|
||||
<p class="help">
|
||||
<a href="{{ author.local_path }}" target="_blank">{% blocktrans with book_title=match.book_set.first.title %}Author of <em>{{ book_title }}</em>{% endblocktrans %}</a>
|
||||
</p>
|
||||
{% endfor %}
|
||||
<label><input type="radio" name="author_match"> {% trans "This is a new author" %}</label>
|
||||
</fieldset>
|
||||
{% else %}
|
||||
<p class="column is-half">{% blocktrans with name=add_author %}Creating a new author: {{ name }}{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if not book %}
|
||||
<fieldset class="column is-half">
|
||||
<legend class="title is-5">{% trans "Is this an editions of an existing work?" %}</legend>
|
||||
{% for match in book_matches %}
|
||||
<label class="label"><input type="radio" name="parent_work" value="{{ match.parent_work.id }}"> {{ match.parent_work.title }}</label>
|
||||
{% endfor %}
|
||||
<label><input type="radio" name="parent_work"> this is a new work</label>
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<button class="button is-primary" type="submit">{% trans "Confirm" %}</button>
|
||||
<button class="button" type="button">{% trans "Back" %}</button>
|
||||
</div>
|
||||
|
||||
<hr class="block">
|
||||
{% endif %}
|
||||
|
||||
<fieldset>
|
||||
<input type="hidden" name="last_edited_by" value="{{ request.user.id }}">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
|
@ -72,8 +109,12 @@
|
|||
<input type="checkbox" name="remove_author" value="{{ author.id }}"> {% trans "Remove this author" %}
|
||||
</label>
|
||||
{% endfor %}
|
||||
{% if confirm_mode %}
|
||||
<input type="hidden" name="add_author" id="id_add_author" value="{{ add_author }}">
|
||||
{% else %}
|
||||
<label class="label" for="id_add_author">{% trans "Add Author:" %}</label>
|
||||
<input class="input" type="text" name="add_author" id="id_add_author" placeholder="John Doe" value="{{ add_author }}">
|
||||
<input class="input" type="text" name="add_author" id="id_add_author" placeholder="{% trans 'John Doe' %}" value="{{ add_author }}">
|
||||
{% endif %}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
@ -142,39 +183,4 @@
|
|||
</fieldset>
|
||||
</form>
|
||||
|
||||
{% if author_matches or book_matches %}
|
||||
<hr class="block">
|
||||
<form class="box content" id="deduplication">
|
||||
<h2 class="title is-4">{% trans "Confirm Book Info" %}</h2>
|
||||
<div class="columns">
|
||||
{% if author_matches.exists %}
|
||||
<fieldset class="column is-half">
|
||||
<legend class="label">{% blocktrans %}Is "{{ add_author }}" an existing author?{% endblocktrans %}</legend>
|
||||
{% for match in author_matches %}
|
||||
<label class="label"><input type="radio" name="author_match" value="{{ match.id }}"> {{ match.name }}</label>
|
||||
<p class="help">
|
||||
<a href="{{ author.local_path }}" target="_blank">{% blocktrans with book_title=match.book_set.first.title %}Author of <em>{{ book_title }}</em>{% endblocktrans %}</a>
|
||||
</p>
|
||||
{% endfor %}
|
||||
<label class="label"><input type="radio" name="author_match"> this is a new author</label>
|
||||
</fieldset>
|
||||
{% else %}
|
||||
<p class="column is-half">{% blocktrans %}Creating a new author: {{ add_author }}{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if not book %}
|
||||
<fieldset class="column is-half">
|
||||
<legend class="title is-5">{% trans "Is this an editions of an existing work?" %}</legend>
|
||||
{% for match in book_matches %}
|
||||
<label class="label"><input type="radio" name="book_match" value="{{ match.id }}"> {{ match.title }}</label>
|
||||
{% endfor %}
|
||||
<label class="label"><input type="radio" name="book_match"> this is a new work</label>
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<button class="button is-primary" type="submit">{% trans "save" %}</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -85,18 +85,7 @@ class BookViews(TestCase):
|
|||
|
||||
def test_edit_book_add_author(self):
|
||||
''' lets a user edit a book '''
|
||||
view = views.EditBook.as_view()
|
||||
self.local_user.groups.add(self.group)
|
||||
form = forms.EditionForm(instance=self.book)
|
||||
form.data['title'] = 'New Title'
|
||||
form.data['last_edited_by'] = self.local_user.id
|
||||
form.data['add_author'] = "John Doe"
|
||||
request = self.factory.post('', form.data)
|
||||
request.user = self.local_user
|
||||
with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'):
|
||||
view(request, self.book.id)
|
||||
self.book.refresh_from_db()
|
||||
self.assertEqual(self.book.title, 'New Title')
|
||||
# TODO
|
||||
|
||||
|
||||
def test_switch_edition(self):
|
||||
|
|
|
@ -129,6 +129,7 @@ urlpatterns = [
|
|||
# books
|
||||
re_path(r'%s(.json)?/?$' % book_path, views.Book.as_view()),
|
||||
re_path(r'%s/edit/?$' % book_path, views.EditBook.as_view()),
|
||||
re_path(r'%s/confirm/?$' % book_path, views.ConfirmEditBook.as_view()),
|
||||
re_path(r'%s/editions(.json)?/?$' % book_path, views.Editions.as_view()),
|
||||
re_path(r'^upload-cover/(?P<book_id>\d+)/?$', views.upload_cover),
|
||||
re_path(r'^add-description/(?P<book_id>\d+)/?$', views.add_description),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from .authentication import Login, Register, Logout
|
||||
from .author import Author, EditAuthor
|
||||
from .block import Block, unblock
|
||||
from .books import Book, EditBook, Editions
|
||||
from .books import Book, EditBook, ConfirmEditBook, Editions
|
||||
from .books import upload_cover, add_description, switch_edition, resolve_book
|
||||
from .error import not_found_page, server_error_page
|
||||
from .federation import Federation
|
||||
|
|
|
@ -122,8 +122,8 @@ class EditBook(View):
|
|||
|
||||
def post(self, request, book_id=None):
|
||||
''' edit a book cool '''
|
||||
book = get_object_or_404(models.Edition, id=book_id) if book_id \
|
||||
else None
|
||||
# returns None if no match is found
|
||||
book = models.Edition.objects.filter(id=book_id).first()
|
||||
form = forms.EditionForm(request.POST, request.FILES, instance=book)
|
||||
|
||||
data = {
|
||||
|
@ -134,9 +134,8 @@ class EditBook(View):
|
|||
return TemplateResponse(request, 'edit_book.html', data)
|
||||
|
||||
add_author = request.POST.get('add_author')
|
||||
if not book or add_author:
|
||||
# creting a book or adding an author to a book needs another step
|
||||
data['confirm_mode'] = True
|
||||
# we're adding an author through a free text field
|
||||
if add_author:
|
||||
data['add_author'] = add_author
|
||||
# check for existing authors
|
||||
vector = SearchVector('name', weight='A') +\
|
||||
|
@ -148,6 +147,8 @@ class EditBook(View):
|
|||
rank=SearchRank(vector, add_author)
|
||||
).filter(rank__gt=0.8).order_by('-rank')[:5]
|
||||
|
||||
# we're creating a new book
|
||||
if not book:
|
||||
# check if this is an edition of an existing work
|
||||
author_text = book.author_text if book else add_author
|
||||
data['book_matches'] = connector_manager.local_search(
|
||||
|
@ -156,12 +157,54 @@ class EditBook(View):
|
|||
raw=True
|
||||
)[:5]
|
||||
|
||||
# either of the above cases requires additional confirmation
|
||||
if add_author or not book:
|
||||
# creting a book or adding an author to a book needs another step
|
||||
data['confirm_mode'] = True
|
||||
return TemplateResponse(request, 'edit_book.html', data)
|
||||
|
||||
book = form.save()
|
||||
return redirect('/book/%s' % book.id)
|
||||
|
||||
|
||||
@method_decorator(login_required, name='dispatch')
|
||||
@method_decorator(
|
||||
permission_required('bookwyrm.edit_book', raise_exception=True),
|
||||
name='dispatch')
|
||||
class ConfirmEditBook(View):
|
||||
''' confirm edits to a book '''
|
||||
def post(self, request, book_id=None):
|
||||
''' edit a book cool '''
|
||||
# returns None if no match is found
|
||||
book = models.Edition.objects.filter(id=book_id).first()
|
||||
form = forms.EditionForm(request.POST, request.FILES, instance=book)
|
||||
|
||||
data = {
|
||||
'book': book,
|
||||
'form': form
|
||||
}
|
||||
if not form.is_valid():
|
||||
return TemplateResponse(request, 'edit_book.html', data)
|
||||
|
||||
# create work, if needed
|
||||
# TODO
|
||||
|
||||
# save book
|
||||
book = form.save()
|
||||
|
||||
# get or create author as needed
|
||||
if request.POST.get('add_author'):
|
||||
if request.POST.get('author_match'):
|
||||
author = get_object_or_404(
|
||||
models.Author, id=request.POST['author_match'])
|
||||
else:
|
||||
author = models.Author.objects.create(
|
||||
name=request.POST.get('add_author'))
|
||||
book.authors.add(author)
|
||||
|
||||
return redirect('/book/%s' % book.id)
|
||||
|
||||
|
||||
class Editions(View):
|
||||
''' list of editions '''
|
||||
def get(self, request, book_id):
|
||||
|
|
Loading…
Reference in a new issue