1 # -*- encoding: utf-8 -*-
3 __author__= "Ćukasz Rekucki"
4 __date__ = "$2009-09-25 15:49:50$"
5 __doc__ = "Module documentation."
7 from piston.handler import BaseHandler, AnonymousBaseHandler
12 import api.forms as forms
13 from datetime import date
15 from django.core.urlresolvers import reverse
17 from wlrepo import MercurialLibrary, RevisionNotFound, DocumentAlreadyExists
18 from librarian import dcparser
20 import api.response as response
21 from api.utils import validate_form, hglibrary
24 # Document List Handlers
26 class BasicLibraryHandler(AnonymousBaseHandler):
27 allowed_methods = ('GET',)
30 def read(self, request, lib):
31 """Return the list of documents."""
33 'url': reverse('document_view', args=[docid]),
34 'name': docid } for docid in lib.documents() ]
36 return {'documents' : document_list}
39 class LibraryHandler(BaseHandler):
40 allowed_methods = ('GET', 'POST')
41 anonymous = BasicLibraryHandler
44 def read(self, request, lib):
45 """Return the list of documents."""
48 'url': reverse('document_view', args=[docid]),
49 'name': docid } for docid in lib.documents() ]
51 return {'documents' : document_list }
53 @validate_form(forms.DocumentUploadForm, 'POST')
55 def create(self, request, form, lib):
56 """Create a new document."""
58 if form.cleaned_data['ocr_data']:
59 data = form.cleaned_data['ocr_data'].encode('utf-8')
61 data = request.FILES['ocr_file'].read().decode('utf-8')
63 if form.cleaned_data['generate_dc']:
64 data = librarian.wrap_text(data, unicode(date.today()))
66 docid = form.cleaned_data['bookname']
68 doc = lib.document_create(docid)
69 doc = doc.quickwrite('xml', data, '$AUTO$ XML data uploaded.',
70 user=request.user.username)
72 url = reverse('document_view', args=[doc.id])
74 return response.EntityCreated().django_response(\
78 'revision': doc.revision },
81 except DocumentAlreadyExists:
82 # Document is already there
83 return response.EntityConflict().django_response(\
84 {"reason": "Document %s already exists." % docid})
89 class BasicDocumentHandler(AnonymousBaseHandler):
90 allowed_methods = ('GET',)
93 def read(self, request, docid, lib):
95 doc = lib.document(docid)
96 except RevisionNotFound:
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,
111 class DocumentHandler(BaseHandler):
112 allowed_methods = ('GET', 'PUT')
113 anonymous = BasicDocumentHandler
116 def read(self, request, docid, lib):
117 """Read document's meta data"""
119 doc = lib.document(docid)
120 udoc = doc.take(request.user.username)
121 except RevisionNotFound:
122 return request.EnityNotFound().django_response()
124 # is_shared = udoc.ancestorof(doc)
125 # is_uptodate = is_shared or shared.ancestorof(document)
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,
138 def update(self, request, docid, lib):
139 """Update information about the document, like display not"""
145 class DocumentTextHandler(BaseHandler):
146 allowed_methods = ('GET', 'PUT')
149 def read(self, request, docid, revision, lib):
150 """Read document as raw text"""
152 if revision == 'latest':
153 document = lib.document(docid)
155 document = lib.document_for_rev(revision)
157 # TODO: some finer-grained access control
158 return document.data('xml')
159 except RevisionNotFound:
160 return response.EntityNotFound().django_response()
163 def update(self, request, docid, revision, lib):
165 data = request.PUT['contents']
167 if request.PUT.has_key('message'):
168 msg = u"$USER$ " + request.PUT['message']
170 msg = u"$AUTO$ XML content update."
172 current = lib.document(docid, request.user.username)
173 orig = lib.document_for_rev(revision)
176 return response.EntityConflict().django_response({
177 "reason": "out-of-date",
178 "provided_revision": orig.revision,
179 "latest_revision": current.revision })
181 ndoc = doc.quickwrite('xml', data, msg)
183 # return the new revision number
187 "previous_revision": prev,
188 "updated_revision": ndoc.revision
191 except (RevisionNotFound, KeyError):
192 return response.EntityNotFound().django_response()
195 # Dublin Core handlers
197 # @requires librarian
199 class DocumentDublinCoreHandler(BaseHandler):
200 allowed_methods = ('GET', 'PUT')
203 def read(self, request, docid, revision, lib):
204 """Read document as raw text"""
206 if revision == 'latest':
207 document = lib.document(docid)
209 document = lib.document_for_rev(revision)
211 bookinfo = dcparser.BookInfo.from_string(doc.data('xml'))
212 return bookinfo.serialize()
213 except RevisionNotFound:
214 return response.EntityNotFound().django_response()
217 def update(self, request, docid, revision, lib):
219 bi_json = request.PUT['contents']
220 if request.PUT.has_key('message'):
221 msg = u"$USER$ " + request.PUT['message']
223 msg = u"$AUTO$ Dublin core update."
225 current = lib.document(docid, request.user.username)
226 orig = lib.document_for_rev(revision)
229 return response.EntityConflict().django_response({
230 "reason": "out-of-date",
231 "provided": orig.revision,
232 "latest": current.revision })
234 xmldoc = parser.WLDocument.from_string(current.data('xml'))
235 document.book_info = dcparser.BookInfo.from_json(bi_json)
238 ndoc = current.quickwrite('xml', \
239 document.serialize().encode('utf-8'),\
240 message=msg, user=request.user.username)
245 "previous_revision": prev,
246 "updated_revision": ndoc.revision
248 except (RevisionNotFound, KeyError):
249 return response.EntityNotFound().django_response()
252 class MergeHandler(BaseHandler):
253 allowed_methods = ('POST',)
255 @validate_form(forms.MergeRequestForm)
257 def create(self, request, form, docid, lib):
258 """Create a new document revision from the information provided by user"""