64e933056fcbc8cd5e66d2c5dc17cb5a71bc07c6
[redakcja.git] / apps / wiki / views.py
1 import os
2
3 from django.conf import settings
4 from django.views.generic.simple import direct_to_template
5 from django.views.decorators.http import require_POST
6 from .helpers import JSONResponse, JSONFormInvalid, JSONServerError
7 from django import http
8
9 from wiki.models import getstorage
10 from wiki.forms import DocumentForm, DocumentTextSaveForm, DocumentTagForm
11 from datetime import datetime
12 from django.utils.encoding import smart_unicode
13 import wlapi
14
15 #
16 # Quick hack around caching problems, TODO: use ETags
17 #
18 from django.views.decorators.cache import never_cache
19
20 import logging
21 logger = logging.getLogger("fnp.peanut.api")
22
23 import nice_diff
24 import operator
25
26 MAX_LAST_DOCS = 10
27
28
29 @never_cache
30 def document_list(request, template_name='wiki/document_list.html'):
31     # TODO: find a way to cache "Storage All"
32     return direct_to_template(request, template_name, extra_context={
33         'document_list': getstorage().all(),
34         'last_docs': sorted(request.session.get("wiki_last_docs", {}).items(),
35                         key=operator.itemgetter(1), reverse=True),
36     })
37
38
39 @never_cache
40 def document_detail(request, name, template_name='wiki/document_details.html'):
41
42     document = getstorage().get_or_404(name)
43
44     access_time = datetime.now()
45     last_documents = request.session.get("wiki_last_docs", {})
46     last_documents[name] = access_time
47
48     if len(last_documents) > MAX_LAST_DOCS:
49         oldest_key = min(last_documents, key=last_documents.__getitem__)
50         del last_documents[oldest_key]
51     request.session['wiki_last_docs'] = last_documents
52
53     return direct_to_template(request, template_name, extra_context={
54         'document': document,
55         'document_info': document.info,
56         'document_meta': document.meta,
57         'forms': {"text_save": DocumentTextSaveForm(), "add_tag": DocumentTagForm()},
58     })
59
60
61 @never_cache
62 def document_text(request, name):
63     storage = getstorage()
64     document = storage.get_or_404(name)
65
66     if request.method == 'POST':
67         form = DocumentTextSaveForm(request.POST)
68
69         if form.is_valid():
70             revision = form.cleaned_data['parent_revision']
71             document.text = form.cleaned_data['text']
72
73             storage.put(document,
74                 author=form.cleaned_data['author'] or request.user.username,
75                 comment=form.cleaned_data['comment'],
76                 parent=revision,
77             )
78
79             return JSONResponse({
80                 'text': document.plain_text if revision != document.revision() else None,
81                 'meta': document.meta(),
82                 'revision': document.revision(),
83             })
84         else:
85             return JSONFormInvalid(form)
86     else:
87         return JSONResponse({
88             'text': document.plain_text,
89             'meta': document.meta(),
90             'revision': document.revision(),
91         })
92
93
94 @never_cache
95 def document_gallery(request, directory):
96     try:
97         base_url = ''.join((
98                         smart_unicode(settings.MEDIA_URL),
99                         smart_unicode(settings.FILEBROWSER_DIRECTORY),
100                         smart_unicode(directory)))
101
102         base_dir = os.path.join(
103                     smart_unicode(settings.MEDIA_ROOT),
104                     smart_unicode(settings.FILEBROWSER_DIRECTORY),
105                     smart_unicode(directory))
106
107         def map_to_url(filename):
108             return "%s/%s" % (base_url, smart_unicode(filename))
109
110         def is_image(filename):
111             return os.path.splitext(f)[1].lower() in (u'.jpg', u'.jpeg', u'.png')
112
113         images = [map_to_url(f) for f in map(smart_unicode, os.listdir(base_dir)) if is_image(f)]
114         images.sort()
115         return JSONResponse(images)
116     except (IndexError, OSError), exc:
117         import traceback
118         traceback.print_exc()
119         raise http.Http404
120
121
122 @never_cache
123 def document_diff(request, name):
124     storage = getstorage()
125
126     revA = int(request.GET.get('from', 0))
127     revB = int(request.GET.get('to', 0))
128
129     if revA > revB:
130         revA, revB = revB, revA
131
132     if revB == 0:
133         revB = None
134
135     docA = storage.get_or_404(name, int(revA))
136     docB = storage.get_or_404(name, int(revB))
137
138     return http.HttpResponse(nice_diff.html_diff_table(docA.plain_text.splitlines(),
139                                          docB.plain_text.splitlines()))
140
141
142 @never_cache
143 def document_history(request, name):
144     storage = getstorage()
145     return JSONResponse(storage.history(name))
146
147
148 @require_POST
149 def document_add_tag(request, name):
150     storage = getstorage()
151
152     form = DocumentTagForm(request.POST)
153     if form.is_valid():
154         doc = storage.get_or_404(name, form.cleaned_data['version'])
155         doc.add_tag(form.cleaned_data['tag'])
156         return JSONResponse({"message": _("Tag added")})
157     else:
158         return JSONFormInvalid(form)
159
160
161 @require_POST
162 def document_publish(request, name, version):
163     storage = getstorage()
164
165     # get the document
166     document = storage.get_or_404(name, revision=int(version))
167
168     api = wlapi.WLAPI(settings.WL_API_CONFIG)
169     try:
170         return JSONResponse({"result": api.publish_book(document)})
171     except wlapi.APICallException, e:
172         return JSONServerError({"message": str(e)})