Commit 45beb14c authored by erdnaxe's avatar erdnaxe 🎇

Add media data

parent 80ede363
......@@ -12,6 +12,7 @@ django-haystack = "*"
django-filter = "*"
djangorestframework = "*"
drf-haystack = "*"
python-stdnum = "*"
[dev-packages]
......
{
"_meta": {
"hash": {
"sha256": "9a1046095316374937efaa29cdaaeaeec950596c616322db363323f0e49d8d4e"
"sha256": "c74f1d97a59c731414c81eece7ccabf0ec4faadb97bcd88152058324554bd1ff"
},
"pipfile-spec": 6,
"requires": {
......@@ -86,6 +86,14 @@
],
"version": "==2.7.5"
},
"python-stdnum": {
"hashes": [
"sha256:b67f395fc6a17bd913671a6e0d5543f1c33baf6a262ada1a613b08c01970817a",
"sha256:caa050aed5d1d4825cc3294c99dc03d498aaf71f4415d659c9fcb58ff0303a5f"
],
"index": "pypi",
"version": "==1.10"
},
"pytz": {
"hashes": [
"sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
......
......@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-01-30 21:44+0100\n"
"POT-Creation-Date: 2019-01-30 22:03+0100\n"
"PO-Revision-Date: 2019-01-24 08:55+0100\n"
"Last-Translator: Alexandre Iooss <erdnaxe@crans.org>\n"
"Language: FR\n"
......
......@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-01-30 21:44+0100\n"
"POT-Creation-Date: 2019-01-30 22:03+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Alexandre Iooss <erdnaxe@crans.org>\n"
"Language: FR\n"
......
......@@ -17,7 +17,8 @@ class AuthorAdmin(VersionAdmin):
@admin.register(Media)
class MediaAdmin(VersionAdmin):
list_display = ('title', 'get_authors', 'side_title')
list_display = ('title', 'side_title', 'get_authors', 'isbn', 'edition',
'publisher', 'published_on')
@staticmethod
def get_authors(obj):
......
"""
Based on https://github.com/secnot/django-isbn-field
"""
from django.core.validators import EMPTY_VALUES
from django.db.models import CharField
from django.utils.translation import gettext_lazy as _
from .validators import isbn_validator
class ISBNField(CharField):
description = _("ISBN-10 or ISBN-13")
def __init__(self, clean_isbn=True, *args, **kwargs):
self.clean_isbn = clean_isbn
kwargs['max_length'] = kwargs[
'max_length'] if 'max_length' in kwargs else 28
kwargs['verbose_name'] = kwargs[
'verbose_name'] if 'verbose_name' in kwargs else u'ISBN'
kwargs['validators'] = [isbn_validator]
super(ISBNField, self).__init__(*args, **kwargs)
def formfield(self, **kwargs):
defaults = {
'min_length': 10,
'validators': [isbn_validator],
}
defaults.update(kwargs)
return super(ISBNField, self).formfield(**defaults)
def deconstruct(self):
name, path, args, kwargs = super(ISBNField, self).deconstruct()
# Only include clean_isbn in kwarg if it's not the default value
if not self.clean_isbn:
kwargs['clean_isbn'] = self.clean_isbn
return name, path, args, kwargs
def pre_save(self, model_instance, add):
"""Remove dashes, spaces, and convert isbn to uppercase before saving
when clean_isbn is enabled"""
value = getattr(model_instance, self.attname)
if self.clean_isbn and value not in EMPTY_VALUES:
cleaned_isbn = value.replace(' ', '').replace('-', '').upper()
setattr(model_instance, self.attname, cleaned_isbn)
return super(ISBNField, self).pre_save(model_instance, add)
def __unicode__(self):
return self.value
......@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-01-30 21:44+0100\n"
"POT-Creation-Date: 2019-01-30 22:03+0100\n"
"PO-Revision-Date: 2019-01-27 08:46+0100\n"
"Last-Translator: Alexandre Iooss <erdnaxe@crans.org>\n"
"Language: FR\n"
......@@ -12,107 +12,131 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: media/apps.py:7 media/models.py:33 media/models.py:34 media/models.py:41
#: media/apps.py:7 media/models.py:63 media/models.py:64 media/models.py:71
msgid "media"
msgstr "media"
#: media/models.py:7 media/models.py:82 media/models.py:94
#: media/fields.py:13
msgid "ISBN-10 or ISBN-13"
msgstr ""
#: media/models.py:9 media/models.py:112 media/models.py:124
msgid "name"
msgstr "nom"
#: media/models.py:14 media/models.py:26
#: media/models.py:16 media/models.py:28
msgid "author"
msgstr "auteur"
#: media/models.py:15
#: media/models.py:17
msgid "authors"
msgstr "auteurs"
#: media/models.py:19
#: media/models.py:21
msgid "title"
msgstr "titre"
#: media/models.py:21
#: media/models.py:23
msgid "side title"
msgstr "côte"
#: media/models.py:46
#: media/models.py:30
msgid "ISBN"
msgstr "ISBN"
#: media/models.py:35
msgid "edition"
msgstr "édition"
#: media/models.py:41
msgid "binding"
msgstr "reliure"
#: media/models.py:47
msgid "publisher"
msgstr "éditeur"
#: media/models.py:53
msgid "published on"
msgstr "édité le"
#: media/models.py:76
msgid "borrower"
msgstr "emprunteur"
#: media/models.py:48
#: media/models.py:78
msgid "borrowed at"
msgstr "emprunté le"
#: media/models.py:50
#: media/models.py:80
msgid "given back at"
msgstr "rendu le"
#: media/models.py:58
#: media/models.py:88
msgid "borrowed with permanent"
msgstr "emprunté avec le permanencier"
#: media/models.py:66
#: media/models.py:96
msgid "given back with permanent"
msgstr "rendu avec le permanencier"
#: media/models.py:77
#: media/models.py:107
msgid "borrowed media"
msgstr "media emprunté"
#: media/models.py:78
#: media/models.py:108
msgid "borrowed medias"
msgstr "media empruntés"
#: media/models.py:89 media/models.py:100
#: media/models.py:119 media/models.py:130
msgid "game type"
msgstr "type de jeu"
#: media/models.py:90
#: media/models.py:120
msgid "game types"
msgstr "types de jeu"
#: media/models.py:105
#: media/models.py:135
msgid "owner"
msgstr "propriétaire"
#: media/models.py:108
#: media/models.py:138
msgid "length"
msgstr "durée"
#: media/models.py:121
#: media/models.py:151
msgid "minimum number of players"
msgstr "nombre minimum de joueurs"
#: media/models.py:127
#: media/models.py:157
msgid "maximum number of players"
msgstr "nombre maximum de joueurs"
#: media/models.py:133
#: media/models.py:163
msgid "box length"
msgstr "longueur de la boîte"
#: media/models.py:138
#: media/models.py:168
msgid "box width"
msgstr "largeur de la boîte"
#: media/models.py:143
#: media/models.py:173
msgid "box depth"
msgstr "hauteur de la boîte"
#: media/models.py:148
#: media/models.py:178
msgid "last time it was the week game"
msgstr "dernière fois qu'il a été jeu de la semaine"
#: media/models.py:153
#: media/models.py:183
msgid "comment"
msgstr "commentaire"
#: media/models.py:164
#: media/models.py:194
msgid "game"
msgstr "jeu"
#: media/models.py:165
#: media/models.py:195
msgid "games"
msgstr "jeux"
......@@ -139,3 +163,19 @@ msgstr ""
#: media/templates/media/index.html:22
msgid "Apply filter"
msgstr "Appliquer le filtre"
#: media/validators.py:16
msgid "Invalid ISBN: Not a string"
msgstr "ISBN invalide : Pas une chaîne de caractères"
#: media/validators.py:19
msgid "Invalid ISBN: Wrong length"
msgstr "ISBN invalide : Mauvaise longueur"
#: media/validators.py:22
msgid "Invalid ISBN: Failed checksum"
msgstr "ISBN invalide : Mauvaise somme de contrôle"
#: media/validators.py:25
msgid "Invalid ISBN: Only upper case allowed"
msgstr "ISBN invalide : Seul les majuscules sont autorisées"
# Generated by Django 2.1.5 on 2019-01-30 21:02
from django.db import migrations, models
import media.fields
import media.validators
class Migration(migrations.Migration):
dependencies = [
('media', '0007_add_game_data'),
]
operations = [
migrations.AddField(
model_name='media',
name='binding',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='binding'),
),
migrations.AddField(
model_name='media',
name='edition',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='edition'),
),
migrations.AddField(
model_name='media',
name='isbn',
field=media.fields.ISBNField(blank=True, max_length=28, null=True, validators=[media.validators.isbn_validator], verbose_name='ISBN'),
),
migrations.AddField(
model_name='media',
name='published_on',
field=models.DateField(blank=True, null=True, verbose_name='published on'),
),
migrations.AddField(
model_name='media',
name='publisher',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='publisher'),
),
]
......@@ -2,6 +2,8 @@ from django.core.validators import MinValueValidator
from django.db import models
from django.utils.translation import gettext_lazy as _
from .fields import ISBNField
class Author(models.Model):
name = models.CharField(_('name'), max_length=255, unique=True)
......@@ -24,6 +26,34 @@ class Media(models.Model):
null=True,
)
author = models.ManyToManyField('Author', verbose_name=_('author'))
isbn = ISBNField(
_('ISBN'),
blank=True,
null=True,
)
edition = models.CharField(
_('edition'),
max_length=255,
blank=True,
null=True,
)
binding = models.CharField(
_('binding'),
max_length=255,
blank=True,
null=True,
)
publisher = models.CharField(
_('publisher'),
max_length=255,
blank=True,
null=True,
)
published_on = models.DateField(
_('published on'),
blank=True,
null=True,
)
def __str__(self):
return "Media {} by {}".format(self.title, self.author.all().first())
......
......@@ -26,7 +26,8 @@ class AuthorTable(BaseTable):
class MediaTable(BaseTable):
class Meta(BaseTable.Meta):
model = Media
fields = ('title', 'author', 'side_title')
fields = ('title', 'side_title', 'author', 'isbn', 'edition',
'publisher', 'published_on')
class GamesTable(BaseTable):
......
"""
Based on https://github.com/secnot/django-isbn-field
"""
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from six import string_types
from stdnum import isbn
def isbn_validator(raw_isbn):
"""Check string is a valid ISBN number"""
isbn_to_check = raw_isbn.replace('-', '').replace(' ', '')
if not isinstance(isbn_to_check, string_types):
raise ValidationError(_(u'Invalid ISBN: Not a string'))
if len(isbn_to_check) != 10 and len(isbn_to_check) != 13:
raise ValidationError(_(u'Invalid ISBN: Wrong length'))
if not isbn.is_valid(isbn_to_check):
raise ValidationError(_(u'Invalid ISBN: Failed checksum'))
if isbn_to_check != isbn_to_check.upper():
raise ValidationError(_(u'Invalid ISBN: Only upper case allowed'))
return True
......@@ -53,6 +53,9 @@ class MediaIndex(PermissionRequiredMixin, SingleTableMixin, FilterView):
filterset_fields = {
'title': ['contains'],
'author': ['exact'],
'isbn': ['contains'],
'edition': ['contains'],
'publisher': ['contains'],
}
def get_context_data(self, **kwargs):
......
......@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-01-30 21:44+0100\n"
"POT-Creation-Date: 2019-01-30 22:03+0100\n"
"PO-Revision-Date: 2019-01-27 08:56+0100\n"
"Last-Translator: Alexandre Iooss <erdnaxe@crans.org>\n"
"Language: FR\n"
......
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