1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
28 from string import joinfields, split, lower
30 from service import security
35 from DAV.constants import COLLECTION, OBJECT
36 from DAV.errors import *
37 from DAV.iface import *
40 from DAV.davcmd import copyone, copytree, moveone, movetree, delone, deltree
41 from caldav_cache import memoize
42 from tools import misc
46 class tinydav_handler(dav_interface):
48 This class models a Tiny ERP interface for the DAV server
50 PROPS={'DAV:': dav_interface.PROPS['DAV:'], }
52 M_NS={ "DAV:" : dav_interface.M_NS['DAV:'], }
54 def __init__(self, parent, verbose=False):
57 self.baseuri = parent.baseuri
59 def get_propnames(self, uri):
61 self.parent.log_message('get propnames: %s' % uri)
62 if uri[-1]=='/':uri=uri[:-1]
63 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
67 node = self.uri2object(cr,uid,pool, uri2)
69 props.update(node.get_dav_props(cr))
73 def get_prop(self,uri,ns,propname):
74 """ return the value of a given property
76 uri -- uri of the object to get the property of
77 ns -- namespace of the property
78 pname -- name of the property
80 if self.M_NS.has_key(ns):
81 return dav_interface.get_prop(self,uri,ns,propname)
83 if uri[-1]=='/':uri=uri[:-1]
84 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
88 node = self.uri2object(cr,uid,pool, uri2)
92 res = node.get_dav_eprop(cr,ns,propname)
96 def urijoin(self,*ajoin):
97 """ Return the base URI of this request, or even join it with the
100 return self.baseuri+ '/'.join(ajoin)
102 def uri2local(self, uri):
103 uparts=urlparse.urlparse(uri)
105 if reluri and reluri[-1]=="/":
110 # pos: -1 to get the parent of the uri
112 def get_cr(self, uri):
113 pdb = self.parent.auth_proxy.last_auth
114 reluri = self.uri2local(uri)
116 dbname = reluri.split('/')[2]
120 return None, None, None, False, None
121 if not pdb and dbname:
122 # if dbname was in our uri, we should have authenticated
124 raise Exception("Programming error")
125 assert pdb == dbname, " %s != %s" %(pdb, dbname)
126 user, passwd, dbn2, uid = self.parent.auth_proxy.auth_creds[pdb]
127 db,pool = pooler.get_db_and_pool(dbname)
129 uri2 = reluri.split('/')[3:]
130 return cr, uid, pool, dbname, uri2
132 def uri2object(self, cr, uid, pool, uri):
135 return pool.get('basic.calendar').get_calendar_object(cr, uid, uri)
137 def get_data(self,uri):
138 self.parent.log_message('GET: %s' % uri)
139 if uri[-1]=='/':uri=uri[:-1]
140 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
144 node = self.uri2object(cr,uid,pool, uri2)
146 raise DAV_NotFound(uri2)
148 datas = node.get_data(cr, uid)
151 self.parent.log_error("GET typeError: %s", str(e))
152 self.parent.log_message("Exc: %s",traceback.format_exc())
154 except IndexError,e :
155 self.parent.log_error("GET IndexError: %s", str(e))
156 raise DAV_NotFound(uri2)
159 self.parent.log_error("GET exception: %s",str(e))
160 self.parent.log_message("Exc: %s", traceback.format_exc())
167 def _get_dav_resourcetype(self,uri):
168 """ return type of object """
169 self.parent.log_message('get RT: %s' % uri)
170 if uri[-1]=='/':uri=uri[:-1]
171 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
175 node = self.uri2object(cr,uid,pool, uri2)
177 raise DAV_NotFound(uri2)
182 def _get_dav_displayname(self,uri):
183 self.parent.log_message('get DN: %s' % uri)
184 if uri[-1]=='/':uri=uri[:-1]
185 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
189 node = self.uri2object(cr,uid,pool, uri2)
192 raise DAV_NotFound(uri2)
194 return node.displayname
197 def _get_dav_getcontentlength(self,uri):
198 """ return the content length of an object """
199 self.parent.log_message('get length: %s' % uri)
200 if uri[-1]=='/':uri=uri[:-1]
202 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
206 node = self.uri2object(cr, uid, pool, uri2)
209 raise DAV_NotFound(uri2)
210 result = node.content_length or 0
215 def _get_dav_getetag(self,uri):
216 """ return the ETag of an object """
217 self.parent.log_message('get etag: %s' % uri)
218 if uri[-1]=='/':uri=uri[:-1]
220 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
224 node = self.uri2object(cr, uid, pool, uri2)
227 raise DAV_NotFound(uri2)
228 result = node.get_etag(cr)
233 def get_lastmodified(self,uri):
234 """ return the last modified date of the object """
235 if uri[-1]=='/':uri=uri[:-1]
237 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
241 node = self.uri2object(cr,uid,pool, uri2)
243 raise DAV_NotFound(uri2)
245 return time.mktime(time.strptime(node.write_date,'%Y-%m-%d %H:%M:%S'))
252 def get_creationdate(self,uri):
253 """ return the last modified date of the object """
255 if uri[-1]=='/':uri=uri[:-1]
256 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
260 node = self.uri2object(cr,uid,pool, uri2)
262 raise DAV_NotFound(uri2)
264 result = time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S')
266 result = time.gmtime()
272 def _get_dav_getcontenttype(self,uri):
273 self.parent.log_message('get contenttype: %s' % uri)
274 if uri[-1]=='/':uri=uri[:-1]
275 cr, uid, pool, dbname, uri2 = self.get_cr(uri)
278 return 'httpd/unix-directory'
279 node = self.uri2object(cr,uid,pool, uri2)
281 raise DAV_NotFound(uri2)
282 result = node.mimetype
284 #raise DAV_NotFound, 'Could not find %s' % path
290 def put(self, uri, data, content_type=None):
291 """ put the object into the filesystem """
292 self.parent.log_message('Putting %s (%d), %s'%( misc.ustr(uri), len(data), content_type))
293 parent='/'.join(uri.split('/')[:-1])
294 cr, uid, pool,dbname, uri2 = self.get_cr(uri)
298 node = self.uri2object(cr,uid,pool, uri2[:])
306 node.set_data(cr, uid, data)
309 self.parent.log_error("Cannot save :%s", str(e))
310 self.parent.log_message("Exc: %s",traceback.format_exc())
320 def exists(self,uri):
321 """ test if a resource exists """
323 cr, uid, pool,dbname, uri2 = self.get_cr(uri)
328 node = self.uri2object(cr,uid,pool, uri2)