Add ISBN data downloader

This commit is contained in:
Alexandre Iooss 2019-08-11 10:40:39 +02:00
parent 2f872eccce
commit 861279d30d
No known key found for this signature in database
GPG Key ID: 6C79278F3FCDCC02
7 changed files with 158 additions and 69 deletions

View File

@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _
from reversion.admin import VersionAdmin
from med.admin import admin_site
from .forms import MediaAdminForm
from .models import Auteur, Emprunt, Jeu, Media
@ -17,16 +18,43 @@ class AuteurAdmin(VersionAdmin):
class MediaAdmin(VersionAdmin):
list_display = ('title', 'authors_list', 'side_title', 'isbn')
list_display = ('title', 'authors_list', 'side_title', 'isbn',
'external_link')
search_fields = ('title', 'authors__nom', 'side_title', 'subtitle', 'isbn')
autocomplete_fields = ('authors',)
date_hierarchy = 'publish_date'
form = MediaAdminForm
def authors_list(self, obj):
return ", ".join([a.nom for a in obj.authors.all()])
authors_list.short_description = _('authors')
def external_link(self, obj):
return format_html('<a href="{}" target="about:blank">{}</a>',
obj.external_url, obj.external_url)
external_link.allow_tags = True
external_link.short_description = _('external url')
def get_form(self, request, obj=None, **kwargs):
"""
Pass request to form (for ISBN magic)
"""
form = super().get_form(request, obj=obj, **kwargs)
form.request = request
return form
def changeform_view(self, request, object_id=None, form_url='',
extra_context=None):
"""
We use _continue for ISBN fetching, so remove continue button
"""
extra_context = extra_context or {}
extra_context['show_save_and_continue'] = False
return super().changeform_view(request, object_id, form_url,
extra_context=extra_context)
class EmpruntAdmin(VersionAdmin):
list_display = ('media', 'user', 'date_emprunt', 'date_rendu',

View File

@ -2,6 +2,9 @@
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import json
import urllib.request
from django.forms import ModelForm
from .models import Emprunt
@ -11,3 +14,45 @@ class EmpruntForm(ModelForm):
class Meta:
model = Emprunt
fields = ['media']
class MediaAdminForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['isbn'].widget.template_name = "media/isbn_button.html"
def download_data(self, isbn):
"""
Download data from ISBN
"""
api_url = "https://openlibrary.org/api/books?bibkeys=ISBN:{}" \
"&format=json&jscmd=data".format(isbn)
with urllib.request.urlopen(api_url) as url:
data = json.loads(url.read().decode())
if data and data['ISBN:' + isbn]:
data = data['ISBN:' + isbn]
# Fill the data
# TODO implement authors
if data['title']:
self.cleaned_data['title'] = data['title']
self.cleaned_data['side_title'] = data['title']
if data['subtitle']:
self.cleaned_data['subtitle'] = data['subtitle']
if data['url']:
self.cleaned_data['external_url'] = data['url']
if data['number_of_pages']:
self.cleaned_data['number_of_pages'] = \
data['number_of_pages']
def clean(self):
"""
If user fetch ISBN data, then download data before validating the form
"""
if "_continue" in self.request.POST:
isbn = self.cleaned_data.get('isbn')
if isbn:
# ISBN is present
self.download_data(isbn)
return super().clean()

View File

@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-10 15:55+0200\n"
"POT-Creation-Date: 2019-08-11 10:39+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -13,46 +13,106 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: admin.py:47
msgid "Turn back"
msgstr "Rendre"
#: admin.py:50
msgid "permanencier rendu"
msgstr ""
#: models.py:17
msgid "author"
msgstr "auteur"
#: models.py:18
#: admin.py:31 models.py:20 models.py:51
msgid "authors"
msgstr "auteurs"
#: models.py:30
#: admin.py:38
msgid "external url"
msgstr "URL externe"
#: admin.py:78
msgid "Turn back"
msgstr "Rendre"
#: admin.py:81
msgid "permanencier rendu"
msgstr ""
#: fields.py:17
msgid "ISBN-10 or ISBN-13"
msgstr "ISBN-10 ou ISBN-13"
#: models.py:19
msgid "author"
msgstr "auteur"
#: models.py:25
msgid "ISBN"
msgstr "ISBN"
#: models.py:26
msgid "You may be able to scan it from a bar code."
msgstr "Peut souvent être scanné à partir du code barre."
#: models.py:31
msgid "title"
msgstr "titre"
#: models.py:35
msgid "subtitle"
msgstr "sous-titre"
#: models.py:41
msgid "external URL"
msgstr "URL externe"
#: models.py:46
msgid "side title"
msgstr "côte"
#: models.py:54
msgid "number of pages"
msgstr "nombre de pages"
#: models.py:59
msgid "publish date"
msgstr "date de publication"
#: models.py:68
msgid "medium"
msgstr "medium"
#: models.py:31
#: models.py:69
msgid "media"
msgstr "media"
#: models.py:60
#: models.py:98
msgid "borrowed item"
msgstr "emprunt"
#: models.py:61
#: models.py:99
msgid "borrowed items"
msgstr "emprunts"
#: models.py:85
#: models.py:123
msgid "game"
msgstr "jeu"
#: models.py:86
#: models.py:124
msgid "games"
msgstr "jeux"
#: templates/media/isbn_button.html:3
msgid "Fetch data"
msgstr "Télécharger les données"
#: validators.py:20
msgid "Invalid ISBN: Not a string"
msgstr "ISBN invalide : ce n'est pas une chaîne de caractères"
#: validators.py:23
msgid "Invalid ISBN: Wrong length"
msgstr "ISBN invalide : mauvaise longueur"
#: validators.py:26
msgid "Invalid ISBN: Failed checksum"
msgstr "ISBN invalide : mauvais checksum"
#: validators.py:29
msgid "Invalid ISBN: Only upper case allowed"
msgstr "ISBN invalide : seulement les majuscules sont autorisées"
#: views.py:41
msgid "Welcome to the Mediatek database"
msgstr "Bienvenue sur la base de données de la Mediatek"

View File

@ -1,46 +0,0 @@
// curl 'https://openlibrary.org/api/books?bibkeys=ISBN:0201558025&format=json&jscmd=data'
a = {
"ISBN:0201558025": {
"publishers": [{"name": "Addison-Wesley"}],
"pagination": "xiii, 657 p. :",
"identifiers": {
"lccn": ["93040325"],
"openlibrary": ["OL1429049M"],
"isbn_10": ["0201558025"],
"wikidata": ["Q15303722"],
"goodreads": ["112243"],
"librarything": ["45844"]
},
//"subtitle": "a foundation for computer science",
//"title": "Concrete mathematics",
//"url": "https://openlibrary.org/books/OL1429049M/Concrete_mathematics",
"classifications": {"dewey_decimal_class": ["510"], "lc_classifications": ["QA39.2 .G733 1994"]},
"notes": "Includes bibliographical references (p. 604-631) and index.",
"number_of_pages": 657,
"cover": {
"small": "https://covers.openlibrary.org/b/id/135182-S.jpg",
"large": "https://covers.openlibrary.org/b/id/135182-L.jpg",
"medium": "https://covers.openlibrary.org/b/id/135182-M.jpg"
},
"subjects": [{
"url": "https://openlibrary.org/subjects/computer_science",
"name": "Computer science"
}, {"url": "https://openlibrary.org/subjects/mathematics", "name": "Mathematics"}],
"publish_date": "1994",
"key": "/books/OL1429049M",
"authors": [{
"url": "https://openlibrary.org/authors/OL720958A/Ronald_L._Graham",
"name": "Ronald L. Graham"
}, {
"url": "https://openlibrary.org/authors/OL229501A/Donald_Knuth",
"name": "Donald Knuth"
}, {"url": "https://openlibrary.org/authors/OL2669938A/Oren_Patashnik", "name": "Oren Patashnik"}],
"by_statement": "Ronald L. Graham, Donald E. Knuth, Oren Patashnik.",
"publish_places": [{"name": "Reading, Mass"}],
"ebooks": [{
"formats": {},
"preview_url": "https://archive.org/details/concretemathemat00grah_444",
"availability": "restricted"
}]
}
}

View File

@ -0,0 +1,3 @@
{% load i18n %}
{% include "django/forms/widgets/input.html" %}
<input type="submit" value="{% trans "Fetch data" %}" name="_continue">

View File

@ -121,7 +121,7 @@ input[type=button]:focus, .button:hover, input[type=submit]:hover, input[type=bu
/* Pull footer to bottom */
#content {
min-height: calc(100vh - 190px);
min-height: calc(100vh - 220px);
}
.login #content {

View File

@ -103,7 +103,6 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
'<img src="/static/admin/img/icon-yes.svg" alt="True">'
)
else:
# TODO permit adhere only if perms.users.add_user
return format_html(
'<img src="/static/admin/img/icon-no.svg" alt="False"> '
'<a class="button" href="{}">{}</a>',