1 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 
   2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 
   5 from django.conf import settings
 
   6 from django.contrib.auth.decorators import permission_required
 
   7 from django.http import HttpResponse, HttpResponseRedirect, Http404
 
   8 from django.shortcuts import get_object_or_404, render
 
   9 from django.views.decorators.csrf import csrf_exempt
 
  10 from django.views.decorators.http import require_POST
 
  11 from lxml import etree
 
  12 from librarian import RDFNS, DCNS
 
  13 from documents.helpers import active_tab
 
  14 from documents.models import Book, Chunk
 
  15 from cover.models import Image
 
  16 from cover import forms
 
  17 from cover.utils import get_import_data
 
  20 PREVIEW_SIZE = (216, 300)
 
  23 def preview(request, book, chunk=None, rev=None):
 
  24     """Creates a cover image.
 
  26     If chunk and rev number are given, use version from given revision.
 
  27     If rev is not given, use publishable version.
 
  30     from librarian.cover import make_cover
 
  31     from librarian.dcparser import BookInfo
 
  33     chunk = Chunk.get(book, chunk)
 
  36             revision = chunk.at_revision(rev)
 
  37         except Chunk.change_model.DoesNotExist:
 
  40         revision = chunk.publishable()
 
  43     xml = revision.materialize().encode('utf-8')
 
  46         info = BookInfo.from_bytes(xml)
 
  48         return HttpResponseRedirect(os.path.join(settings.STATIC_URL, "img/sample_cover.png"))
 
  49     width = request.GET.get('width')
 
  50     width = int(width) if width else None
 
  51     height=request.GET.get('height')
 
  52     height = int(height) if height else None
 
  53     cover = make_cover(info, width=width, height=height)
 
  54     #cover = make_cover(info)
 
  55     response = HttpResponse(content_type=cover.mime_type())
 
  57         size = (width, height)
 
  60     img = cover.image().resize(size, Image.ANTIALIAS)
 
  61     img.save(response, cover.format)
 
  63     if 'download' in request.GET:
 
  64         response['Content-Disposition'] = 'attachment; filename=%s.jpg' % chunk.book.slug
 
  71 def preview_from_xml(request):
 
  72     from hashlib import sha1
 
  74     from os import makedirs
 
  75     from lxml import etree
 
  76     from librarian.cover import make_cover
 
  77     from librarian.dcparser import BookInfo
 
  79     xml = request.POST['xml']
 
  81         info = BookInfo.from_bytes(xml.encode('utf-8'))
 
  83         return HttpResponse(os.path.join(settings.STATIC_URL, "img/sample_cover.png"))
 
  84     coverid = sha1(etree.tostring(info.to_etree())).hexdigest()
 
  85     cover = make_cover(info)
 
  87     cover_dir = 'cover/preview'
 
  89         makedirs(os.path.join(settings.MEDIA_ROOT, cover_dir))
 
  92     fname = os.path.join(cover_dir, "%s.%s" % (coverid, cover.ext()))
 
  93     img = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS)
 
  94     img.save(os.path.join(settings.MEDIA_ROOT, fname))
 
  95     return HttpResponse(os.path.join(settings.MEDIA_URL, fname))
 
  99 def image(request, pk):
 
 100     img = get_object_or_404(Image, pk=pk)
 
 102     if request.user.has_perm('cover.change_image'):
 
 103         if request.method == "POST":
 
 104             form = forms.ImageEditForm(request.POST, request.FILES, instance=img)
 
 107                 return HttpResponseRedirect(img.get_absolute_url())
 
 109             form = forms.ImageEditForm(instance=img)
 
 112         form = forms.ReadonlyImageEditForm(instance=img)
 
 115     return render(request, "cover/image_detail.html", {
 
 116         "object": Image.objects.get(id=img.id),
 
 118         "editable": editable,
 
 122 def image_file(request, pk):
 
 123     img = get_object_or_404(Image, pk=pk)
 
 124     return HttpResponseRedirect(img.file.url)
 
 128 def image_list(request):
 
 129     return render(request, "cover/image_list.html", {
 
 130         'object_list': Image.objects.all(),
 
 131         'can_add': request.user.has_perm('cover.add_image'),
 
 135 @permission_required('cover.add_image')
 
 137 def add_image(request):
 
 139     if request.method == 'POST':
 
 140         if request.POST.get('form_id') == 'import':
 
 141             ff = forms.ImportForm(request.POST)
 
 143                 form = forms.ImageAddForm(ff.cleaned_data)
 
 145             form = forms.ImageAddForm(request.POST, request.FILES)
 
 148                 return HttpResponseRedirect(obj.get_absolute_url())
 
 150         form = forms.ImageAddForm()
 
 152         ff = forms.ImportForm()
 
 153     return render(request, 'cover/add_image.html', {
 
 158 @permission_required('cover.add_image')
 
 159 def quick_import(request, pk):
 
 160     url = request.POST.get('url')
 
 161     if url.startswith('%s://%s/' % (
 
 163             request.get_host())):
 
 164         cover_id = url.rsplit('/', 1)[-1]
 
 165         cover = Image.objects.get(pk=cover_id)
 
 167         data = get_import_data(url)
 
 168         same = Image.objects.filter(source_url=data['source_url'])
 
 169         if not same.exists():
 
 170             same = Image.objects.filter(download_url=data['download_url'])
 
 174             form = forms.ImageAddForm(data)
 
 178     # We have a cover. Now let's commit.
 
 179     book = Book.objects.get(pk=pk)
 
 181     text = chunk.head.materialize()
 
 183     root = etree.fromstring(text)
 
 184     rdf = root.find('.//' + RDFNS('Description'))
 
 185     for tag in 'url', 'attribution', 'source':
 
 186         for elem in rdf.findall('.//' + DCNS('relation.coverImage.%s' % tag)):
 
 188     e = etree.Element(DCNS('relation.coverImage.url'))
 
 189     e.text = request.build_absolute_uri(cover.use_file.url)
 
 192     e = etree.Element(DCNS('relation.coverImage.attribution'))
 
 195         e.text += cover.title + ', '
 
 197         e.text += cover.author + ', '
 
 198     e.text += cover.license_name
 
 201     e = etree.Element(DCNS('relation.coverImage.source'))
 
 202     e.text = cover.get_full_url()
 
 206     xml = etree.tostring(root, encoding='unicode')
 
 211         publishable=chunk.head.publishable,
 
 213     return HttpResponseRedirect(book.get_absolute_url())