8862de0c95e58d9d139e97588b3625fea5107ec4
[redakcja.git] / apps / api / handlers / library_handlers.py
1 # -*- encoding: utf-8 -*-
2
3 __author__= "Ɓukasz Rekucki"
4 __date__ = "$2009-09-25 15:49:50$"
5 __doc__ = "Module documentation."
6
7 from piston.handler import BaseHandler, AnonymousBaseHandler
8
9
10 import librarian
11 import librarian.html
12 import api.forms as forms
13 from datetime import date
14
15 from django.core.urlresolvers import reverse
16
17 from wlrepo import RevisionNotFound, DocumentAlreadyExists
18 from librarian import dcparser
19
20 import api.response as response
21 from api.utils import validate_form, hglibrary
22
23 #
24 # Document List Handlers
25 #
26 class BasicLibraryHandler(AnonymousBaseHandler):
27     allowed_methods = ('GET',)
28
29     @hglibrary
30     def read(self, request, lib):
31         """Return the list of documents."""       
32         document_list = [{
33             'url': reverse('document_view', args=[docid]),
34             'name': docid } for docid in lib.documents() ]
35
36         return {'documents' : document_list}
37         
38
39 class LibraryHandler(BaseHandler):
40     allowed_methods = ('GET', 'POST')
41     anonymous = BasicLibraryHandler
42
43     @hglibrary
44     def read(self, request, lib):
45         """Return the list of documents."""
46
47         document_list = [{
48             'url': reverse('document_view', args=[docid]),
49             'name': docid } for docid in lib.documents() ]
50
51         return {'documents' : document_list }        
52
53     @validate_form(forms.DocumentUploadForm, 'POST')
54     @hglibrary
55     def create(self, request, form, lib):
56         """Create a new document."""       
57
58         if form.cleaned_data['ocr_data']:
59             data = form.cleaned_data['ocr_data'].encode('utf-8')
60         else:            
61             data = request.FILES['ocr_file'].read().decode('utf-8')
62
63         if form.cleaned_data['generate_dc']:
64             data = librarian.wrap_text(data, unicode(date.today()))
65
66         docid = form.cleaned_data['bookname']
67         try:
68             doc = lib.document_create(docid)
69             doc = doc.quickwrite('xml', data, '$AUTO$ XML data uploaded.',
70                 user=request.user.username)
71
72             url = reverse('document_view', args=[doc.id])
73
74             return response.EntityCreated().django_response(\
75                 body = {
76                     'url': url,
77                     'name': doc.id,
78                     'revision': doc.revision },
79                 url = url )
80                 
81         except DocumentAlreadyExists:
82             # Document is already there
83             return response.EntityConflict().django_response(\
84                 {"reason": "Document %s already exists." % docid})
85
86 #
87 # Document Handlers
88 #
89 class BasicDocumentHandler(AnonymousBaseHandler):
90     allowed_methods = ('GET',)
91
92     @hglibrary
93     def read(self, request, docid, lib):
94         try:    
95             doc = lib.document(docid)
96         except RevisionNotFound:
97             return rc.NOT_FOUND
98
99         result = {
100             'name': doc.id,
101             'html_url': reverse('dochtml_view', args=[doc.id,doc.revision]),
102             'text_url': reverse('doctext_view', args=[doc.id,doc.revision]),
103             'dc_url': reverse('docdc_view', args=[doc.id,doc.revision]),
104             'public_revision': doc.revision,
105         }
106
107         return result
108
109 #
110 # Document Meta Data
111 #
112 class DocumentHandler(BaseHandler):
113     allowed_methods = ('GET', 'PUT')
114     anonymous = BasicDocumentHandler
115
116     @hglibrary
117     def read(self, request, docid, lib):
118         """Read document's meta data"""       
119         try:
120             doc = lib.document(docid)
121             udoc = doc.take(request.user.username)
122         except RevisionNotFound:
123             return request.EnityNotFound().django_response()
124
125         # is_shared = udoc.ancestorof(doc)
126         # is_uptodate = is_shared or shared.ancestorof(document)
127
128         result = {
129             'name': udoc.id,
130             'html_url': reverse('dochtml_view', args=[doc.id,doc.revision]),
131             'text_url': reverse('doctext_view', args=[doc.id,doc.revision]),
132             'dc_url': reverse('docdc_view', args=[doc.id,doc.revision]),
133             'user_revision': udoc.revision,
134             'public_revision': doc.revision,            
135         }       
136
137         return result
138
139     @hglibrary
140     def update(self, request, docid, lib):
141         """Update information about the document, like display not"""
142         return
143 #
144 #
145 #
146
147 class DocumentHTMLHandler(BaseHandler):
148     allowed_methods = ('GET', 'PUT')
149
150     @hglibrary
151     def read(self, request, docid, revision, lib):
152         """Read document as html text"""
153         try:
154             if revision == 'latest':
155                 document = lib.document(docid)
156             else:
157                 document = lib.document_for_rev(revision)
158
159             return librarian.html.transform(document.data('xml'))
160         except RevisionNotFound:
161             return response.EntityNotFound().django_response()
162
163 #
164 # Document Text View
165 #
166 class DocumentTextHandler(BaseHandler):
167     allowed_methods = ('GET', 'PUT')
168
169     @hglibrary
170     def read(self, request, docid, revision, lib):
171         """Read document as raw text"""               
172         try:
173             if revision == 'latest':
174                 document = lib.document(docid)
175             else:
176                 document = lib.document_for_rev(revision)
177             
178             # TODO: some finer-grained access control
179             return document.data('xml')
180         except RevisionNotFound:
181             return response.EntityNotFound().django_response()
182
183     @hglibrary
184     def update(self, request, docid, revision, lib):
185         try:
186             data = request.PUT['contents']            
187
188             if request.PUT.has_key('message'):
189                 msg = u"$USER$ " + request.PUT['message']
190             else:
191                 msg = u"$AUTO$ XML content update."
192
193             current = lib.document(docid, request.user.username)
194             orig = lib.document_for_rev(revision)
195
196             if current != orig:
197                 return response.EntityConflict().django_response({
198                         "reason": "out-of-date",
199                         "provided_revision": orig.revision,
200                         "latest_revision": current.revision })
201
202             ndoc = doc.quickwrite('xml', data, msg)
203
204             # return the new revision number
205             return {
206                 "document": ndoc.id,
207                 "subview": "xml",
208                 "previous_revision": prev,
209                 "updated_revision": ndoc.revision
210             }
211         
212         except (RevisionNotFound, KeyError):
213             return response.EntityNotFound().django_response()
214
215 #
216 # Dublin Core handlers
217 #
218 # @requires librarian
219 #
220 class DocumentDublinCoreHandler(BaseHandler):
221     allowed_methods = ('GET', 'PUT')
222
223     @hglibrary
224     def read(self, request, docid, revision, lib):
225         """Read document as raw text"""        
226         try:
227             if revision == 'latest':
228                 document = lib.document(docid)
229             else:
230                 document = lib.document_for_rev(revision)
231             
232             bookinfo = dcparser.BookInfo.from_string(doc.data('xml'))
233             return bookinfo.serialize()
234         except RevisionNotFound:
235             return response.EntityNotFound().django_response()
236
237     @hglibrary
238     def update(self, request, docid, revision, lib):
239         try:
240             bi_json = request.PUT['contents']            
241             if request.PUT.has_key('message'):
242                 msg = u"$USER$ " + request.PUT['message']
243             else:
244                 msg = u"$AUTO$ Dublin core update."
245
246             current = lib.document(docid, request.user.username)
247             orig = lib.document_for_rev(revision)
248
249             if current != orig:
250                 return response.EntityConflict().django_response({
251                         "reason": "out-of-date",
252                         "provided": orig.revision,
253                         "latest": current.revision })
254
255             xmldoc = parser.WLDocument.from_string(current.data('xml'))
256             document.book_info = dcparser.BookInfo.from_json(bi_json)
257
258             # zapisz
259             ndoc = current.quickwrite('xml', \
260                 document.serialize().encode('utf-8'),\
261                 message=msg, user=request.user.username)
262
263             return {
264                 "document": ndoc.id,
265                 "subview": "xml",
266                 "previous_revision": prev,
267                 "updated_revision": ndoc.revision
268             }
269         except (RevisionNotFound, KeyError):
270             return response.EntityNotFound().django_response()
271
272
273 class MergeHandler(BaseHandler):
274     allowed_methods = ('POST',)
275
276     @validate_form(forms.MergeRequestForm)
277     @hglibrary
278     def create(self, request, form, docid, lib):
279         """Create a new document revision from the information provided by user"""
280
281         pass
282
283         
284         
285