editor: Handling backspace/delete on the text boundries
[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
19 PREVIEW_SIZE = (216, 300)
20
21
22 def preview(request, book, chunk=None, rev=None):
23     """Creates a cover image.
24
25     If chunk and rev number are given, use version from given revision.
26     If rev is not given, use publishable version.
27     """
28     from PIL import Image
29     from librarian.cover import WLCover
30     from librarian.dcparser import BookInfo
31
32     chunk = Chunk.get(book, chunk)
33     if rev is not None:
34         try:
35             revision = chunk.at_revision(rev)
36         except Chunk.change_model.DoesNotExist:
37             raise Http404
38     else:
39         revision = chunk.publishable()
40         if revision is None:
41             raise Http404
42     xml = revision.materialize().encode('utf-8')
43
44     try:
45         info = BookInfo.from_string(xml)
46     except:
47         return HttpResponseRedirect(os.path.join(settings.STATIC_URL, "img/sample_cover.png"))
48     cover = WLCover(info)
49     response = HttpResponse(mimetype=cover.mime_type())
50     image = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS)
51     image.save(response, cover.format)
52     return response
53
54
55 @csrf_exempt
56 @require_POST
57 def preview_from_xml(request):
58     from hashlib import sha1
59     from PIL import Image
60     from os import makedirs
61     from lxml import etree
62     from librarian.cover import WLCover
63     from librarian.dcparser import BookInfo
64
65     xml = request.POST['xml']
66     try:
67         info = BookInfo.from_string(xml.encode('utf-8'))
68     except:
69         return HttpResponse(os.path.join(settings.STATIC_URL, "img/sample_cover.png"))
70     coverid = sha1(etree.tostring(info.to_etree())).hexdigest()
71     cover = WLCover(info)
72
73     cover_dir = 'cover/preview'
74     try:
75         makedirs(os.path.join(settings.MEDIA_ROOT, cover_dir))
76     except OSError:
77         pass
78     fname = os.path.join(cover_dir, "%s.%s" % (coverid, cover.ext()))
79     image = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS)
80     image.save(os.path.join(settings.MEDIA_ROOT, fname))
81     return HttpResponse(os.path.join(settings.MEDIA_URL, fname))
82
83
84 @active_tab('cover')
85 def image(request, pk):
86     image = get_object_or_404(Image, pk=pk)
87
88     if request.user.has_perm('cover.change_image'):
89         if request.method == "POST":
90             form = forms.ImageEditForm(request.POST, instance=image)
91             if form.is_valid():
92                 form.save()
93                 return HttpResponseRedirect(image.get_absolute_url())
94         else:
95             form = forms.ImageEditForm(instance=image)
96         editable = True
97     else:
98         form = forms.ReadonlyImageEditForm(instance=image)
99         editable = False
100
101     return render(request, "cover/image_detail.html", {
102         "object": image,
103         "form": form,
104         "editable": editable,
105     })
106
107
108 @active_tab('cover')
109 def image_list(request):
110     objects = Image.objects.all()
111     enable_add = request.user.has_perm('cover.add_image')
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         })