9a54ce8c07ffd4a436d8bf987a51a5e0a37d2646
[redakcja.git] / apps / api / handlers.py
1 from piston.handler import BaseHandler, AnonymousBaseHandler
2 from piston.utils import rc, validate
3
4 import settings
5 import librarian
6 import api.forms as forms
7 from datetime import date
8
9 from django.core.urlresolvers import reverse
10 from wlrepo import MercurialLibrary, CabinetNotFound
11
12 from librarian import dcparser
13
14 #
15 # Document List Handlers
16 #
17 class BasicLibraryHandler(AnonymousBaseHandler):
18     allowed_methods = ('GET',)
19
20     def read(self, request):
21         """Return the list of documents."""
22         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
23         cab = lib.main_cabinet
24
25         document_list = [{
26             'url': reverse('document_view', args=[docid]),
27             'name': docid } for docid in cab.documents() ]
28
29         return {
30             'cabinet': cab.name,
31             'latest_rev': cab.shelf(),
32             'documents' : document_list }
33
34 class LibraryHandler(BaseHandler):
35     allowed_methods = ('GET', 'POST')
36     anonymous = BasicLibraryHandler
37
38     def read(self, request):
39         """Return the list of documents."""
40         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
41         cab = lib.main_cabinet
42
43         document_list = [{
44             'url': reverse('document_view', args=[docid]),
45             'name': docid } for docid in cab.documents() ]
46
47         return {
48             'cabinet': cab.name,
49             'latest_rev': cab.shelf(),
50             'documents' : document_list }
51
52     def create(self, request):
53         """Create a new document."""
54         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
55         cab = lib.main_cabinet
56
57         form = forms.DocumentUploadForm(request.POST, request.FILES)
58         if not form.is_valid():
59             return rc.BAD_REQUEST
60
61         f = request.FILES['ocr']
62         data = f.read().decode('utf-8')
63
64         if form.cleaned_data['generate_dc']:
65             data = librarian.wrap_text(data, unicode(date.today()))
66
67         # TODO: what if the file exists ?
68         doc = cab.create(form.cleaned_data['bookname'], initial_data=data)
69         
70         return {
71             'url': reverse('document_view', args=[doc.name]),
72             'name': doc.name,
73             'size': doc.size,
74             'revision': doc.shelf() }
75
76 #
77 # Document Handlers
78 #
79 class BasicDocumentHandler(AnonymousBaseHandler):
80     allowed_methods = ('GET',)
81
82     def read(self, request, docid):
83         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
84
85         opts = forms.DocumentGetForm(request.GET)
86         if not opts.is_valid():
87             return rc.BAD_REQUEST
88
89         document = lib.main_cabinet.retrieve(docid)        
90
91         result = {
92             'name': document.name,
93             'size': document.size,
94             'text_url': reverse('doctext_view', args=[docid]),
95             #'dc_url': reverse('docdc_view', docid=document.name),
96             #'parts_url': reverse('docparts_view', docid=document.name),
97             'latest_rev': document.shelf(),          
98         }
99
100         if request.GET.get('with_part', 'no') == 'yes':
101             result['parts'] = document.parts()
102
103         return result   
104
105 #
106 # Document Meta Data
107 #
108 class DocumentHandler(BaseHandler):
109     allowed_methods = ('GET', 'PUT')
110     anonymous = BasicDocumentHandler
111     
112     def read(self, request, docid):
113         """Read document's meta data"""        
114         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
115
116         opts = forms.DocumentGetForm(request.GET)
117         if not opts.is_valid():
118             return rc.BAD_REQUEST
119               
120         document = lib.cabinet(docid, request.user.username, \
121                 create=opts.cleaned_data['autocabinet'] ).retrieve()
122
123         if not document:
124             return rc.NOT_HERE
125                 
126         shared = lib.main_cabinet.retrieve(docid)
127
128         is_shared = document.ancestorof(shared)
129         # is_uptodate = is_shared or shared.ancestorof(document)
130
131         result = {
132             'name': document.name,
133             'size': document.size,
134             'text_url': reverse('doctext_view', args=[docid]),
135             'dc_url': reverse('docdc_view', args=[docid]),
136             'parts_url': reverse('docparts_view', args=[docid]),
137             'latest_rev': document.shelf(),
138             'latest_shared_rev': shared.shelf(),
139             'shared': is_shared,
140             # 'up_to_date': is_uptodate,
141         }
142
143         #if request.GET.get('with_part', 'no') == 'yes':
144         #    result['parts'] = document.parts()
145
146         return result        
147
148 #
149 # Document Text View
150 #
151 class DocumentTextHandler(BaseHandler):
152     allowed_methods = ('GET', 'PUT')
153
154     def read(self, request, docid):
155         """Read document as raw text"""
156         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
157         try:
158             # latest rev
159             # comment
160             return lib.document(docid, request.user.username).read()
161         except CabinetNotFound:
162             return rc.NOT_HERE
163
164     def update(self, request, docid):
165         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
166         try:
167             # check latest REV
168             data = request.PUT['contents']
169             lib.document(docid, request.user.username).write(data)
170             return rc.ALL_OK
171         except (CabinetNotFound, KeyError):
172             return rc.NOT_HERE
173
174
175 #
176 # Dublin Core handlers
177 #
178 # @requires librarian
179 #
180 class DocumentDublinCoreHandler(BaseHandler):
181     allowed_methods = ('GET', 'PUT')
182
183     def read(self, request, docid):
184         """Read document as raw text"""
185         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
186         try:
187             doc = lib.document(docid, request.user.username)
188
189             # TODO: RAL:document should support file-like ops
190             bookinfo = dcparser.BookInfo.from_string(doc.read())
191             return bookinfo.serialize()
192         except CabinetNotFound:
193             return rc.NOT_HERE
194
195     def update(self, request, docid):
196         lib = MercurialLibrary(path=settings.REPOSITORY_PATH)
197         try:
198             data = request.PUT['contents']
199             lib.document(docid, request.user.username).write(data)
200             return rc.ALL_OK
201         except (CabinetNotFound, KeyError):
202             return rc.NOT_HERE
203