Validate ISBN before sending the request to Decitre. #28

This commit is contained in:
Gabriel Augendre 2018-06-16 09:26:10 +02:00
parent 65031511d0
commit 9cd41b5a3f
5 changed files with 62 additions and 7 deletions

View file

@ -0,0 +1,19 @@
# Generated by Django 2.0.6 on 2018-06-16 07:16
from django.db import migrations, models
import manuels.models
class Migration(migrations.Migration):
dependencies = [
('manuels', '0025_auto_20180607_0746'),
]
operations = [
migrations.AlterField(
model_name='book',
name='isbn',
field=models.CharField(help_text="Format attendu : 10 ou 13 chiffres, éventuellement séparés par des tirets et éventuellement suivis de la lettre <code>X</code>. La recherche sur Decitre ne fonctionnera qu'avec un code ISBN à13 chiffres (ou EAN)", max_length=20, validators=[manuels.models.isbn_validator], verbose_name='ISBN/EAN'),
),
]

View file

@ -158,7 +158,8 @@ class Book(BaseModel):
'ISBN/EAN', 'ISBN/EAN',
max_length=20, max_length=20,
help_text="Format attendu : 10 ou 13 chiffres, éventuellement séparés par des tirets et éventuellement " help_text="Format attendu : 10 ou 13 chiffres, éventuellement séparés par des tirets et éventuellement "
"suivis de la lettre <code>X</code>", "suivis de la lettre <code>X</code>. La recherche sur Decitre ne fonctionnera qu'avec un code ISBN à"
"13 chiffres (ou EAN)",
validators=[isbn_validator] validators=[isbn_validator]
) )
price = models.FloatField('prix', validators=[positive_float_validator]) price = models.FloatField('prix', validators=[positive_float_validator])

View file

@ -7,13 +7,14 @@ document.addEventListener("DOMContentLoaded", function (event) {
isbn.classList.add('is-invalid'); isbn.classList.add('is-invalid');
isbn.classList.remove('is-valid'); isbn.classList.remove('is-valid');
document.querySelector('#id_isbn_invalid_feedback').style.display = 'block'; document.querySelector('#id_isbn_invalid_feedback').style.display = 'block';
document.querySelector('#id_isbn_error_text').textContent = data.error; document.querySelector('#id_isbn_invalid_feedback').textContent = data.error;
return; return;
} }
isbn.classList.remove('is-invalid'); isbn.classList.remove('is-invalid');
isbn.classList.add('is-valid'); isbn.classList.add('is-valid');
document.querySelector('#id_isbn_invalid_feedback').style.display = 'none'; document.querySelector('#id_isbn_invalid_feedback').style.display = 'none';
document.querySelector('#id_isbn_invalid_feedback').textContent = '';
document.querySelector('#id_title').value = data.title; document.querySelector('#id_title').value = data.title;
document.querySelector('#id_title').classList.add('is-valid'); document.querySelector('#id_title').classList.add('is-valid');

View file

@ -53,10 +53,6 @@
</div> </div>
</div> </div>
<div class="invalid-feedback" id="id_isbn_invalid_feedback"> <div class="invalid-feedback" id="id_isbn_invalid_feedback">
Erreur lors de la recherche. Il se peut que le livre n'existe pas dans la base de connaissance de
Decitre ou que vous ayez mal saisi l'ISBN.
Veuillez saisir les informations du livre à la main.<br>
Données techniques : <span id="id_isbn_error_text"></span>
</div> </div>
<small class="form-text text-muted"> <small class="form-text text-muted">
{{ form.isbn.help_text|safe }} {{ form.isbn.help_text|safe }}

View file

@ -227,15 +227,53 @@ class ConfirmTeacherView(BaseTeacherView, UpdateView):
return response return response
def validate_isbn(isbn):
_sum = 0
if len(isbn) == 10:
for i, digit in enumerate(isbn):
if digit == 'X':
digit = 10
else:
digit = int(digit)
_sum += digit * (i + 1)
return _sum % 11 == 0
elif len(isbn) == 13:
for i, digit in enumerate(isbn):
weight = 3 if i % 2 == 1 else 1
digit = int(digit)
_sum += digit * weight
return _sum % 10 == 0
return False
@cache_page(None) @cache_page(None)
def isbn_api(request, isbn): def isbn_api(request, isbn):
isbn = isbn.strip().replace('-', '')
if not validate_isbn(isbn):
return JsonResponse({
'error': "L'ISBN saisi n'est pas valide."
})
if len(isbn) == 10:
return JsonResponse({
'error': "La recherche sur Decitre ne fonctionne qu'avec un ISBN 13 (ou EAN)."
})
res = requests.get(f'https://www.decitre.fr/livres/{isbn}.html') res = requests.get(f'https://www.decitre.fr/livres/{isbn}.html')
try: try:
res.raise_for_status() res.raise_for_status()
except Exception as exc: except Exception as exc:
message = ("Erreur lors de la recherche. Il se peut que le livre n'existe pas dans la base de connaissances "
"de Decitre ou que vous ayez mal saisi l'ISBN. Vous pouvez toujours saisir "
"les informations du livre à la main. Message : {}").format(str(exc))
return JsonResponse({ return JsonResponse({
'error': str(exc) 'error': message
}) })
decitre_soup = bs4.BeautifulSoup(res.text, "html.parser") decitre_soup = bs4.BeautifulSoup(res.text, "html.parser")