Validate ISBN before sending the request to Decitre. #28
This commit is contained in:
parent
65031511d0
commit
9cd41b5a3f
5 changed files with 62 additions and 7 deletions
19
manuels/migrations/0026_auto_20180616_0916.py
Normal file
19
manuels/migrations/0026_auto_20180616_0916.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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])
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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 }}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue