Commit 861279d3 authored by erdnaxe's avatar erdnaxe 🎇

Add ISBN data downloader

parent 2f872ecc
Pipeline #1418 passed with stage
in 3 minutes and 25 seconds
...@@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from med.admin import admin_site from med.admin import admin_site
from .forms import MediaAdminForm
from .models import Auteur, Emprunt, Jeu, Media from .models import Auteur, Emprunt, Jeu, Media
...@@ -17,16 +18,43 @@ class AuteurAdmin(VersionAdmin): ...@@ -17,16 +18,43 @@ class AuteurAdmin(VersionAdmin):
class MediaAdmin(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') search_fields = ('title', 'authors__nom', 'side_title', 'subtitle', 'isbn')
autocomplete_fields = ('authors',) autocomplete_fields = ('authors',)
date_hierarchy = 'publish_date' date_hierarchy = 'publish_date'
form = MediaAdminForm
def authors_list(self, obj): def authors_list(self, obj):
return ", ".join([a.nom for a in obj.authors.all()]) return ", ".join([a.nom for a in obj.authors.all()])
authors_list.short_description = _('authors') 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): class EmpruntAdmin(VersionAdmin):
list_display = ('media', 'user', 'date_emprunt', 'date_rendu', list_display = ('media', 'user', 'date_emprunt', 'date_rendu',
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay # Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import json
import urllib.request
from django.forms import ModelForm from django.forms import ModelForm
from .models import Emprunt from .models import Emprunt
...@@ -11,3 +14,45 @@ class EmpruntForm(ModelForm): ...@@ -11,3 +14,45 @@ class EmpruntForm(ModelForm):
class Meta: class Meta:
model = Emprunt model = Emprunt
fields = ['media'] 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 "" ...@@ -3,7 +3,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
...@@ -13,46 +13,106 @@ msgstr "" ...@@ -13,46 +13,106 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: admin.py:47 #: admin.py:31 models.py:20 models.py:51
msgid "authors"
msgstr "auteurs"
#: admin.py:38
msgid "external url"
msgstr "URL externe"
#: admin.py:78
msgid "Turn back" msgid "Turn back"
msgstr "Rendre" msgstr "Rendre"
#: admin.py:50 #: admin.py:81
msgid "permanencier rendu" msgid "permanencier rendu"
msgstr "" msgstr ""
#: models.py:17 #: fields.py:17
msgid "ISBN-10 or ISBN-13"
msgstr "ISBN-10 ou ISBN-13"
#: models.py:19
msgid "author" msgid "author"
msgstr "auteur" msgstr "auteur"
#: models.py:18 #: models.py:25
msgid "authors" msgid "ISBN"
msgstr "auteurs" 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:30 #: 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" msgid "medium"
msgstr "medium" msgstr "medium"
#: models.py:31 #: models.py:69
msgid "media" msgid "media"
msgstr "media" msgstr "media"
#: models.py:60 #: models.py:98
msgid "borrowed item" msgid "borrowed item"
msgstr "emprunt" msgstr "emprunt"
#: models.py:61 #: models.py:99
msgid "borrowed items" msgid "borrowed items"
msgstr "emprunts" msgstr "emprunts"
#: models.py:85 #: models.py:123
msgid "game" msgid "game"
msgstr "jeu" msgstr "jeu"
#: models.py:86 #: models.py:124
msgid "games" msgid "games"
msgstr "jeux" 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 #: views.py:41
msgid "Welcome to the Mediatek database" msgid "Welcome to the Mediatek database"
msgstr "Bienvenue sur la base de données de la Mediatek" msgstr "Bienvenue sur la base de données de la Mediatek"
// 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"
}]
}
}
\ No newline at end of file
{% load i18n %}
{% include "django/forms/widgets/input.html" %}
<input type="submit" value="{% trans "Fetch data" %}" name="_continue">
\ No newline at end of file
...@@ -121,7 +121,7 @@ input[type=button]:focus, .button:hover, input[type=submit]:hover, input[type=bu ...@@ -121,7 +121,7 @@ input[type=button]:focus, .button:hover, input[type=submit]:hover, input[type=bu
/* Pull footer to bottom */ /* Pull footer to bottom */
#content { #content {
min-height: calc(100vh - 190px); min-height: calc(100vh - 220px);
} }
.login #content { .login #content {
......
...@@ -103,7 +103,6 @@ class UserAdmin(VersionAdmin, BaseUserAdmin): ...@@ -103,7 +103,6 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
'<img src="/static/admin/img/icon-yes.svg" alt="True">' '<img src="/static/admin/img/icon-yes.svg" alt="True">'
) )
else: else:
# TODO permit adhere only if perms.users.add_user
return format_html( return format_html(
'<img src="/static/admin/img/icon-no.svg" alt="False"> ' '<img src="/static/admin/img/icon-no.svg" alt="False"> '
'<a class="button" href="{}">{}</a>', '<a class="button" href="{}">{}</a>',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment