jsmin
fnp-django-pagination==2.2.3
django-maintenancemode==0.11.3
-jsonfield==2.0.2
django-picklefield==1.1.0
django-modeltranslation==0.13
django-allauth==0.39
def item_description(self, item):
lines = []
- artist = item.extra_info.get('artist_name', None)
+ extra_info = item.get_extra_info_json()
+ artist = extra_info.get('artist_name', None)
if artist is not None:
lines.append(u'Czyta: %s' % artist)
- director = item.extra_info.get('director_name', None)
+ director = extra_info.get('director_name', None)
if director is not None:
lines.append(u'Reżyseria: %s' % director)
return u'<br/>\n'.join(lines)
name: Parent Audiobook
file: mp3/parent.mp3
uploaded_at: "1970-01-03 0:0Z"
- extra_info: {"director_name": "Director", "artist_name": "Artist"}
+ extra_info: '{"director_name": "Director", "artist_name": "Artist"}'
- model: catalogue.bookmedia
fields:
book: 1
def ancestor_has_cover(book):
while book.parent:
book = book.parent
- if book.extra_info.get('cover_url'):
+ if book.get_extra_info_json().get('cover_url'):
return True
return False
with transaction.atomic():
for book in Book.objects.all().order_by('slug').iterator():
- extra_info = book.extra_info
+ extra_info = book.get_extra_info_json()
if not extra_info.get('cover_url'):
if ancestor_has_cover(book):
with_ancestral_cover.append(book)
for book in no_license:
print()
print(full_url(book))
- print(book.extra_info.get('cover_by'))
- print(book.extra_info.get('cover_source'))
- print(book.extra_info.get('cover_url'))
+ extra_info = book.get_extra_info_json()
+ print(extra_info.get('cover_by'))
+ print(extra_info.get('cover_source'))
+ print(extra_info.get('cover_url'))
if not_redakcja:
print()
for book in not_redakcja:
print()
print(full_url(book))
- print(book.extra_info.get('cover_by'))
- print(book.extra_info.get('cover_source'))
- print(book.extra_info.get('cover_url'))
+ extra_info = book.get_extra_info_json()
+ print(extra_info.get('cover_by'))
+ print(extra_info.get('cover_source'))
+ print(extra_info.get('cover_url'))
if without_cover:
print()
Book,
[
('wiki_link', lambda b: b.wiki_link),
- ('źródło', lambda b: b.extra_info.get('source_url')),
+ ('źródło', lambda b: b.get_extra_info_json().get('source_url')),
],
'admin:catalogue_book_change'
),
Picture,
[
('wiki_link', lambda p: p.wiki_link),
- ('źródło', lambda p: p.extra_info.get('source_url')),
+ ('źródło', lambda p: p.get_extra_info_json().get('source_url')),
],
'admin:pictures_picture_change'
)
print(
('Administracja: https://%s%s' % (domain, reverse(admin_name, args=[obj.pk])))
.encode('utf-8'))
- if obj.extra_info.get('about'):
- print(('Redakcja: %s' % (obj.extra_info.get('about'),)).encode('utf-8'))
+ if obj.get_extra_info_json().get('about'):
+ print(('Redakcja: %s' % (obj.get_extra_info_json().get('about'),)).encode('utf-8'))
print((' %s (%s): %s' % (name, getattr(e, 'code', 'błąd'), url)).encode('utf-8'))
if not clean:
print()
from django.db import models, migrations
import django.db.models.deletion
import fnpdjango.storage
-import jsonfield.fields
import catalogue.fields
import catalogue.models.bookmedia
from django.conf import settings
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='creation date', db_index=True)),
('changed_at', models.DateTimeField(auto_now=True, verbose_name='creation date', db_index=True)),
('parent_number', models.IntegerField(default=0, verbose_name='Parent number')),
- ('extra_info', jsonfield.fields.JSONField(default={}, verbose_name='Additional information')),
+ ('extra_info', models.TextField(default='{}', verbose_name='Additional information')),
('gazeta_link', models.CharField(max_length=240, blank=True)),
('wiki_link', models.CharField(max_length=240, blank=True)),
('cover', catalogue.fields.EbookField('cover', upload_to=catalogue.models.book._cover_upload_to, storage=fnpdjango.storage.BofhFileSystemStorage(), max_length=255, blank=True, null=True, verbose_name='cover')),
('cover_thumb', catalogue.fields.EbookField('cover_thumb', max_length=255, upload_to=catalogue.models.book._cover_thumb_upload_to, null=True, verbose_name='cover thumbnail', blank=True)),
- ('_related_info', jsonfield.fields.JSONField(null=True, editable=False, blank=True)),
+ ('_related_info', models.TextField(null=True, editable=False, blank=True)),
('txt_file', catalogue.fields.EbookField('txt', default='', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._txt_upload_to, max_length=255, blank=True, verbose_name='TXT file')),
('fb2_file', catalogue.fields.EbookField('fb2', default='', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._fb2_upload_to, max_length=255, blank=True, verbose_name='FB2 file')),
('pdf_file', catalogue.fields.EbookField('pdf', default='', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._pdf_upload_to, max_length=255, blank=True, verbose_name='PDF file')),
('name', models.CharField(max_length=512, verbose_name='name')),
('file', catalogue.fields.OverwritingFileField(upload_to=catalogue.models.bookmedia._file_upload_to, max_length=600, verbose_name='XML file')),
('uploaded_at', models.DateTimeField(auto_now_add=True, verbose_name='creation date', db_index=True)),
- ('extra_info', jsonfield.fields.JSONField(default={}, verbose_name='Additional information', editable=False)),
+ ('extra_info', models.TextField(default='{}', verbose_name='Additional information', editable=False)),
('source_sha1', models.CharField(max_length=40, null=True, editable=False, blank=True)),
('book', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='media', to='catalogue.Book')),
],
from __future__ import unicode_literals
from django.db import migrations, models
-import jsonfield.fields
import catalogue.fields
import catalogue.models.bookmedia
migrations.AlterField(
model_name='book',
name='extra_info',
- field=jsonfield.fields.JSONField(default={}, verbose_name='extra information'),
+ field=models.TextField(default='{}', verbose_name='extra information'),
),
migrations.AlterField(
model_name='book',
migrations.AlterField(
model_name='bookmedia',
name='extra_info',
- field=jsonfield.fields.JSONField(default={}, verbose_name='extra information', editable=False),
+ field=models.TextField(default='{}', verbose_name='extra information', editable=False),
),
migrations.AlterField(
model_name='bookmedia',
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
from django.db import migrations, models
book.cached_author = ', '.join(
TagRelation.objects.filter(content_type__model='book', object_id=book.id, tag__category='author')
.values_list('tag__name', flat=True))
- book.has_audience = 'audience' in book.extra_info
+ book.has_audience = 'audience' in book.get_extra_info_json()
book.save()
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from collections import OrderedDict
+import json
from datetime import date, timedelta
from random import randint
import os.path
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _, get_language
from django.utils.deconstruct import deconstructible
-import jsonfield
from fnpdjango.storage import BofhFileSystemStorage
from librarian.cover import WLCover
created_at = models.DateTimeField(_('creation date'), auto_now_add=True, db_index=True)
changed_at = models.DateTimeField(_('change date'), auto_now=True, db_index=True)
parent_number = models.IntegerField(_('parent number'), default=0)
- extra_info = jsonfield.JSONField(_('extra information'), default={})
+ extra_info = models.TextField(_('extra information'), default='{}')
gazeta_link = models.CharField(blank=True, max_length=240)
wiki_link = models.CharField(blank=True, max_length=240)
print_on_demand = models.BooleanField(_('print on demand'), default=False)
def __str__(self):
return self.title
+ def get_extra_info_json(self):
+ return json.loads(self.extra_info or '{}')
+
def get_initial(self):
try:
return re.search(r'\w', self.title, re.U).group(0)
return self.tag_unicode('genre')
def translator(self):
- translators = self.extra_info.get('translators')
+ translators = self.get_extra_info_json().get('translators')
if not translators:
return None
if len(translators) > 3:
return ', '.join(u'\xa0'.join(reversed(translator.split(', ', 1))) for translator in translators) + others
def cover_source(self):
- return self.extra_info.get('cover_source', self.parent.cover_source() if self.parent else '')
+ return self.get_extra_info_json().get('cover_source', self.parent.cover_source() if self.parent else '')
def save(self, force_insert=False, force_update=False, **kwargs):
from sortify import sortify
self.sort_key_author = author
self.cached_author = self.tag_unicode('author')
- self.has_audience = 'audience' in self.extra_info
+ self.has_audience = 'audience' in self.get_extra_info_json()
if self.preview and not self.preview_key:
self.preview_key = get_random_hash(self.slug)[:32]
projects = set()
for mp3 in self.media.filter(type='mp3').iterator():
# ogg files are always from the same project
- meta = mp3.extra_info
+ meta = mp3.get_extra_info_json()
project = meta.get('project')
if not project:
# temporary fallback
def zip_format(format_):
def pretty_file_name(book):
return "%s/%s.%s" % (
- book.extra_info['author'],
+ book.get_extra_info_json()['author'],
book.slug,
format_)
book.common_slug = book_info.variant_of.slug
else:
book.common_slug = book.slug
- book.extra_info = book_info.to_dict()
+ book.extra_info = json.dumps(book_info.to_dict())
book.load_abstract()
book.save()
need = False
info = {}
for field in ('cover_url', 'cover_by', 'cover_source'):
- val = self.extra_info.get(field)
+ val = self.get_extra_info_json().get(field)
if val:
info[field] = val
else:
return ', '.join(names)
def publisher(self):
- publisher = self.extra_info['publisher']
+ publisher = self.get_extra_info_json()['publisher']
if isinstance(publisher, str):
return publisher
elif isinstance(publisher, list):
}
def audiences_pl(self):
- audiences = self.extra_info.get('audiences', [])
+ audiences = self.get_extra_info_json().get('audiences', [])
audiences = sorted(set([self._audiences_pl.get(a, (99, a)) for a in audiences]))
return [a[1] for a in audiences]
def stage_note(self):
- stage = self.extra_info.get('stage')
+ stage = self.get_extra_info_json().get('stage')
if stage and stage < '0.4':
return (_('This work needs modernisation'),
reverse('infopage', args=['wymagajace-uwspolczesnienia']))
return self.SORT_KEY_SEP.join((self.sort_key_author, self.sort_key, str(self.id)))
def cover_color(self):
- return WLCover.epoch_colors.get(self.extra_info.get('epoch'), '#000000')
+ return WLCover.epoch_colors.get(self.get_extra_info_json().get('epoch'), '#000000')
@cached_render('catalogue/book_mini_box.html')
def mini_box(self):
from collections import namedtuple
from django.db import models
from django.utils.translation import ugettext_lazy as _
-import jsonfield
from slugify import slugify
from mutagen import MutagenError
index = models.IntegerField(_('index'), default=0)
file = models.FileField(_('file'), max_length=600, upload_to=_file_upload_to, storage=OverwriteStorage())
uploaded_at = models.DateTimeField(_('creation date'), auto_now_add=True, editable=False, db_index=True)
- extra_info = jsonfield.JSONField(_('extra information'), default={}, editable=False)
+ extra_info = models.TextField(_('extra information'), default='{}', editable=False)
book = models.ForeignKey('Book', models.CASCADE, related_name='media')
source_sha1 = models.CharField(null=True, blank=True, max_length=40, editable=False)
verbose_name_plural = _('book media')
app_label = 'catalogue'
+ def get_extra_info_json(self):
+ return json.loads(self.extra_info or '{}')
+
def save(self, parts_count=None, *args, **kwargs):
from catalogue.utils import ExistingFile, remove_zip
remove_zip("%s_%s" % (old.book.slug, old.type))
remove_zip("%s_%s" % (self.book.slug, self.type))
- extra_info = self.extra_info
- if isinstance(extra_info, str):
- # Walkaround for weird jsonfield 'no-decode' optimization.
- extra_info = json.loads(extra_info)
+ extra_info = self.get_extra_info_json()
extra_info.update(self.read_meta())
- self.extra_info = extra_info
+ self.extra_info = json.dumps(extra_info)
self.source_sha1 = self.read_source_sha1(self.file.path, self.type)
return super(BookMedia, self).save(*args, **kwargs)
@property
def director(self):
- return self.extra_info.get('director_name', None)
+ return self.get_extra_info_json().get('director_name', None)
@property
def artist(self):
- return self.extra_info.get('artist_name', None)
+ return self.get_extra_info_json().get('artist_name', None)
def file_url(self):
return self.file.url
# and invalidate their cached includes.
if old_name != self.name or old_netloc != self.netloc:
for book in Book.objects.all():
- source = book.extra_info.get('source_url', '')
+ source = book.get_extra_info_json().get('source_url', '')
if self.netloc in source or (old_netloc != self.netloc and old_netloc in source):
book.clear_cache()
return ret
{% load i18n %}
{% load catalogue_tags %}
+{% with extra_info=book.get_extra_info_json %}
<p>
- {% if book.extra_info.license %}
+ {% if extra_info.license %}
{% trans "This work is licensed under:" %}
- <a href="{{ book.extra_info.license }}">{{ book.extra_info.license_description }}</a>
+ <a href="{{ extra_info.license }}">{{ extra_info.license_description }}</a>
{% else %}
{% blocktrans %}This work isn't covered by copyright and is part of the
public domain, which means it can be freely used, published and
{% endif %}
</p>
-{% if book.extra_info.source_name %}
- <p>{% trans "Resource prepared based on:" %} {{ book.extra_info.source_name }}</p>
+{% if extra_info.source_name %}
+ <p>{% trans "Resource prepared based on:" %} {{ extra_info.source_name }}</p>
{% endif %}
-{% if book.extra_info.description %}
- <p>{{ book.extra_info.description }}</p>
+{% if extra_info.description %}
+ <p>{{ extra_info.description }}</p>
{% endif %}
-{% if book.extra_info.editor or book.extra_info.technical_editor %}
+{% if extra_info.editor or extra_info.technical_editor %}
<p>
{% if is_picture %}
{% trans "Edited by:" %}
{% else %}
{% trans "Edited and annotated by:" %}
{% endif %}
- {% all_editors book.extra_info %}.
+ {% all_editors extra_info %}.
</p>
{% endif %}
-{% if book.extra_info.publisher %}
+{% if extra_info.publisher %}
<p>
{% trans "Publisher:" %}
{{ book.publisher }}
</p>
{% endif %}
-{% if book.extra_info.funders %}
+{% if extra_info.funders %}
<p>
{% trans "Publication funded by:" %}
- {% for funder in book.extra_info.funders %}{{ funder }}{% if not forloop.last %}, {% else %}.{% endif %}{% endfor %}
+ {% for funder in extra_info.funders %}{{ funder }}{% if not forloop.last %}, {% else %}.{% endif %}{% endfor %}
</p>
{% endif %}
-{% if book.extra_info.cover_by %}
+{% if extra_info.cover_by %}
<p>
{% trans "Cover image by:" %}
- <a href="{{ book.extra_info.cover_source }}">{{ book.extra_info.cover_by }}</a>.
+ <a href="{{ extra_info.cover_source }}">{{ extra_info.cover_by }}</a>.
</p>
{% endif %}
-{% if book.extra_info.isbn_html %}
+{% if extra_info.isbn_html %}
<p>
- {{ book.extra_info.isbn_html }}
+ {{ extra_info.isbn_html }}
</p>
{% endif %}
+
+{% endwith %}
{% endfor %}
</span></span>
- {% if book.extra_info.location %}
- <span class="category">
- <span class="mono"> {% trans "Region" %}:</span> <span class="book-box-tag">
- {{ book.extra_info.location }}
- </span></span>
- {% endif %}
+ {% with extra_info=book.get_extra_info_json %}
+ {% if extra_info.location %}
+ <span class="category">
+ <span class="mono"> {% trans "Region" %}:</span> <span class="book-box-tag">
+ {{ extra_info.location }}
+ </span></span>
+ {% endif %}
+ {% endwith %}
{% if book.is_foreign %}
<span class="category">
{% block cover-area-extra %}
- {% if book.extra_info.license %}
- {% license_icon book.extra_info.license %}
- {% endif %}
+ {% with license=book.get_extra_info_json.license %}
+ {% if license %}
+ {% license_icon license %}
+ {% endif %}
+ {% endwith %}
{% endblock %}
<li data-mp3='{{ i.mp3.file.url }}' data-ogg='{{ i.ogg.file.url }}'>
<div class='play'>{{ i.mp3.name }}
<div class='extra-info'>
- {% trans "Artist:" %} <span class='artist'>{{ i.mp3.extra_info.artist_name }}</span>,
- {% trans "director:" %} <span class='director'>{{ i.mp3.extra_info.director_name }}</span>
+ {% with extra_info=i.mp3.get_extra_info_json %}
+ {% trans "Artist:" %} <span class='artist'>{{ extra_info.artist_name }}</span>,
+ {% trans "director:" %} <span class='director'>{{ extra_info.director_name }}</span>
<p>
- {% with fb=i.mp3.extra_info.funded_by %}
+ {% with fb=extra_info.funded_by %}
{% if fb %}Dofinansowano ze środków: {{ fb }}.{% endif %}
{% endwith %}
</p>
+ {% endwith %}
</div>
</div>
</li>
def get_isbn(request, book_format, slug):
book = Book.objects.get(slug=slug)
- return HttpResponse(book.extra_info.get('isbn_%s' % book_format))
+ return HttpResponse(book.get_extra_info_json().get('isbn_%s' % book_format))
-# -*- coding: utf-8 -*-
import csv
import json
except BaseException:
return ''
else:
- return Contact.pretty_print(obj.body.get(field_name, ''), for_html=True)
+ return Contact.pretty_print(obj.get_body_json().get(field_name, ''), for_html=True)
def __getattr__(self, name):
if name.startswith('admin_list_'):
if object_id:
try:
instance = Contact.objects.get(pk=object_id)
- assert isinstance(instance.body, dict)
+ body = instance.get_body_json()
+ assert isinstance(body, dict)
except (Contact.DoesNotExist, AssertionError):
pass
else:
# Create readonly fields from the body JSON.
attachments = list(instance.attachment_set.all())
- body_keys = instance.body.keys() + [a.tag for a in attachments]
+ body_keys = body.keys() + [a.tag for a in attachments]
# Find the original form.
try:
f.short_description = orig_fields[key].label if key in orig_fields else _(key)
setattr(self, "body__%s" % key, f)
- for k, v in instance.body.items():
+ for k, v in body.items():
attach_getter(k, Contact.pretty_print(v, for_html=True))
download_link = "<a href='%(url)s'>%(url)s</a>"
if extract_type_slug == 'contacts':
keys = ['contact']
elif extract_type_slug == 'all':
- keys = contact.body.keys() + ['contact']
+ keys = contact.get_body_json().keys() + ['contact']
keys = [key for key in orig_keys if key in keys] + [key for key in keys if key not in orig_keys]
else:
keys = form.get_extract_fields(contact, extract_type_slug)
if extract_type_slug == 'contacts':
records = [dict(contact=contact.contact)]
elif extract_type_slug == 'all':
- records = [dict(contact=contact.contact, **contact.body)]
+ records = [dict(contact=contact.contact, **contact.get_body_json())]
else:
records = form.get_extract_records(keys, contact, extract_type_slug)
+import json
from django.contrib.sites.models import Site
from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import UploadedFile
body.setdefault(f.form_tag, []).append(sub_body)
contact = Contact.objects.create(
- body=body,
+ body=json.dumps(body),
ip=request.META['REMOTE_ADDR'],
contact=self.cleaned_data['contact'],
form_tag=self.form_tag)
from django.db import migrations, models
import django.db.models.deletion
-import jsonfield.fields
class Migration(migrations.Migration):
('ip', models.GenericIPAddressField(verbose_name='IP address')),
('contact', models.EmailField(max_length=128, verbose_name='contact')),
('form_tag', models.CharField(max_length=32, verbose_name='form', db_index=True)),
- ('body', jsonfield.fields.JSONField(verbose_name='body')),
+ ('body', models.TextField(verbose_name='body')),
],
options={
'ordering': ('-created_at',),
+import json
import yaml
from hashlib import sha1
from django.db import models
from django.urls import reverse
from django.utils.encoding import smart_text
from django.utils.translation import ugettext_lazy as _
-from jsonfield import JSONField
from . import app_settings
ip = models.GenericIPAddressField(_('IP address'))
contact = models.EmailField(_('contact'), max_length=128)
form_tag = models.CharField(_('form'), max_length=32, db_index=True)
- body = JSONField(_('body'))
+ body = models.TextField(_('body'))
@staticmethod
def pretty_print(value, for_html=False):
return str(self.created_at)
def digest(self):
- serialized_body = ';'.join(sorted('%s:%s' % item for item in self.body.items()))
+ serialized_body = ';'.join(sorted('%s:%s' % item for item in self.get_body_json().items()))
data = '%s%s%s%s%s' % (self.id, self.contact, serialized_body, self.ip, self.form_tag)
return sha1(data).hexdigest()
return list(orig_fields.keys())
def items(self):
- return [(key, self.body[key]) for key in self.keys() if key in self.body]
+ body = self.get_body_json()
+ return [(key, body[key]) for key in self.keys() if key in body]
+
+ def get_body_json(self):
+ return json.loads(self.body or '{}')
class Attachment(models.Model):
{% for note_source in obj.notesource_set.all %}
<div class='dictionary-note-source'>
<a href='{% url "book_text" note_source.book.slug %}#{{ note_source.anchor }}'>{{ note_source.book.pretty_title }}</a>
- (<a href='{{ note_source.book.extra_info.about }}'>źródło na Platformie Redakcyjnej</a>)
+ (<a href='{{ note_source.book.get_extra_info_json.about }}'>źródło na Platformie Redakcyjnej</a>)
</div>
{% endfor %}
</div>
-# -*- coding: utf-8 -*-
from datetime import date
+import json
from urllib.request import urlopen
from django import forms
for file_format in data['formats']:
data['product_form'] = PRODUCT_FORMS[file_format]
data['product_form_detail'] = PRODUCT_FORM_DETAILS[file_format]
- data['contributors'] = self.contributors(data)
+ data['contributors'] = json.dumps(self.contributors(data))
ONIXRecord.new_record(purpose=ISBNPool.PURPOSE_WL, data=data)
return data
'title': self.cleaned_data['title'],
'language': self.cleaned_data['language'],
'publishing_date': self.cleaned_data['publishing_date'],
- 'contributors': [self.prepare_author(a) for a in self.cleaned_data['authors'].split(',')],
+ 'contributors': json.dumps([self.prepare_author(a) for a in self.cleaned_data['authors'].split(',')]),
'edition_type': 'NED',
'imprint': 'Fundacja Nowoczesna Polska',
'dc_slug': self.slug(),
+import json
from django.core.management.base import BaseCommand
from django.utils import timezone
else:
part_number = ''
contributors = ''
- for no, contributor in enumerate(record.contributors, start=1):
+ for no, contributor in enumerate(json.loads(record.contributors), start=1):
contributors += self.render_contributor(no, contributor)
return PRODUCT % {
'datestamp': record.datestamp.strftime('%Y%m%d'),
from django.db import migrations, models
import django.db.models.deletion
-import jsonfield.fields
class Migration(migrations.Migration):
('product_form_detail', models.CharField(max_length=8, blank=True)),
('title', models.CharField(max_length=256)),
('part_number', models.CharField(max_length=64, blank=True)),
- ('contributors', jsonfield.fields.JSONField()),
+ ('contributors', models.TextField()),
('edition_type', models.CharField(max_length=4)),
('edition_number', models.IntegerField(default=1)),
('language', models.CharField(max_length=4)),
#
from django.db import models
from django.db.models import F
-from jsonfield import JSONField
class ISBNPool(models.Model):
product_form_detail = models.CharField(max_length=8, blank=True)
title = models.CharField(max_length=256)
part_number = models.CharField(max_length=64, blank=True)
- contributors = JSONField() # roles, names, optional: ISNI, date of birth/death
+ contributors = models.TextField() # roles, names, optional: ISNI, date of birth/death
edition_type = models.CharField(max_length=4)
edition_number = models.IntegerField(default=1)
language = models.CharField(max_length=4)
from django.db import models, migrations
import django.db.models.deletion
-import jsonfield.fields
from django.conf import settings
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('slug', models.SlugField(max_length=120, verbose_name='Slug')),
('text', models.TextField(verbose_name='text')),
- ('created_from', jsonfield.fields.JSONField(null=True, verbose_name='Additional information', blank=True)),
+ ('created_from', models.TextField(null=True, verbose_name='Additional information', blank=True)),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='creation date')),
('seen_at', models.DateTimeField(auto_now_add=True, verbose_name='last view date')),
('view_count', models.IntegerField(default=1, verbose_name='view count')),
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
from django.db import migrations, models
-import jsonfield.fields
class Migration(migrations.Migration):
migrations.AlterField(
model_name='poem',
name='created_from',
- field=jsonfield.fields.JSONField(null=True, verbose_name='extra information', blank=True),
+ field=models.TextField(null=True, verbose_name='extra information', blank=True),
),
migrations.AlterField(
model_name='poem',
from django.conf import settings
from django.urls import reverse
-from jsonfield import JSONField
from catalogue.models import Book, Tag
slug = models.SlugField(_('slug'), max_length=120, db_index=True)
text = models.TextField(_('text'))
created_by = models.ForeignKey(User, models.SET_NULL, null=True)
- created_from = JSONField(_('extra information'), null=True, blank=True)
+ created_from = models.TextField(_('extra information'), null=True, blank=True)
created_at = models.DateTimeField(_('creation date'), auto_now_add=True, editable=False)
seen_at = models.DateTimeField(_('last view date'), auto_now_add=True, editable=False)
view_count = models.IntegerField(_('view count'), default=1)
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
+import json
from django.shortcuts import render, get_object_or_404
from django.views.decorators import cache
user = request.user if request.user.is_authenticated() else None
text = Poem.write(Continuations.get(book))
p = Poem(slug=get_random_hash(text), text=text, created_by=user)
- p.created_from = [book.id]
+ p.created_from = json.dumps([book.id])
p.save()
return render(
text = Poem.write(Continuations.get(tag))
p = Poem(slug=get_random_hash(text), text=text, created_by=user)
books = Book.tagged.with_any((tag,))
- p.created_from = [b.id for b in books]
+ p.created_from = json.dumps([b.id for b in books])
p.save()
book = books[0] if len(books) == 1 else None
def get_poem(request, poem):
p = get_object_or_404(Poem, slug=poem)
p.visit()
- if p.created_from:
- books = Book.objects.filter(id__in=p.created_from)
+ created_from = json.loads(p.created_from or '[]')
+ if created_from:
+ books = Book.objects.filter(id__in=created_from)
book = books[0] if len(books) == 1 else None
else:
books = book = None
from django.db import models, migrations
import django.db.models.deletion
import sorl.thumbnail.fields
-import jsonfield.fields
import django.core.files.storage
('xml_file', models.FileField(upload_to='xml', storage=django.core.files.storage.FileSystemStorage(base_url='/media/pictures/', location=join(settings.MEDIA_ROOT, 'pictures')), verbose_name='xml_file')),
('image_file', sorl.thumbnail.fields.ImageField(upload_to='images', storage=django.core.files.storage.FileSystemStorage(base_url='/media/pictures/', location=join(settings.MEDIA_ROOT, 'pictures')), verbose_name='image_file')),
('html_file', models.FileField(upload_to='html', storage=django.core.files.storage.FileSystemStorage(base_url='/media/pictures/', location=join(settings.MEDIA_ROOT, 'pictures')), verbose_name='html_file')),
- ('areas_json', jsonfield.fields.JSONField(default={}, verbose_name='picture areas JSON', editable=False)),
- ('extra_info', jsonfield.fields.JSONField(default={}, verbose_name='Additional information')),
+ ('areas_json', models.TextField(default='{}', verbose_name='picture areas JSON', editable=False)),
+ ('extra_info', models.TextField(default={}, verbose_name='Additional information')),
('culturepl_link', models.CharField(max_length=240, blank=True)),
('wiki_link', models.CharField(max_length=240, blank=True)),
- ('_related_info', jsonfield.fields.JSONField(null=True, editable=False, blank=True)),
+ ('_related_info', models.TextField(null=True, editable=False, blank=True)),
('width', models.IntegerField(null=True)),
('height', models.IntegerField(null=True)),
],
name='PictureArea',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('area', jsonfield.fields.JSONField(default={}, verbose_name='area', editable=False)),
+ ('area', models.TextField(default='{}', verbose_name='area', editable=False)),
('kind', models.CharField(db_index=True, max_length=10, verbose_name='form', choices=[('thing', 'thing'), ('theme', 'motif')])),
('picture', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='areas', to='picture.Picture')),
],
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
+import json
from django.core.files.base import ContentFile
from django.db import models, migrations
from django.template.loader import render_to_string
from librarian import dcparser
for pic in Picture.objects.all():
info = dcparser.parse(pic.xml_file.path, PictureInfo)
- pic.extra_info = info.to_dict()
- areas_json = pic.areas_json
- for field in areas_json[u'things'].values():
- field[u'object'] = field[u'object'].capitalize()
- pic.areas_json = areas_json
+ pic.extra_info = json.dumps(info.to_dict())
+ areas_json = json.loads(pic.areas_json)
+ for field in areas_json['things'].values():
+ field['object'] = field['object'].capitalize()
+ pic.areas_json = json.dumps(areas_json)
html_text = render_to_string('picture/picture_info.html', {
- 'things': pic.areas_json['things'],
- 'themes': pic.areas_json['themes'],
+ 'things': areas_json['things'],
+ 'themes': areas_json['themes'],
})
pic.html_file.save("%s.html" % pic.slug, ContentFile(html_text))
pic.save()
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
from django.db import migrations, models
-import jsonfield.fields
class Migration(migrations.Migration):
migrations.AlterField(
model_name='picture',
name='extra_info',
- field=jsonfield.fields.JSONField(default={}, verbose_name='extra information'),
+ field=models.TextField(default='{}', verbose_name='extra information'),
),
migrations.AlterField(
model_name='picture',
from picture import tasks
from wolnelektury.utils import cached_render, clear_cached_renders
from io import BytesIO
-import jsonfield
import itertools
+import json
import logging
import re
class PictureArea(models.Model):
picture = models.ForeignKey('picture.Picture', models.CASCADE, related_name='areas')
- area = jsonfield.JSONField(_('area'), default={}, editable=False)
+ area = models.TextField(_('area'), default='{}', editable=False)
kind = models.CharField(
_('kind'), max_length=10, blank=False, null=False, db_index=True,
choices=(('thing', _('thing')), ('theme', _('theme'))))
pa = PictureArea()
pa.picture = picture
pa.kind = kind
- pa.area = coords
+ pa.area = json.dumps(coords)
return pa
+ def get_area_json(self):
+ return json.loads(self.area)
+
@cached_render('picture/picturearea_short.html')
def midi_box(self):
themes = self.tags.filter(category='theme')
slug = models.SlugField(_('slug'), max_length=120, db_index=True, unique=True)
sort_key = models.CharField(_('sort key'), max_length=120, db_index=True, editable=False)
sort_key_author = models.CharField(
- _('sort key by author'), max_length=120, db_index=True, editable=False, default=u'')
+ _('sort key by author'), max_length=120, db_index=True, editable=False, default='')
created_at = models.DateTimeField(_('creation date'), auto_now_add=True, db_index=True)
changed_at = models.DateTimeField(_('creation date'), auto_now=True, db_index=True)
xml_file = models.FileField(_('xml file'), upload_to="xml", storage=picture_storage)
image_file = ImageField(_('image file'), upload_to="images", storage=picture_storage)
html_file = models.FileField(_('html file'), upload_to="html", storage=picture_storage)
- areas_json = jsonfield.JSONField(_('picture areas JSON'), default={}, editable=False)
- extra_info = jsonfield.JSONField(_('extra information'), default={})
+ areas_json = models.TextField(_('picture areas JSON'), default='{}', editable=False)
+ extra_info = models.TextField(_('extra information'), default='{}')
culturepl_link = models.CharField(blank=True, max_length=240)
wiki_link = models.CharField(blank=True, max_length=240)
picture.areas.all().delete()
picture.title = str(picture_xml.picture_info.title)
- picture.extra_info = picture_xml.picture_info.to_dict()
+ picture.extra_info = json.dumps(picture_xml.picture_info.to_dict())
picture_tags = set(catalogue.models.Tag.tags_from_info(picture_xml.picture_info))
for tag in picture_tags:
area.tags = _tags.union(picture_tags)
picture.tags = picture_tags
- picture.areas_json = area_data
+ picture.areas_json = json.dumps(area_data)
if image_file is not None:
img = image_file
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
+import json
from traceback import print_exc
from celery.task import task
def generate_picture_html(picture_id):
import picture.models
pic = picture.models.Picture.objects.get(pk=picture_id)
+ areas_json = json.loads(pic.areas_json)
html_text = render_to_string('picture/picture_info.html', {
- 'things': pic.areas_json['things'],
- 'themes': pic.areas_json['themes'],
+ 'things': areas_json['things'],
+ 'themes': areas_json['themes'],
})
pic.html_file.save("%s.html" % pic.slug, ContentFile(html_text))
{% block extra_categories %}
- {% if picture.extra_info.styles %}
+ {% with extra_info=picture.get_extra_info_json %}
+ {% if extra_info.styles %}
<span class="category">
<span class="mono"> {% trans "Style" %}:</span> <span class="book-box-tag">
- {% for tag in picture.extra_info.styles %}
+ {% for tag in extra_info.styles %}
<a>{{ tag }}</a>
{% if not forloop.last %}<span>, </span>{% endif %}
{% endfor %}
</span>
{% endif %}
- {% if picture.extra_info.medium %}
+ {% if extra_info.medium %}
<span class="category">
<span class="mono"> {% trans "Medium" %}:</span> <span class="book-box-tag">
- <a>{{ picture.extra_info.medium }}</a>
+ <a>{{ extra_info.medium }}</a>
</span>
</span>
{% endif %}
- {% if picture.extra_info.original_dimensions %}
+ {% if extra_info.original_dimensions %}
<span class="category">
<span class="mono"> {% trans "Dimensions" %}:</span> <span class="book-box-tag">
- <a>{{ picture.extra_info.original_dimensions }}</a>
+ <a>{{ extra_info.original_dimensions }}</a>
</span>
</span>
{% endif %}
<span class="category">
<span class="mono"> {% trans "Date" %}:</span> <span class="book-box-tag">
- <a>{{ picture.extra_info.created_at }}</a>
+ <a>{{ extra_info.created_at }}</a>
</span>
</span>
+ {% endwith %}
{% endblock %}
{% block right-column %}
+ {% with extra_info=picture.get_extra_info_json %}
<div class="right-column">
<div class="other-tools">
<h2 class="mono">{% trans "See" %}</h2>
<ul class="plain">
- {% if picture.extra_info.source_url %}
- <li><a href="{{ picture.extra_info.source_url }}">{% trans "Source" %}</a> {% trans "of the picture" %}</li>
+ {% if extra_info.source_url %}
+ <li><a href="{{ extra_info.source_url }}">{% trans "Source" %}</a> {% trans "of the picture" %}</li>
{% endif %}
<li><a href="{{ picture.xml_file.url }}">{% trans "Source XML file" %}</a></li>
- {% if picture.extra_info.about and not hide_about %}
- <li>{% trans "Picture on" %} <a href="{{ picture.extra_info.about }}">{% trans "Editor's Platform" %}</a></li>
+ {% if extra_info.about and not hide_about %}
+ <li>{% trans "Picture on" %} <a href="{{ extra_info.about }}">{% trans "Editor's Platform" %}</a></li>
{% endif %}
{% if picture.wiki_link %}
<li><a href="{{ picture.wiki_link }}">{% trans "Picture description on Wikipedia" %}</a></li>
</ul>
</div>
</div>
+ {% endwith %}
{% endblock %}
# what to do about this?
_engine = sorl.thumbnail.default.engine
sorl.thumbnail.default.engine = cropper
- coords = to_square(area.area)
+ coords = to_square(area.get_area_json())
try:
th = sorl.thumbnail.default.backend.get_thumbnail(
def picture_viewer(request, slug):
picture = get_object_or_404(Picture, slug=slug)
sponsors = []
- for sponsor in picture.extra_info.get('sponsors', []):
+ for sponsor in picture.get_extra_info_json().get('sponsors', []):
have_sponsors = Sponsor.objects.filter(name=sponsor)
if have_sponsors.exists():
sponsors.append(have_sponsors[0])
'epoch': picture.tag_unicode('epoch'),
'kind': picture.tag_unicode('kind'),
'genre': picture.tag_unicode('genre'),
- 'style': picture.extra_info['style'],
+ 'style': picture.get_extra_info_json()['style'],
'image_url': picture.image_file.url,
'width': picture.width,
'height': picture.height,
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
else:
mt['deprecated'] = '-'
- licenses = set(
- (b.extra_info.get('license'), b.extra_info.get('license_description'))
- for b in Book.objects.all().iterator() if b.extra_info.get('license'))
+ licenses = set()
+ for b in Book.objects.all().iterator():
+ extra_info = b.get_extra_info_json()
+ if extra_info.get('license'):
+ licenses.add((extra_info.get('license'), extra_info.get('license_description')))
return render(request, 'reporting/main.html', {
'media_types': media_types,
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.contrib import admin
-from jsonfield import JSONField
+from django.db.models import TextField
from sponsors import models
from sponsors import widgets
class SponsorPageAdmin(admin.ModelAdmin):
formfield_overrides = {
- JSONField: {'widget': widgets.SponsorPageWidget},
+ TextField: {'widget': widgets.SponsorPageWidget},
}
list_display = ('name',)
search_fields = ('name',)
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
from django.db import models, migrations
-import jsonfield.fields
class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=120, verbose_name='name')),
- ('sponsors', jsonfield.fields.JSONField(default={}, verbose_name='sponsors')),
+ ('sponsors', models.TextField(default='{}', verbose_name='sponsors')),
('_html', models.TextField(editable=False, blank=True)),
('sprite', models.ImageField(upload_to='sponsorzy/sprite', blank=True)),
],
from django.template.loader import render_to_string
from PIL import Image
-from jsonfield import JSONField
from django.core.files.base import ContentFile
THUMB_WIDTH = 120
class SponsorPage(models.Model):
name = models.CharField(_('name'), max_length=120)
- sponsors = JSONField(_('sponsors'), default={})
+ sponsors = models.TextField(_('sponsors'), default='{}')
_html = models.TextField(blank=True, editable=False)
sprite = models.ImageField(upload_to='sponsorzy/sprite', blank=True)
+ def get_sponsors_json(self):
+ return json.loads(self.sponsors or '[]')
+
def populated_sponsors(self):
result = []
offset = 0
- for column in self.sponsors:
+ for column in self.get_sponsors_json():
result_group = {'name': column['name'], 'sponsors': []}
sponsor_objects = Sponsor.objects.in_bulk(column['sponsors'])
for sponsor_pk in column['sponsors']:
def render_sprite(self):
sponsor_ids = []
- for column in self.sponsors:
+ for column in self.get_sponsors_json():
sponsor_ids.extend(column['sponsors'])
sponsors = Sponsor.objects.in_bulk(sponsor_ids)
sprite = Image.new('RGBA', (THUMB_WIDTH, len(sponsors) * THUMB_HEIGHT))
html = property(fget=html)
def save(self, *args, **kwargs):
- if isinstance(self.sponsors, str):
- # Walkaround for weird jsonfield 'no-decode' optimization.
- self.sponsors = json.loads(self.sponsors)
self.render_sprite()
self._html = render_to_string('sponsors/page.html', {
'sponsors': self.populated_sponsors(),