Document: make node classes pluggable (part 1)

Refactor and put hooks in document/nodes so that addons can override
the classes and enhance the node behaviour, per database.

bzr revid: p_christ@hol.gr-20101012103856-j115po98jqff6j02
This commit is contained in:
P. Christeas 2010-10-12 13:38:56 +03:00
parent 2655d0e091
commit 402d407b2c
2 changed files with 52 additions and 22 deletions

View File

@ -175,6 +175,38 @@ class document_directory(osv.osv):
return nodes.get_node_context(cr, uid, context).get_uri(cr, uri)
def get_node_class(self, cr, uid, ids, dbro=None, context=None):
"""Retrieve the class of nodes for this directory
This function can be overriden by inherited classes ;)
@param dbro The browse object, if caller already has it
"""
if dbro is None:
dbro = self.browse(cr, uid, ids, context=context)
if dbro.type == 'directory':
return nodes.node_dir
elif dbro.type == 'ressource':
assert not dbro.ressource_parent_type_id, \
"resource and parent_id at #%d: %r" % (dbro.id, dbro.ressource_parent_type_id)
return nodes.node_res_dir
else:
raise ValueError("dir node for %s type", dbro.type)
def _prepare_context(self, cr, uid, nctx, context):
""" Fill nctx with properties for this database
@param nctx instance of nodes.node_context, to be filled
@param context ORM context (dict) for us
Note that this function is called *without* a list of ids,
it should behave the same for the whole database (based on the
ORM instance of document.directory).
Some databases may override this and attach properties to the
node_context. See WebDAV, CalDAV.
"""
return
def get_dir_permissions(self, cr, uid, ids ):
"""Check what permission user 'uid' has on directory 'id'
"""

View File

@ -64,13 +64,16 @@ class node_context(object):
""" This is the root node, representing access to some particular
context """
cached_roots = {}
node_file_class = None
def __init__(self, cr, uid, context=None):
self.dbname = cr.dbname
self.uid = uid
self.context = context
self._dirobj = pooler.get_pool(cr.dbname).get('document.directory')
self.node_file_class = node_file
assert self._dirobj
self._dirobj._prepare_context(cr, uid, self, context=context)
self.rootdir = False #self._dirobj._get_root_directory(cr,uid,context)
def __eq__(self, other):
@ -104,14 +107,10 @@ class node_context(object):
"""Create (or locate) a node for a directory
@param dbro a browse object of document.directory
"""
fullpath = self._dirobj.get_full_path(cr, self.uid, dbro.id, self.context)
if dbro.type == 'directory':
return node_dir(fullpath, None ,self, dbro)
elif dbro.type == 'ressource':
assert dbro.ressource_parent_type_id == False
return node_res_dir(fullpath, None, self, dbro)
else:
raise ValueError("dir node for %s type", dbro.type)
fullpath = dbro.get_full_path(context=self.context)
klass = dbro.get_node_class(dbro, context=self.context)
return klass(fullpath, None ,self, dbro)
def get_file_node(self, cr, fbro):
""" Create or locate a node for a static file
@ -121,7 +120,7 @@ class node_context(object):
if fbro.parent_id:
parent = self.get_dir_node(cr, fbro.parent_id)
return node_file(fbro.name, parent, self, fbro)
return self.node_file_class(fbro.name, parent, self, fbro)
class node_descriptor(object):
@ -438,22 +437,20 @@ class node_database(node_class):
if not domain:
domain = []
where2 = where + domain + [('type', '=', 'directory')]
where2 = where + domain + ['|', ('type', '=', 'directory'), \
'&', ('type', '=', 'ressource'), ('ressource_parent_type_id','=',False)]
ids = dirobj.search(cr, uid, where2, context=ctx)
res = []
for dirr in dirobj.browse(cr, uid, ids, context=ctx):
res.append(node_dir(dirr.name, self, self.context,dirr))
where2 = where + domain + [('type', '=', 'ressource'), ('ressource_parent_type_id','=',False)]
ids = dirobj.search(cr, uid, where2, context=ctx)
for dirr in dirobj.browse(cr, uid, ids, context=ctx):
res.append(node_res_dir(dirr.name, self, self.context, dirr))
klass = dirr.get_node_class(dirr, context=ctx)
res.append(klass(dirr.name, self, self.context,dirr))
fil_obj = dirobj.pool.get('ir.attachment')
ids = fil_obj.search(cr, uid, where, context=ctx)
if ids:
for fil in fil_obj.browse(cr, uid, ids, context=ctx):
res.append(node_file(fil.name, self, self.context, fil))
klass = self.context.node_file_class
res.append(klass(fil.name, self, self.context, fil))
return res
def _file_get(self,cr, nodename=False):
@ -910,6 +907,7 @@ class node_res_obj(node_class):
where = [('directory_id','=',self.dir_id) ]
ids = cntobj.search(cr,uid,where,context=ctx)
for content in cntobj.browse(cr, uid, ids, context=ctx):
# TODO: remove relic of GroupDAV
if content.extension == '.ics': # FIXME: call the content class!
return ('vevent-collection','http://groupdav.org/')
return None
@ -944,6 +942,7 @@ class node_res_obj(node_class):
res_name = getattr(bo, namefield)
if not res_name:
continue
# TODO Revise
res.append(node_res_obj(res_name, self.dir_id, self, self.context, self.res_model, res_bo = bo))
@ -956,9 +955,6 @@ class node_res_obj(node_class):
# child resources can be controlled by properly set dctx
res.append(node_res_dir(dirr.name,self,self.context, dirr, {'active_id': self.res_id}))
fil_obj = dirobj.pool.get('ir.attachment')
if self.res_find_all:
where2 = where
@ -967,7 +963,8 @@ class node_res_obj(node_class):
ids = fil_obj.search(cr, uid, where3, context=ctx)
if ids:
for fil in fil_obj.browse(cr, uid, ids, context=ctx):
res.append(node_file(fil.name, self, self.context, fil))
klass = self.context.node_file_class
res.append(klass(fil.name, self, self.context, fil))
# Get Child Ressource Directories
@ -1038,7 +1035,8 @@ class node_res_obj(node_class):
fil_id = fil_obj.create(cr, uid, val, context=ctx)
fil = fil_obj.browse(cr, uid, fil_id, context=ctx)
fnode = node_file(path, self, self.context, fil)
klass = self.context.node_file_class
fnode = klass(path, self, self.context, fil)
if data is not None:
fnode.set_data(cr, data, fil)
return fnode