Merge branch 'master' into view-refactor
[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 settings
11 import librarian
12 import api.forms as forms
13 from datetime import date
14
15 from django.core.urlresolvers import reverse
16
17 from wlrepo import MercurialLibrary, 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             'text_url': reverse('doctext_view', args=[doc.id,doc.revision]),
102             'dc_url': reverse('docdc_view', args=[doc.id,doc.revision]),
103             'public_revision': doc.revision,
104         }
105
106         return result
107
108 #
109 # Document Meta Data
110 #
111 class DocumentHandler(BaseHandler):
112     allowed_methods = ('GET', 'PUT')
113     anonymous = BasicDocumentHandler
114
115     @hglibrary
116     def read(self, request, docid, lib):
117         """Read document's meta data"""       
118         try:
119             doc = lib.document(docid)
120             udoc = doc.take(request.user.username)
121         except RevisionNotFound:
122             return request.EnityNotFound().django_response()
123
124         # is_shared = udoc.ancestorof(doc)
125         # is_uptodate = is_shared or shared.ancestorof(document)
126
127         result = {
128             'name': udoc.id,
129             'text_url': reverse('doctext_view', args=[doc.id,doc.revision]),
130             'dc_url': reverse('docdc_view', args=[doc.id,doc.revision]),
131             'user_revision': udoc.revision,
132             'public_revision': doc.revision,            
133         }       
134
135         return result
136
137     @hglibrary
138     def update(self, request, docid, lib):
139         """Update information about the document, like display not"""
140         return
141
142 #
143 # Document Text View
144 #
145 class DocumentTextHandler(BaseHandler):
146     allowed_methods = ('GET', 'PUT')
147
148     @hglibrary
149     def read(self, request, docid, revision, lib):
150         """Read document as raw text"""               
151         try:
152             if revision == 'latest':
153                 document = lib.document(docid)
154             else:
155                 document = lib.document_for_rev(revision)
156             
157             # TODO: some finer-grained access control
158             return document.data('xml')
159         except RevisionNotFound:
160             return response.EntityNotFound().django_response()
161
162     @hglibrary
163     def update(self, request, docid, revision, lib):
164         try:
165             data = request.PUT['contents']            
166
167             if request.PUT.has_key('message'):
168                 msg = u"$USER$ " + request.PUT['message']
169             else:
170                 msg = u"$AUTO$ XML content update."
171
172             current = lib.document(docid, request.user.username)
173             orig = lib.document_for_rev(revision)
174
175             if current != orig:
176                 return response.EntityConflict().django_response({
177                         "reason": "out-of-date",
178                         "provided_revision": orig.revision,
179                         "latest_revision": current.revision })
180
181             ndoc = doc.quickwrite('xml', data, msg)
182
183             # return the new revision number
184             return {
185                 "document": ndoc.id,
186                 "subview": "xml",
187                 "previous_revision": prev,
188                 "updated_revision": ndoc.revision
189             }
190         
191         except (RevisionNotFound, KeyError):
192             return response.EntityNotFound().django_response()
193
194 #
195 # Dublin Core handlers
196 #
197 # @requires librarian
198 #
199 class DocumentDublinCoreHandler(BaseHandler):
200     allowed_methods = ('GET', 'PUT')
201
202     @hglibrary
203     def read(self, request, docid, revision, lib):
204         """Read document as raw text"""        
205         try:
206             if revision == 'latest':
207                 document = lib.document(docid)
208             else:
209                 document = lib.document_for_rev(revision)
210             
211             bookinfo = dcparser.BookInfo.from_string(doc.data('xml'))
212             return bookinfo.serialize()
213         except RevisionNotFound:
214             return response.EntityNotFound().django_response()
215
216     @hglibrary
217     def update(self, request, docid, revision, lib):
218         try:
219             bi_json = request.PUT['contents']            
220             if request.PUT.has_key('message'):
221                 msg = u"$USER$ " + request.PUT['message']
222             else:
223                 msg = u"$AUTO$ Dublin core update."
224
225             current = lib.document(docid, request.user.username)
226             orig = lib.document_for_rev(revision)
227
228             if current != orig:
229                 return response.EntityConflict().django_response({
230                         "reason": "out-of-date",
231                         "provided": orig.revision,
232                         "latest": current.revision })
233
234             xmldoc = parser.WLDocument.from_string(current.data('xml'))
235             document.book_info = dcparser.BookInfo.from_json(bi_json)
236
237             # zapisz
238             ndoc = current.quickwrite('xml', \
239                 document.serialize().encode('utf-8'),\
240                 message=msg, user=request.user.username)
241
242             return {
243                 "document": ndoc.id,
244                 "subview": "xml",
245                 "previous_revision": prev,
246                 "updated_revision": ndoc.revision
247             }
248         except (RevisionNotFound, KeyError):
249             return response.EntityNotFound().django_response()
250
251
252 class MergeHandler(BaseHandler):
253     allowed_methods = ('POST',)
254
255     @validate_form(forms.MergeRequestForm)
256     @hglibrary
257     def create(self, request, form, docid, lib):
258         """Create a new document revision from the information provided by user"""
259
260         pass
261
262         
263         
264