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