7
from string import joinfields, split, lower
9
from DAV import AuthServer
10
from service import security
15
from content_index import content_index
17
from DAV.constants import COLLECTION, OBJECT
18
from DAV.errors import *
19
from DAV.iface import *
22
from DAV.davcmd import copyone, copytree, moveone, movetree, delone, deltree
24
from cache import memoize
28
class tinyerp_handler(dav_interface):
30
This class models a Tiny ERP interface for the DAV server
32
def __init__(self, host,port, verbose=False):
34
self.directory_id=False
37
self.baseuri = 'http://%s:%s/' % (self.host, self.port)
41
# def get_db(self,uri):
42
# names=self.uri2local(uri).split('/')
45
# self.db_name=self.uri2local(uri).split('/')[1]
46
# if self.db_name=='':
47
# raise Exception,'Plese specify Database name in folder'
53
reluri = self.uri2local(uri)
54
return not len(reluri.split('/'))>1
59
s = netsvc.LocalService('db')
62
for db_name in result:
63
db = pooler.get_db_only(db_name)
65
cr.execute("select id from ir_module_module where name = 'document' and state='installed' ")
68
self.db_name_list.append(db_name)
70
return self.db_name_list
72
def get_childs(self,uri):
73
""" return the child objects as self.baseuris for the given URI """
75
s = netsvc.LocalService('db')
76
return map(lambda x: urlparse.urljoin(self.baseuri, x), self.db_list())
78
if uri[-1]=='/':uri=uri[:-1]
79
cr, uid, pool, uri2 = self.get_cr(uri)
80
node = self.uri2object(cr,uid,pool, uri2[:])
81
for d in node.children():
82
result.append( urlparse.urljoin(self.baseuri, d.path) )
85
def uri2local(self, uri):
86
uparts=urlparse.urlparse(uri)
88
if reluri and reluri[-1]=="/":
93
# pos: -1 to get the parent of the uri
95
def get_cr(self, uri):
96
reluri = self.uri2local(uri)
97
dbname = reluri.split('/')[1]
98
uid = security.login(dbname, dav_auth.auth['user'], dav_auth.auth['pwd'])
99
db,pool = pooler.get_db_and_pool(dbname)
101
uri2 = reluri.split('/')[1:]
102
return cr, uid, pool, uri2
104
def uri2object(self, cr,uid, pool,uri):
105
return pool.get('document.directory').get_object(cr, uid, uri)
107
def get_data(self,uri):
110
if uri[-1]=='/':uri=uri[:-1]
111
cr, uid, pool, uri2 = self.get_cr(uri)
112
node = self.uri2object(cr,uid,pool, uri2)
115
if node.type=='file':
117
if node.object.datas:
118
datas=node.object.datas
119
elif node.object.link:
121
datas=base64.encodestring(urllib.urlopen(node.object.link).read())
122
return base64.decodestring(datas or '')
123
elif node.type=='content':
124
report = pool.get('ir.actions.report.xml').browse(cr, uid, node.content['report_id']['id'])
125
srv = netsvc.LocalService('report.'+report.report_name)
126
pdf,pdftype = srv.create(cr, uid, [node.object.id], {}, {})
132
def _get_dav_resourcetype(self,uri):
133
""" return type of object """
135
if uri[-1]=='/':uri=uri[:-1]
138
cr, uid, pool, uri2 = self.get_cr(uri)
139
node = self.uri2object(cr,uid,pool, uri2)
141
if node.type in ('collection','database'):
145
def _get_dav_displayname(self,uri):
149
def _get_dav_getcontentlength(self,uri):
150
""" return the content length of an object """
151
print 'Get DAV CL', uri
152
if uri[-1]=='/':uri=uri[:-1]
156
cr, uid, pool, uri2 = self.get_cr(uri)
157
node = self.uri2object(cr, uid, pool, uri2)
158
if node.type=='file':
159
result = node.object.file_size or 0
164
def get_lastmodified(self,uri):
165
""" return the last modified date of the object """
166
print 'Get DAV Mod', uri
167
if uri[-1]=='/':uri=uri[:-1]
172
cr, uid, pool, uri2 = self.get_cr(uri)
173
node = self.uri2object(cr,uid,pool, uri2)
174
if node.type=='file':
175
dt = node.object.write_date or node.object.create_date
176
result = int(time.mktime(time.strptime(dt,'%Y-%m-%d %H:%M:%S')))
183
def get_creationdate(self,uri):
184
""" return the last modified date of the object """
185
print 'Get DAV Cre', uri
189
if uri[-1]=='/':uri=uri[:-1]
190
cr, uid, pool, uri2 = self.get_cr(uri)
191
node = self.uri2object(cr,uid,pool, uri2)
192
if node.type=='file':
193
result = node.object.write_date or node.object.create_date
195
result = time.strftime('%Y-%m-%d %H:%M:%S')
197
return time.mktime(time.strptime(result,'%Y-%m-%d %H:%M:%S'))
200
def _get_dav_getcontenttype(self,uri):
201
print 'Get DAV CT', uri
202
if uri[-1]=='/':uri=uri[:-1]
204
return 'httpd/unix-directory'
205
cr, uid, pool, uri2 = self.get_cr(uri)
206
node = self.uri2object(cr,uid,pool, uri2)
207
result = 'application/octet-stream'
208
if node.type=='collection':
209
return 'httpd/unix-directory'
212
#raise DAV_NotFound, 'Could not find %s' % path
215
""" create a new collection """
217
if uri[-1]=='/':uri=uri[:-1]
220
parent='/'.join(uri.split('/')[:-1])
221
if not parent.startswith(self.baseuri):
222
parent=self.baseuri + ''.join(parent[1:])
223
if not uri.startswith(self.baseuri):
224
uri=self.baseuri + ''.join(uri[1:])
227
cr, uid, pool, uri2 = self.get_cr(uri)
228
node = self.uri2object(cr,uid,pool, uri2[:-1])
229
object2=node and node.object2 or False
230
object=node and node.object or False
234
pool.get('document.directory').create(cr, uid, {
237
'ressource_type_id': False,
238
'ressource_id': False
241
pool.get('document.directory').create(cr, uid, {
243
'parent_id': object.id,
244
'ressource_type_id': object.ressource_type_id.id,
245
'ressource_id': object2 and object2.id or False
252
def put(self,uri,data,content_type=None):
253
""" put the object into the filesystem """
254
print 'Putting', uri, len(data), content_type
257
parent='/'.join(uri.split('/')[:-1])
258
cr, uid, pool, uri2 = self.get_cr(uri)
261
node = self.uri2object(cr,uid,pool, uri2[:])
264
print 'NODE FOUND', node
265
fobj = pool.get('ir.attachment')
267
ext = objname.find('.') >0 and objname.split('.')[1] or False
268
if node and node.type=='file':
269
print '*** FILE', node.object
271
'file_size': len(data),
272
'datas': base64.encodestring(data),
274
cid = fobj.write(cr, uid, [node.object.id], val)
277
print '*** CREATE', 'not node'
278
node = self.uri2object(cr,uid,pool, uri2[:-1])
279
object2=node and node.object2 or False
280
object=node and node.object or False
283
'datas_fname': objname,
284
'file_size': len(data),
285
'datas': base64.encodestring(data),
287
'parent_id': object and object.id or False,
290
if object2.partner_id and object2.partner_id.id:
291
partner = object2.partner_id.id
292
if object2._name == 'res.partner':
296
'res_model': object2._name,
297
'partner_id': partner,
300
cid = fobj.create(cr, uid, val)
303
# TODO: Test Permissions
313
""" delete a collection """
314
if uri[-1]=='/':uri=uri[:-1]
318
cr, uid, pool, uri2 = self.get_cr(uri)
319
node = self.uri2object(cr,uid,pool, uri2)
320
object2=node and node.object2 or False
321
object=node and node.object or False
322
if object._table_name=='document.directory':
324
raise DAV_Forbidden # forbidden
326
raise DAV_Forbidden # forbidden
327
res = pool.get('document.directory').unlink(cr, uid, [object.id])
334
if uri[-1]=='/':uri=uri[:-1]
339
cr, uid, pool, uri2 = self.get_cr(uri)
340
node = self.uri2object(cr,uid,pool, uri2)
341
object2=node and node.object2 or False
342
object=node and node.object or False
344
raise DAV_NotFound, 404
346
print ' rm',object._table_name,uri
347
if object._table_name=='ir.attachment':
348
res = pool.get('ir.attachment').unlink(cr, uid, [object.id])
350
raise DAV_Forbidden # forbidden
351
parent='/'.join(uri.split('/')[:-1])
356
### DELETE handlers (examples)
357
### (we use the predefined methods in davcmd instead of doing
361
def delone(self,uri):
362
""" delete a single resource
364
You have to return a result dict of the form
366
or None if everything's ok
369
if uri[-1]=='/':uri=uri[:-1]
371
parent='/'.join(uri.split('/')[:-1])
374
def deltree(self,uri):
375
""" delete a collection
377
You have to return a result dict of the form
379
or None if everything's ok
381
if uri[-1]=='/':uri=uri[:-1]
382
res=deltree(self,uri)
383
parent='/'.join(uri.split('/')[:-1])
388
### MOVE handlers (examples)
391
def moveone(self,src,dst,overwrite):
392
""" move one resource with Depth=0
394
an alternative implementation would be
399
r=os.system("rm -f '%s'" %dst)
401
r=os.system("mv '%s' '%s'" %(src,dst))
405
(untested!). This would not use the davcmd functions
406
and thus can only detect errors directly on the root node.
408
res=moveone(self,src,dst,overwrite)
411
def movetree(self,src,dst,overwrite):
412
""" move a collection with Depth=infinity
414
an alternative implementation would be
419
r=os.system("rm -rf '%s'" %dst)
421
r=os.system("mv '%s' '%s'" %(src,dst))
425
(untested!). This would not use the davcmd functions
426
and thus can only detect errors directly on the root node"""
428
res=movetree(self,src,dst,overwrite)
435
def copyone(self,src,dst,overwrite):
436
""" copy one resource with Depth=0
438
an alternative implementation would be
443
r=os.system("rm -f '%s'" %dst)
445
r=os.system("cp '%s' '%s'" %(src,dst))
449
(untested!). This would not use the davcmd functions
450
and thus can only detect errors directly on the root node.
452
res=copyone(self,src,dst,overwrite)
455
def copytree(self,src,dst,overwrite):
456
""" copy a collection with Depth=infinity
458
an alternative implementation would be
463
r=os.system("rm -rf '%s'" %dst)
465
r=os.system("cp -r '%s' '%s'" %(src,dst))
469
(untested!). This would not use the davcmd functions
470
and thus can only detect errors directly on the root node"""
471
res=copytree(self,src,dst,overwrite)
476
### This methods actually copy something. low-level
477
### They are called by the davcmd utility functions
478
### copytree and copyone (not the above!)
479
### Look in davcmd.py for further details.
482
def copy(self,src,dst):
483
src=urllib.unquote(src)
484
dst=urllib.unquote(dst)
485
ct = self._get_dav_getcontenttype(src)
486
data = self.get_data(src)
487
self.put(dst,data,ct)
490
def copycol(self,src,dst):
491
""" copy a collection.
493
As this is not recursive (the davserver recurses itself)
494
we will only create a new directory here. For some more
495
advanced systems we might also have to copy properties from
496
the source to the destination.
498
print " copy a collection."
499
return self.mkcol(dst)
502
def exists(self,uri):
503
""" test if a resource exists """
507
cr, uid, pool, uri2 = self.get_cr(uri)
509
node = self.uri2object(cr,uid,pool, uri2)
515
print 'Get Exists', uri, result
519
def is_collection(self,uri):
520
""" test if the given uri is a collection """
521
return self._get_dav_resourcetype(uri)==COLLECTION