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