Add ISBN data downloader
This commit is contained in:
parent
2f872eccce
commit
861279d30d
|
@ -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',
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
}]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{% load i18n %}
|
||||
{% include "django/forms/widgets/input.html" %}
|
||||
<input type="submit" value="{% trans "Fetch data" %}" name="_continue">
|
|
@ -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 {
|
||||
|
|
|
@ -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>',
|
||||
|
|
Loading…
Reference in New Issue