raven
[redakcja.git] / apps / cover / views.py
1 # -*- coding: utf-8 -*-
2 #
3 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 #
6 import os.path
7 from django.conf import settings
8 from django.contrib.auth.decorators import permission_required
9 from django.http import HttpResponse, HttpResponseRedirect, Http404
10 from django.shortcuts import get_object_or_404, render
11 from django.views.decorators.csrf import csrf_exempt
12 from django.views.decorators.http import require_POST
13 from catalogue.helpers import active_tab
14 from catalogue.models import Chunk
15 from cover.models import Image
16 from cover import forms
17
18 PREVIEW_SIZE = (216, 300)
19
20
21 def preview(request, book, chunk=None, rev=None):
22     """Creates a cover image.
23
24     If chunk and rev number are given, use version from given revision.
25     If rev is not given, use publishable version.
26     """
27     from PIL import Image
28     from librarian.cover import make_cover
29     from librarian.dcparser import BookInfo
30
31     chunk = Chunk.get(book, chunk)
32     if rev is not None:
33         try:
34             revision = chunk.at_revision(rev)
35         except Chunk.change_model.DoesNotExist:
36             raise Http404
37     else:
38         revision = chunk.publishable()
39         if revision is None:
40             raise Http404
41     xml = revision.materialize().encode('utf-8')
42
43     try:
44         info = BookInfo.from_string(xml)
45     except:
46         return HttpResponseRedirect(os.path.join(settings.STATIC_URL, "img/sample_cover.png"))
47     cover = make_cover(info)
48     response = HttpResponse(content_type=cover.mime_type())
49     image = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS)
50     image.save(response, cover.format)
51     return response
52
53
54 @csrf_exempt
55 @require_POST
56 def preview_from_xml(request):
57     from hashlib import sha1
58     from PIL import Image
59     from os import makedirs
60     from lxml import etree
61     from librarian.cover import make_cover
62     from librarian.dcparser import BookInfo
63
64     xml = request.POST['xml']
65     try:
66         info = BookInfo.from_string(xml.encode('utf-8'))
67     except:
68         return HttpResponse(os.path.join(settings.STATIC_URL, "img/sample_cover.png"))
69     coverid = sha1(etree.tostring(info.to_etree())).hexdigest()
70     cover = make_cover(info)
71
72     cover_dir = 'cover/preview'
73     try:
74         makedirs(os.path.join(settings.MEDIA_ROOT, cover_dir))
75     except OSError:
76         pass
77     fname = os.path.join(cover_dir, "%s.%s" % (coverid, cover.ext()))
78     image = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS)
79     image.save(os.path.join(settings.MEDIA_ROOT, fname))
80     return HttpResponse(os.path.join(settings.MEDIA_URL, fname))
81
82
83 @active_tab('cover')
84 def image(request, pk):
85     image = get_object_or_404(Image, pk=pk)
86
87     if request.user.has_perm('cover.change_image'):
88         if request.method == "POST":
89             form = forms.ImageEditForm(request.POST, request.FILES, instance=image)
90             if form.is_valid():
91                 form.save()
92                 return HttpResponseRedirect(image.get_absolute_url())
93         else:
94             form = forms.ImageEditForm(instance=image)
95         editable = True
96     else:
97         form = forms.ReadonlyImageEditForm(instance=image)
98         editable = False
99
100     return render(request, "cover/image_detail.html", {
101         "object": Image.objects.get(id=image.id),
102         "form": form,
103         "editable": editable,
104     })
105
106
107 @active_tab('cover')
108 def image_list(request):
109     return render(request, "cover/image_list.html", {
110         'object_list': Image.objects.all(),
111         'can_add': request.user.has_perm('cover.add_image'),
112     })
113
114
115 @permission_required('cover.add_image')
116 @active_tab('cover')
117 def add_image(request):
118     form = ff = None
119     if request.method == 'POST':
120         if request.POST.get('form_id') == 'flickr':
121             ff = forms.FlickrForm(request.POST)
122             if ff.is_valid():
123                 form = forms.ImageAddForm(ff.cleaned_data)
124         else:
125             form = forms.ImageAddForm(request.POST, request.FILES)
126             if form.is_valid():
127                 obj = form.save()
128                 return HttpResponseRedirect(obj.get_absolute_url())
129     if form is None:
130         form = forms.ImageAddForm()
131     if ff is None:
132         ff = forms.FlickrForm()
133     return render(request, 'cover/add_image.html', {
134             'form': form,
135             'ff': ff,
136         })