from django.test.utils import override_settings
from catalogue.models import Book, Tag
-from picture.forms import PictureImportForm
-from picture.models import Picture
-import picture.tests
from api.models import Consumer, Token
'Wrong tag details.')
-class PictureTests(ApiTest):
- def test_publish(self):
- slug = "kandinsky-composition-viii"
- with open(path.join(
- picture.tests.__path__[0], "files", slug + ".xml"
- ), 'rb') as f:
- xml = SimpleUploadedFile(
- 'composition8.xml',
- f.read())
- with open(path.join(
- picture.tests.__path__[0], "files", slug + ".png"
- ), 'rb') as f:
- img = SimpleUploadedFile(
- 'kompozycja-8.png',
- f.read())
-
- import_form = PictureImportForm({}, {
- 'picture_xml_file': xml,
- 'picture_image_file': img
- })
-
- assert import_form.is_valid()
- if import_form.is_valid():
- import_form.save()
-
- Picture.objects.get(slug=slug)
-
-
class BooksTests(ApiTest):
fixtures = ['test-books.yaml']
data={"data": json.dumps({})})
self.assertEqual(response.status_code, 403)
- response = self.signed('/api/pictures/',
- method='POST',
- data={"data": json.dumps({})})
- self.assertEqual(response.status_code, 403)
-
self.user.is_superuser = True
self.user.save()
self.assertTrue(mock.called)
self.assertEqual(response.status_code, 201)
- with patch('picture.models.Picture.from_xml_file') as mock:
- response = self.signed('/api/pictures/',
- method='POST',
- data={"data": json.dumps({
- "picture_xml": "<utwor/>",
- "picture_image_data": "Kg==",
- })})
- self.assertTrue(mock.called)
- self.assertEqual(response.status_code, 201)
-
self.user.is_superuser = False
self.user.save()
path('blog',
piwik_track_view(views.BlogView.as_view())),
- path('pictures/', include('picture.api.urls')),
path('', include('social.api.urls')),
path('', include('catalogue.api.urls')),
]
def get_queryset(self):
category = self.kwargs['category']
tags = Tag.objects.filter(category=category).exclude(items=None).order_by('slug')
- if self.request.query_params.get('book_only') == 'true':
- tags = tags.filter(for_books=True)
- if self.request.GET.get('picture_only') == 'true':
- tags = filter(for_pictures=True)
after = self.request.query_params.get('after')
count = self.request.query_params.get('count')
from django.core.management.color import color_style
from django.core.files import File
from django.db import transaction
-from librarian.picture import ImageStore
-
from catalogue.models import Book
-from picture.models import Picture
class Command(BaseCommand):
'-F', '--not-findable', action='store_false',
dest='findable', default=True,
help='Set book as not findable.')
- parser.add_argument(
- '-p', '--picture', action='store_true', dest='import_picture',
- default=False, help='Import pictures')
parser.add_argument('directory', nargs='+')
def import_book(self, file_path, options):
print("Importing %s.%s" % (file_base, ebook_format))
book.save()
- def import_picture(self, file_path, options, continue_on_error=True):
- try:
- image_store = ImageStore(os.path.dirname(file_path))
- picture = Picture.from_xml_file(file_path, image_store=image_store, overwrite=options.get('force'))
- except Exception as ex:
- if continue_on_error:
- print("%s: %s" % (file_path, ex))
- return
- else:
- raise ex
- return picture
-
@transaction.atomic
def handle(self, **options):
self.style = color_style()
verbose = options.get('verbose')
- import_picture = options.get('import_picture')
files_imported = 0
files_skipped = 0
# Import book files
try:
- if import_picture:
- self.import_picture(file_path, options)
- else:
- self.import_book(file_path, options)
-
+ self.import_book(file_path, options)
files_imported += 1
- except (Book.AlreadyExists, Picture.AlreadyExists):
+ except Book.AlreadyExists:
print(self.style.ERROR(
- '%s: Book or Picture already imported. Skipping. To overwrite use --force.' %
+ '%s: Book already imported. Skipping. To overwrite use --force.' %
file_path))
files_skipped += 1
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from newtagging.models import tags_updated
-from picture.models import Picture, PictureArea
from .models import BookMedia, Book, Collection, Fragment, Tag
def tag_after_change(sender, instance, **kwargs):
caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
- for model in Book, Picture:
- for model_instance in model.tagged.with_all([instance]).only('pk'):
- model_instance.clear_cache()
+ for book in Book.tagged.with_all([instance]).only('pk'):
+ book.clear_cache()
@receiver(tags_updated)
return
caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
- if sender in (Book, Picture):
+ if sender in (Book,):
instance.clear_cache()
{% if extra_info.editor or extra_info.technical_editor %}
<p>
- {% if is_picture %}
- {% trans "Opracowanie redakcyjne:" %}
- {% else %}
- {% trans "Opracowanie redakcyjne i przypisy:" %}
- {% endif %}
+ {% trans "Opracowanie redakcyjne i przypisy:" %}
{% all_editors extra_info %}.
</p>
{% endif %}
+++ /dev/null
-{% load i18n %}
-
-{% if books %}
- <p>{% trans "Literatura" %}:</p>
- <div>{{books|safe}}</div>
-{% endif %}
-
-{% if pictures %}
- <p>{% trans "Sztuka" %}:</p>
- <div>{{pictures|safe}}</div>
-{% endif %}
from catalogue.models import Book, BookMedia, Fragment, Tag, Source
from catalogue.constants import LICENSES
from club.models import Membership
-from picture.models import Picture
register = template.Library()
return reverse('book_list')
-# @register.inclusion_tag('catalogue/tag_list.html')
-def tag_list(tags, choices=None, category=None, list_type='books'):
- if choices is None:
- choices = []
-
- if category is None and tags:
- category = tags[0].category
-
- category_choices = [tag for tag in choices if tag.category == category]
-
- if len(tags) == 1 and category not in [t.category for t in choices]:
- one_tag = tags[0]
- else:
- one_tag = None
-
- if category is not None:
- other = Tag.objects.filter(category=category).exclude(pk__in=[t.pk for t in tags])\
- .exclude(pk__in=[t.pk for t in category_choices])
- # Filter out empty tags.
- ct = ContentType.objects.get_for_model(Picture if list_type == 'gallery' else Book)
- other = other.filter(items__content_type=ct).distinct()
- if list_type == 'audiobooks':
- other = other.filter(id__in=get_audiobook_tags())
- other = other.only('name', 'slug', 'category')
- else:
- other = []
-
- return {
- 'one_tag': one_tag,
- 'choices': choices,
- 'category_choices': category_choices,
- 'tags': tags,
- 'other': other,
- 'list_type': list_type,
- }
-
-
@register.inclusion_tag('catalogue/book_info.html')
def book_info(book):
return {
- 'is_picture': isinstance(book, Picture),
'book': book,
}
}
-# TODO: These are no longer just books.
-@register.inclusion_tag('catalogue/related_books.html', takes_context=True)
-def related_books(context, instance, limit=6, random=1, taken=0):
- limit -= taken
- max_books = limit - random
- is_picture = isinstance(instance, Picture)
-
- pics_qs = Picture.objects.all()
- if is_picture:
- pics_qs = pics_qs.exclude(pk=instance.pk)
- pics = Picture.tagged.related_to(instance, pics_qs)
- if pics.exists():
- # Reserve one spot for an image.
- max_books -= 1
-
- books_qs = Book.objects.filter(findable=True)
- if not is_picture:
- books_qs = books_qs.exclude(common_slug=instance.common_slug).exclude(ancestor=instance)
- books = Book.tagged.related_to(instance, books_qs)[:max_books]
-
- pics = pics[:1 + max_books - books.count()]
-
- random_excluded_books = [b.pk for b in books]
- random_excluded_pics = [p.pk for p in pics]
- (random_excluded_pics if is_picture else random_excluded_books).append(instance.pk)
-
- return {
- 'request': context['request'],
- 'books': books,
- 'pics': pics,
- 'random': random,
- 'random_excluded_books': random_excluded_books,
- 'random_excluded_pics': random_excluded_pics,
- }
-
-
@register.simple_tag
-def related_books_2022(book=None, picture=None, limit=4, taken=0):
+def related_books_2022(book=None, limit=4, taken=0):
limit -= taken
max_books = limit
books_qs = Book.objects.filter(findable=True)
if book is not None:
books_qs = books_qs.exclude(common_slug=book.common_slug).exclude(ancestor=book)
- instance = book or picture
- books = Book.tagged.related_to(instance, books_qs)[:max_books]
-
- return books
-
-@register.simple_tag
-def related_pictures_2022(book=None, picture=None, limit=4, taken=0):
- limit -= taken
- max_books = limit
-
- books_qs = Picture.objects.all()
- instance = book or picture
- books = Picture.tagged.related_to(instance, books_qs)[:max_books]
+ books = Book.tagged.related_to(book, books_qs)[:max_books]
return books
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-#
-from django.contrib import admin
-from picture.models import Picture
-from sorl.thumbnail.admin import AdminImageMixin
-
-
-class PictureAdmin(AdminImageMixin, admin.ModelAdmin):
- pass
-
-admin.site.register(Picture, PictureAdmin)
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-#
-from django.urls import path
-from . import views
-
-
-urlpatterns = [
- path('', views.PicturesView.as_view()),
-]
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-#
-import json
-from django.http import Http404
-from rest_framework.permissions import DjangoModelPermissions
-from rest_framework.response import Response
-from rest_framework import status
-from rest_framework.views import APIView
-from picture.forms import PictureImportForm
-from picture.models import Picture
-
-
-class PicturesView(APIView):
- permission_classes = [DjangoModelPermissions]
- queryset = Picture.objects.none() # Required for DjangoModelPermissions
-
- def post(self, request):
- data = json.loads(request.POST.get('data'))
- form = PictureImportForm(data)
- if form.is_valid():
- form.save()
- return Response({}, status=status.HTTP_201_CREATED)
- else:
- raise Http404
+++ /dev/null
-from sorl.thumbnail.engines import pil_engine
-from sorl.thumbnail import parsers
-
-
-#
-# Class developed by
-# http://timmyomahony.com/blog/custom-cropping-engine-sorl-thumbnail/
-#
-class CustomCroppingEngine(pil_engine.Engine):
- """
- A custom sorl.thumbnail engine (using PIL) that first crops an image
- according to 4 pixel/percentage values in the source image, then scales
- that crop down to the size specified in the geometry. This is in contrast
- to sorl.thumbnails default engine which first scales the image down to the
- specified geometry and applies the crop afterward.
- """
- def create(self, image, geometry, options):
- image = self.orientation(image, geometry, options)
- image = self.colorspace(image, geometry, options)
- image = self.crop(image, geometry, options)
- image = self.scale(image, geometry, options)
- return image
-
- def _crop_parse(self, crop, xy_image, xy_window):
- """
- Conver the crop string passed by the user to accurate cropping values
- (This is adapter from the default sorl.thumbnail.parsers.parse_crop)
- """
- crops = crop.split(' ')
- if len(crops) != 4:
- raise parsers.ThumbnailParseError('Unrecognized crop option: %s' % crop)
- x1, y1, x2, y2 = crops
-
- def get_offset(crop, epsilon):
- m = parsers.bgpos_pat.match(crop)
- if not m:
- raise parsers.ThumbnailParseError('Unrecognized crop option: %s' % crop)
- value = int(m.group('value')) # we only take ints in the regexp
- unit = m.group('unit')
- if unit == '%':
- value = epsilon * value / 100.0
- return int(max(0, min(value, epsilon)))
- x1 = get_offset(x1, xy_image[0])
- y1 = get_offset(y1, xy_image[1])
- x2 = get_offset(x2, xy_image[0])
- y2 = get_offset(y2, xy_image[1])
- return x1, y1, x2, y2
-
- def crop(self, image, geometry, options):
- crop = options['crop']
- if not crop or crop == 'noop':
- return image
- x_image, y_image = self.get_image_size(image)
- x1, y1, x2, y2 = self._crop_parse(crop, (x_image, y_image), geometry)
- return self._crop(image, x1, y1, x2, y2)
-
- def _crop(self, image, x1, y1, x2, y2):
- return image.crop((x1, y1, x2, y2))
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-#
-from django import forms
-from picture.models import Picture
-
-
-class PictureImportForm(forms.Form):
- picture_xml_file = forms.FileField(required=False)
- picture_xml = forms.CharField(required=False)
- picture_image_file = forms.FileField(required=False)
- picture_image_data = forms.CharField(required=False)
-
- def clean(self):
- from base64 import b64decode
- from django.core.files.base import ContentFile
-
- if not self.cleaned_data['picture_xml_file']:
- if self.cleaned_data['picture_xml']:
- self.cleaned_data['picture_xml_file'] = \
- ContentFile(self.cleaned_data['picture_xml'].encode('utf-8'))
- else:
- raise forms.ValidationError('Proszę dostarczyć XML.')
-
- if not self.cleaned_data['picture_image_file']:
- if self.cleaned_data['picture_image_data']:
- self.cleaned_data['picture_image_file'] = \
- ContentFile(b64decode(
- self.cleaned_data['picture_image_data']))
- else:
- raise forms.ValidationError('Proszę dostarczyć obraz.')
-
- return super(PictureImportForm, self).clean()
-
- def save(self, commit=True, **kwargs):
- return Picture.from_xml_file(
- self.cleaned_data['picture_xml_file'], image_file=self.cleaned_data['picture_image_file'],
- overwrite=True, **kwargs)
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-msgid ""
-msgstr ""
-"Project-Id-Version: WolneLektury-picture\n"
-"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: picture/templates/picture/picture_detail.html:13
-msgid "Strona główna"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:14
-msgid "Obrazy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:29
-msgctxt "obrazu"
-msgid "Styl"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:39
-msgctxt "obrazu"
-msgid "Technika"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:46
-msgctxt "obrazu"
-msgid "Wymiary pracy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:52
-msgctxt "obrazu"
-msgid "Czas powstania"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:39
-msgid "Epoka"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:48
-msgid "Rodzaj"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:57
-msgid "Gatunek"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:74
-msgid "Zobacz online"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:77
-msgid "pobierz oryginał"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:51
-msgctxt "na obrazie"
-msgid "Obiekty"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:52
-msgid "Motywy"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:56
-msgid "Informacja"
-msgstr ""
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-msgid ""
-msgstr ""
-"Project-Id-Version: WolneLektury-picture\n"
-"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: picture/templates/picture/picture_detail.html:13
-msgid "Strona główna"
-msgstr "Main page"
-
-#: picture/templates/picture/picture_detail.html:14
-msgid "Obrazy"
-msgstr "Pictures"
-
-#: picture/templates/picture/picture_detail.html:29
-msgctxt "obrazu"
-msgid "Styl"
-msgstr "Style"
-
-#: picture/templates/picture/picture_detail.html:39
-msgctxt "obrazu"
-msgid "Technika"
-msgstr "Medium"
-
-#: picture/templates/picture/picture_detail.html:46
-msgctxt "obrazu"
-msgid "Wymiary pracy"
-msgstr "Dimensions"
-
-#: picture/templates/picture/picture_detail.html:52
-msgctxt "obrazu"
-msgid "Czas powstania"
-msgstr "Date"
-
-#: picture/templates/picture/picture_short.html:39
-msgid "Epoka"
-msgstr "Epoch"
-
-#: picture/templates/picture/picture_short.html:48
-msgid "Rodzaj"
-msgstr "Kind"
-
-#: picture/templates/picture/picture_short.html:57
-msgid "Gatunek"
-msgstr "Genre"
-
-#: picture/templates/picture/picture_short.html:74
-msgid "Zobacz online"
-msgstr "View online"
-
-#: picture/templates/picture/picture_short.html:77
-msgid "pobierz oryginał"
-msgstr "download original"
-
-#: picture/templates/picture/picture_viewer.html:51
-msgctxt "na obrazie"
-msgid "Obiekty"
-msgstr "Objects"
-
-#: picture/templates/picture/picture_viewer.html:52
-msgid "Motywy"
-msgstr "Themes"
-
-#: picture/templates/picture/picture_viewer.html:56
-msgid "Informacja"
-msgstr "Info"
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-msgid ""
-msgstr ""
-"Project-Id-Version: WolneLektury-picture\n"
-"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: picture/templates/picture/picture_detail.html:13
-msgid "Strona główna"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:14
-msgid "Obrazy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:29
-msgctxt "obrazu"
-msgid "Styl"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:39
-msgctxt "obrazu"
-msgid "Technika"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:46
-msgctxt "obrazu"
-msgid "Wymiary pracy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:52
-msgctxt "obrazu"
-msgid "Czas powstania"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:39
-msgid "Epoka"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:48
-msgid "Rodzaj"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:57
-msgid "Gatunek"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:74
-msgid "Zobacz online"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:77
-msgid "pobierz oryginał"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:51
-msgctxt "na obrazie"
-msgid "Obiekty"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:52
-msgid "Motywy"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:56
-msgid "Informacja"
-msgstr ""
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-msgid ""
-msgstr ""
-"Project-Id-Version: WolneLektury-picture\n"
-"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#: picture/templates/picture/picture_detail.html:13
-msgid "Strona główna"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:14
-msgid "Obrazy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:29
-msgctxt "obrazu"
-msgid "Styl"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:39
-msgctxt "obrazu"
-msgid "Technika"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:46
-msgctxt "obrazu"
-msgid "Wymiary pracy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:52
-msgctxt "obrazu"
-msgid "Czas powstania"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:39
-msgid "Epoka"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:48
-msgid "Rodzaj"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:57
-msgid "Gatunek"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:74
-msgid "Zobacz online"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:77
-msgid "pobierz oryginał"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:51
-msgctxt "na obrazie"
-msgid "Obiekty"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:52
-msgid "Motywy"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:56
-msgid "Informacja"
-msgstr ""
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-msgid ""
-msgstr ""
-"Project-Id-Version: WolneLektury-picture\n"
-"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: picture/templates/picture/picture_detail.html:13
-msgid "Strona główna"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:14
-msgid "Obrazy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:29
-msgctxt "obrazu"
-msgid "Styl"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:39
-msgctxt "obrazu"
-msgid "Technika"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:46
-msgctxt "obrazu"
-msgid "Wymiary pracy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:52
-msgctxt "obrazu"
-msgid "Czas powstania"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:39
-msgid "Epoka"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:48
-msgid "Rodzaj"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:57
-msgid "Gatunek"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:74
-msgid "Zobacz online"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:77
-msgid "pobierz oryginał"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:51
-msgctxt "na obrazie"
-msgid "Obiekty"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:52
-msgid "Motywy"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:56
-msgid "Informacja"
-msgstr ""
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-msgid ""
-msgstr ""
-"Project-Id-Version: WolneLektury-picture\n"
-"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < "
-"11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? "
-"1 : n % 1 != 0 ? 2: 3);\n"
-
-#: picture/templates/picture/picture_detail.html:13
-msgid "Strona główna"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:14
-msgid "Obrazy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:29
-msgctxt "obrazu"
-msgid "Styl"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:39
-msgctxt "obrazu"
-msgid "Technika"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:46
-msgctxt "obrazu"
-msgid "Wymiary pracy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:52
-msgctxt "obrazu"
-msgid "Czas powstania"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:39
-msgid "Epoka"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:48
-msgid "Rodzaj"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:57
-msgid "Gatunek"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:74
-msgid "Zobacz online"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:77
-msgid "pobierz oryginał"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:51
-msgctxt "na obrazie"
-msgid "Obiekty"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:52
-msgid "Motywy"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:56
-msgid "Informacja"
-msgstr ""
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-msgid ""
-msgstr ""
-"Project-Id-Version: WolneLektury-picture\n"
-"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
-"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
-"(n%100>=11 && n%100<=14)? 2 : 3);\n"
-
-#: picture/templates/picture/picture_detail.html:13
-msgid "Strona główna"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:14
-msgid "Obrazy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:29
-msgctxt "obrazu"
-msgid "Styl"
-msgstr "Стиль"
-
-#: picture/templates/picture/picture_detail.html:39
-msgctxt "obrazu"
-msgid "Technika"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:46
-msgctxt "obrazu"
-msgid "Wymiary pracy"
-msgstr "Размеры"
-
-#: picture/templates/picture/picture_detail.html:52
-msgctxt "obrazu"
-msgid "Czas powstania"
-msgstr "Дата"
-
-#: picture/templates/picture/picture_short.html:39
-msgid "Epoka"
-msgstr "Эпоха"
-
-#: picture/templates/picture/picture_short.html:48
-msgid "Rodzaj"
-msgstr "Вид"
-
-#: picture/templates/picture/picture_short.html:57
-msgid "Gatunek"
-msgstr "Жанр"
-
-#: picture/templates/picture/picture_short.html:74
-msgid "Zobacz online"
-msgstr "Смотреть онлайн"
-
-#: picture/templates/picture/picture_short.html:77
-msgid "pobierz oryginał"
-msgstr "скачать оригинал"
-
-#: picture/templates/picture/picture_viewer.html:51
-msgctxt "na obrazie"
-msgid "Obiekty"
-msgstr "Объекты"
-
-#: picture/templates/picture/picture_viewer.html:52
-msgid "Motywy"
-msgstr "Темы"
-
-#: picture/templates/picture/picture_viewer.html:56
-msgid "Informacja"
-msgstr "Инфобокс"
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-msgid ""
-msgstr ""
-"Project-Id-Version: WolneLektury-picture\n"
-"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != "
-"11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % "
-"100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || "
-"(n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n"
-
-#: picture/templates/picture/picture_detail.html:13
-msgid "Strona główna"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:14
-msgid "Obrazy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:29
-msgctxt "obrazu"
-msgid "Styl"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:39
-msgctxt "obrazu"
-msgid "Technika"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:46
-msgctxt "obrazu"
-msgid "Wymiary pracy"
-msgstr ""
-
-#: picture/templates/picture/picture_detail.html:52
-msgctxt "obrazu"
-msgid "Czas powstania"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:39
-msgid "Epoka"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:48
-msgid "Rodzaj"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:57
-msgid "Gatunek"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:74
-msgid "Zobacz online"
-msgstr ""
-
-#: picture/templates/picture/picture_short.html:77
-msgid "pobierz oryginał"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:51
-msgctxt "na obrazie"
-msgid "Obiekty"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:52
-msgid "Motywy"
-msgstr ""
-
-#: picture/templates/picture/picture_viewer.html:56
-msgid "Informacja"
-msgstr ""
from catalogue.models.tag import prefetched_relations
from catalogue.utils import split_tags
-from picture import tasks
from wolnelektury.utils import cached_render, clear_cached_renders
from io import BytesIO
import itertools
picture.xml_file.save("%s.xml" % picture.slug, File(xml_file))
picture.save()
- tasks.generate_picture_html(picture.id)
if close_xml_file:
xml_file.close()
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-#
-import json
-from celery import shared_task
-from django.core.files.base import ContentFile
-from django.template.loader import render_to_string
-
-
-@shared_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': areas_json['things'],
- 'themes': areas_json['themes'],
- })
- pic.html_file.save("%s.html" % pic.slug, ContentFile(html_text))
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-#
-import logging
-from random import randint
-from django import template
-from django.urls import reverse
-from django.utils.cache import add_never_cache_headers
-import sorl.thumbnail.default
-from catalogue.utils import split_tags
-from ..engine import CustomCroppingEngine
-from ..models import Picture
-
-
-register = template.Library()
-
-cropper = CustomCroppingEngine()
-
-
-@register.simple_tag()
-def area_thumbnail_url(area, geometry):
- def to_square(coords):
- w = coords[1][0] - coords[0][0]
- h = coords[1][1] - coords[0][1]
- if w == h:
- return coords
- elif w > h:
- return [[coords[0][0] + w/2 - h/2, coords[0][1]],
- [coords[1][0] - w/2 + h/2, coords[1][1]]]
- else:
- return [[coords[0][0], coords[0][1] + h/2 - w/2],
- [coords[1][0], coords[1][1] - h/2 + w/2, ]]
-
- # so much for sorl extensibility.
- # what to do about this?
- _engine = sorl.thumbnail.default.engine
- sorl.thumbnail.default.engine = cropper
- coords = to_square(area.get_area_json())
-
- try:
- th = sorl.thumbnail.default.backend.get_thumbnail(
- area.picture.image_file,
- geometry,
- crop="%dpx %dpx %dpx %dpx" % tuple(map(lambda d: max(0, d), tuple(coords[0] + coords[1]))))
- except ZeroDivisionError:
- return ''
- except Exception as e:
- logging.exception("Error creating a thumbnail for PictureArea")
- return ''
-
- sorl.thumbnail.default.engine = _engine
-
- return th.url
-
-
-@register.simple_tag
-def picture_random_picture(exclude_ids):
- queryset = Picture.objects.exclude(pk__in=exclude_ids).exclude(image_file='')
- count = queryset.count()
- if count:
- return queryset[randint(0, count - 1)]
- else:
- return None
+++ /dev/null
-<picture>
- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
- <rdf:Description rdf:about="http://wiki.wolnepodreczniki.pl/Lektury:Andersen/Brzydkie_kaczątko">
- <dc:creator xml:lang="pl">Kandinsky, Vasily</dc:creator>
- <dc:title xml:lang="la">composition 8</dc:title>
- <dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
- <dc:contributor.editor xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Sekuła, Aleksandra</dc:contributor.editor>
- <dc:contributor.editor xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Kwiatkowska, Katarzyna</dc:contributor.editor>
- <dc:contributor.technical_editor xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Trzeciak, Weronika</dc:contributor.technical_editor>
- <dc:subject.period xml:lang="pl">Modernizm</dc:subject.period>
- <dc:subject.type xml:lang="pl">Obraz</dc:subject.type>
- <dc:description xml:lang="pl">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa wykonana przez Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN.</dc:description>
- <dc:description.dimensions xml:lang="pl">55 1/8 x 79 1/8 inches</dc:description.dimensions>
- <dc:description.medium xml:lang="pl">Olej na płótnie</dc:description.medium>
- <dc:identifier.url xml:lang="pl">http://wolnelektury.pl/katalog/obraz/kandinsky-composition-viii</dc:identifier.url>
- <dc:source.URL xml:lang="pl">http://www.ibiblio.org/wm/paint/auth/kandinsky/kandinsky.comp-8.jpg</dc:source.URL>
- <dc:source xml:lang="pl">Muzeum Narodowe, inw. 00000001.</dc:source>
- <dc:rights xml:lang="pl">Domena publiczna - Vasily Kandinsky zm. ?</dc:rights>
- <dc:date.pd xml:lang="pl">1940</dc:date.pd>
- <dc:type>Image</dc:type>
- <dc:format xml:lang="pl">image/png</dc:format>
- <dc:format.dimensions xml:lang="pl">1090 x 755 px</dc:format.dimensions>
- <dc:format.checksum.sha1 xml:lang="pl">122b590510ce70cc80e617557f82048ce20f1d7b</dc:format.checksum.sha1>
- <dc:date xml:lang="pl">1923</dc:date>
- <dc:language xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">eng</dc:language>
- </rdf:Description>
- </rdf:RDF>
-
- <sem type="object" object="kosmos">
- <div type="area" x1="17" y1="31" x2="275" y2="309"/>
- </sem>
- <sem type="theme" theme="nieporządek">
- <div type="area" x1="300" y1="138" x2="976" y2="514"/>
- </sem>
-
-</picture>
+++ /dev/null
-# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
-#
-from os import path
-from picture.models import Picture
-from catalogue.test_utils import WLTestCase
-
-
-class PictureTest(WLTestCase):
-
- def test_import(self):
- picture = Picture.from_xml_file(path.join(path.dirname(__file__), "files/kandinsky-composition-viii.xml"))
-
- themes = set()
- for area in picture.areas.all():
- themes.update([
- (tag.category, tag.name)
- for tag in area.tags if tag.category in ('theme', 'thing')])
- assert themes == {('theme', 'nieporządek'), ('thing', 'Kosmos')}, \
- 'Bad themes on Picture areas: %s' % themes
-
- pic_themes = set([tag.name for tag in picture.tags if tag.category in ('theme', 'thing')])
- assert not pic_themes, 'Unwanted themes set on Pictures: %s' % pic_themes
-
- picture.delete()
-
- def test_import_with_explicit_image(self):
- picture = Picture.from_xml_file(path.join(path.dirname(__file__), "files/kandinsky-composition-viii.xml"),
- path.join(path.dirname(__file__), "files/kandinsky-composition-viii.png"))
-
- picture.delete()
-
- def test_import_2(self):
- picture = Picture.from_xml_file(path.join(path.dirname(__file__), "files/kandinsky-composition-viii.xml"),
- path.join(path.dirname(__file__), "files/kandinsky-composition-viii.png"),
- overwrite=True)
- cats = set([t.category for t in picture.tags])
- assert 'epoch' in cats
- assert 'kind' in cats
from catalogue.constants import LANGUAGES_3TO2
import catalogue.models
import pdcounter.models
-import picture.models
from .fields import InlineRadioWidget
from .utils import UnaccentSearchQuery, UnaccentSearchVector
)
format = forms.ChoiceField(required=False, choices=[
('', _('wszystkie')),
- ('text', _('tekst')),
('audio', _('audiobook')),
('daisy', _('Daisy')),
- ('art', _('obraz')),
], widget=InlineRadioWidget())
lang = forms.ChoiceField(required=False)
epoch = forms.ChoiceField(required=False)
('theme', _('motyw')),
('genre', _('gatunek')),
('book', _('tytuł')),
- ('art', _('obraz')),
('collection', _('kolekcja')),
('quote', _('cytat')),
], widget=InlineRadioWidget())
'book': catalogue.models.Book.objects.filter(findable=True),
'pdbook': pdcounter.models.BookStub.objects.all(),
'snippet': catalogue.models.Snippet.objects.filter(book__findable=True),
- 'art': picture.models.Picture.objects.all(),
- # art pieces
}
if self.cleaned_data['category']:
c = self.cleaned_data['category']
qs['book'] = qs['book'].none()
qs['pdbook'] = qs['pdbook'].none()
if c != 'quote': qs['snippet'] = qs['snippet'].none()
- if c != 'art': qs['art'] = qs['art'].none()
- qs['art'] = picture.models.Picture.objects.none()
if self.cleaned_data['format']:
c = self.cleaned_data['format']
qs['theme'] = qs['theme'].none()
qs['genre'] = qs['genre'].none()
qs['collection'] = qs['collection'].none()
- if c == 'art':
- qs['book'] = qs['book'].none()
- qs['pdbook'] = qs['pdbook'].none()
- qs['snippet'] = qs['snippet'].none()
- if c in ('text', 'audio', 'daisy'):
- qs['art'] = qs['art'].none()
- if c == 'audio':
- qs['book'] = qs['book'].filter(media__type='mp3')
- qs['pdbook'] = qs['book'].none()
- qs['snippet'] = qs['snippet'].filter(book__media__type='mp3')
- elif c == 'daisy':
- qs['book'] = qs['book'].filter(media__type='daisy')
- qs['snippet'] = qs['snippet'].filter(book__media__type='daisy')
+ if c == 'audio':
+ qs['book'] = qs['book'].filter(media__type='mp3')
+ qs['pdbook'] = qs['book'].none()
+ qs['snippet'] = qs['snippet'].filter(book__media__type='mp3')
+ elif c == 'daisy':
+ qs['book'] = qs['book'].filter(media__type='daisy')
+ qs['snippet'] = qs['snippet'].filter(book__media__type='daisy')
if self.cleaned_data['lang']:
qs['author'] = qs['author'].none()
qs['pdauthor'] = qs['pdauthor'].none()
qs['theme'] = qs['theme'].none()
qs['genre'] = qs['genre'].none()
- qs['art'] = qs['art'].none()
qs['collection'] = qs['collection'].none()
qs['book'] = qs['book'].filter(language=self.cleaned_data['lang'])
qs['pdbook'] = qs['pdbook'].none()
qs['book'] = qs['book'].filter(tag_relations__tag=t)
qs['pdbook'] = qs['pdbook'].none()
qs['snippet'] = qs['snippet'].filter(book__tag_relations__tag=t)
- qs['art'] = qs['art'].filter(tag_relations__tag=t)
return qs
search_vector=UnaccentSearchVector('title')
).filter(search_vector=squery),
'book': books[:100],
- 'art': qs['art'].annotate(
- search_vector=UnaccentSearchVector('title')
- ).filter(search_vector=squery)[:100],
'snippet': snippets_by_book,
'pdauthor': pdcounter.models.Author.search(squery, qs=qs['pdauthor']),
'pdbook': pdcounter.models.BookStub.search(squery, qs=qs['pdbook']),
</div>
{% endif %}
- {% if results.art %}
- <div class="l-container">
- <h2 class="header">{% trans "Obrazy" %}</h2>
- </div>
- <div class="l-section l-section--col">
- <div class="l-books__grid">
- {% for book in results.art %}
- {% include 'catalogue/book_box.html' %}
- {% endfor %}
- </div>
- </div>
- {% endif %}
-
{% if results.snippet %}
<div class="l-container">
<h2 class="header">{% trans "W treści" %}</h2>
import catalogue.models
import infopages.models
-import picture.models
from .forms import SearchFilters
import re
import json
{
'type': 'author',
'label': author.name,
- 'url': author.get_absolute_gallery_url() if author.for_pictures else author.get_absolute_url(),
+ 'url': author.get_absolute_url(),
'img': get_thumbnail(author.photo, '72x72', crop='top').url if author.photo else '',
}
for author in authors[:limit - len(data)]
{
'type': tag.category,
'label': tag.name,
- 'url': tag.get_absolute_gallery_url() if tag.for_pictures else tag.get_absolute_url(),
+ 'url': tag.get_absolute_url(),
}
for tag in tags[:limit - len(data)]
])
'img': get_thumbnail(b.cover_clean, '72x72').url if b.cover_clean else '',
}
)
- if len(data) < limit:
- arts = picture.models.Picture.objects.filter(
- title__iregex='\m' + prefix).only('title', 'id', 'slug') # img?
- data.extend([
- {
- 'type': 'art',
- 'label': art.title,
- 'author': art.author_unicode(),
- 'url': art.get_absolute_url(),
- 'img': get_thumbnail(art.image_file, '72x72').url if art.image_file else '',
- }
- for art in arts[:limit - len(data)]
- ])
if len(data) < limit:
infos = infopages.models.InfoPage.objects.filter(
published=True,
from annoy.utils import banner_exempt
import catalogue.views
import club.views
-import picture.views
from . import views
# Admin panel
path('admin/catalogue/book/import', catalogue.views.import_book, name='import_book'),
- path('admin/catalogue/picture/import', picture.views.import_picture, name='import_picture'),
path('admin/doc/', include('django.contrib.admindocs.urls')),
path('admin/', admin.site.urls),