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.response import validate_form
24 # Document List Handlers
26 class BasicLibraryHandler(AnonymousBaseHandler):
27 allowed_methods = ('GET',)
29 def read(self, request):
30 """Return the list of documents."""
31 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
34 'url': reverse('document_view', args=[docid]),
35 'name': docid } for docid in lib.documents() ]
37 return {'documents' : document_list}
39 class LibraryHandler(BaseHandler):
40 allowed_methods = ('GET', 'POST')
41 anonymous = BasicLibraryHandler
43 def read(self, request):
44 """Return the list of documents."""
45 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
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')
54 def create(self, request, form):
55 """Create a new document."""
56 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
58 if form.cleaned_data['ocr_data']:
59 data = form.cleaned_data['ocr_data'].encode('utf-8')
61 data = request.FILES['ocr'].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.quickwrite('xml', data, '$AUTO$ XML data uploaded.',
70 user=request.user.username)
72 url = reverse('document_view', args=[doc.id])
75 return response.EntityCreated().django_response(\
79 'revision': doc.revision },
82 except DocumentAlreadyExists:
83 # Document is already there
84 return response.EntityConflict().django_response(\
85 {"reason": "Document %s already exists." % docid})
90 class BasicDocumentHandler(AnonymousBaseHandler):
91 allowed_methods = ('GET',)
93 def read(self, request, docid):
95 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
96 doc = lib.document(docid)
97 except RevisionNotFound:
102 'text_url': reverse('doctext_view', args=[doc.id]),
103 'dc_url': reverse('docdc_view', docid=doc.id),
104 'public_revision': doc.revision,
112 class DocumentHandler(BaseHandler):
113 allowed_methods = ('GET', 'PUT')
114 anonymous = BasicDocumentHandler
116 def read(self, request, docid):
117 """Read document's meta data"""
118 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
121 doc = lib.document(docid)
122 udoc = doc.take(request.user.username)
123 except RevisionNotFound:
124 return request.EnityNotFound().django_response()
126 # is_shared = udoc.ancestorof(doc)
127 # is_uptodate = is_shared or shared.ancestorof(document)
131 'text_url': reverse('doctext_view', args=[udoc.id]),
132 'dc_url': reverse('docdc_view', args=[udoc.id]),
133 'parts_url': reverse('docparts_view', args=[udoc.id]),
134 'user_revision': udoc.revision,
135 'public_revision': doc.revision,
143 class DocumentTextHandler(BaseHandler):
144 allowed_methods = ('GET', 'PUT')
146 @validate_form(forms.DocumentEntryRequest)
147 def read(self, request, form, docid):
148 """Read document as raw text"""
149 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
152 if request.GET['revision'] == 'latest':
153 document = lib.document(docid)
155 document = lib.document_for_rev(request.GET['revision'])
157 # TODO: some finer-grained access control
158 return document.data('xml')
159 except RevisionNotFound:
160 return response.EntityNotFound().django_response()
162 def update(self, request, docid):
163 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
165 data = request.PUT['contents']
166 prev = request.PUT['revision']
168 if request.PUT.has_key('message'):
169 msg = u"$USER$ " + request.PUT['message']
171 msg = u"$AUTO$ XML content update."
173 current = lib.document(docid, request.user.username)
174 orig = lib.document_for_rev(prev)
177 return response.EntityConflict().django_response({
178 "reason": "out-of-date",
179 "provided_revision": orig.revision,
180 "latest_revision": current.revision })
182 ndoc = doc.quickwrite('xml', data, msg)
184 # return the new revision number
188 "previous_revision": prev,
189 "updated_revision": ndoc.revision
192 except (RevisionNotFound, KeyError):
193 return response.EntityNotFound().django_response()
196 # Dublin Core handlers
198 # @requires librarian
200 class DocumentDublinCoreHandler(BaseHandler):
201 allowed_methods = ('GET', 'PUT')
203 @validate_form(forms.DocumentEntryRequest)
204 def read(self, request, docid):
205 """Read document as raw text"""
206 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
208 if request.GET['revision'] == 'latest':
209 document = lib.document(docid)
211 document = lib.document_for_rev(request.GET['revision'])
213 bookinfo = dcparser.BookInfo.from_string(doc.data('xml'))
214 return bookinfo.serialize()
215 except RevisionNotFound:
216 return response.EntityNotFound().django_response()
218 def update(self, request, docid):
219 lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
221 bi_json = request.PUT['contents']
222 prev = request.PUT['revision']
223 if request.PUT.has_key('message'):
224 msg = u"$USER$ " + request.PUT['message']
226 msg = u"$AUTO$ Dublin core update."
228 current = lib.document(docid, request.user.username)
229 orig = lib.document_for_rev(prev)
232 return response.EntityConflict().django_response({
233 "reason": "out-of-date",
234 "provided": orig.revision,
235 "latest": current.revision })
237 xmldoc = parser.WLDocument.from_string(current.data('xml'))
238 document.book_info = dcparser.BookInfo.from_json(bi_json)
241 ndoc = current.quickwrite('xml', \
242 document.serialize().encode('utf-8'),\
243 message=msg, user=request.user.username)
248 "previous_revision": prev,
249 "updated_revision": ndoc.revision
251 except (RevisionNotFound, KeyError):
252 return response.EntityNotFound().django_response()