doc webdav: install a dummy DAV handler at / , for Nautilus
[odoo/odoo.git] / addons / document_webdav / nodes.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2010 Tiny SPRL (<http://tiny.be>).
6 #
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.
11 #
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.
16 #
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/>.
19 #
20 ##############################################################################
21
22
23 from document import nodes
24 from tools.safe_eval import safe_eval as eval
25 try:
26     from tools.dict_tools import dict_filter
27 except ImportError:
28     from document.dict_tools import dict_filter
29
30 import urllib
31
32     
33 class node_acl_mixin(object):
34     def _get_dav_owner(self, cr):
35         return self.uuser
36
37     def _get_dav_group(self, cr):
38         return self.ugroup
39         
40     def _get_dav_supported_privilege_set(self, cr):
41         return '' # TODO
42     
43     def _get_dav_current_user_privilege_set(self, cr):
44         return '' # TODO
45
46     def _get_dav_props_hlpr(self, cr, par_class, prop_model, 
47                             prop_ref_field, res_id):
48         """ Helper for dav properties, usable in subclasses
49         
50         @param par_class The parent class
51         @param prop_model The name of the orm model holding the properties
52         @param prop_ref_field The name of the field at prop_model pointing to us
53         @param res_id the id of self in the corresponing orm table, that should
54                         match prop_model.prop_ref_field
55         """
56         ret = par_class.get_dav_props(self, cr)
57         if prop_model:
58             propobj = self.context._dirobj.pool.get(prop_model)
59             uid = self.context.uid
60             ctx = self.context.context.copy()
61             ctx.update(self.dctx)
62             # Not really needed because we don't do eval here:
63             # ctx.update({'uid': uid, 'dbname': self.context.dbname })
64             # dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx)
65             sdomain = [(prop_ref_field, '=', False),]
66             if res_id:
67                 sdomain = ['|', (prop_ref_field, '=', res_id)] + sdomain
68             prop_ids = propobj.search(cr, uid, sdomain, context=ctx)
69             if prop_ids:
70                 ret = ret.copy()
71                 for pbro in propobj.browse(cr, uid, prop_ids, context=ctx):
72                     ret[pbro.namespace] = ret.get(pbro.namespace, ()) + \
73                         (pbro.name,)
74                     # Note that we cannot have properties to conditionally appear
75                     # on the context, yet.
76                 
77         return ret
78
79     def _get_dav_eprop_hlpr(self, cr, ns, prop,
80                             par_class, prop_model, 
81                             prop_ref_field, res_id):
82         """ Helper for get dav eprop, usable in subclasses
83         
84         @param namespace the one to search for
85         @param name Name to search for
86         @param par_class The parent class
87         @param prop_model The name of the orm model holding the properties
88         @param prop_ref_field The name of the field at prop_model pointing to us
89         @param res_id the id of self in the corresponing orm table, that should
90                         match prop_model.prop_ref_field
91         """
92         ret = par_class.get_dav_eprop(self, cr, ns, prop)
93         if ret is not None:
94             return ret
95         if prop_model:
96             propobj = self.context._dirobj.pool.get(prop_model)
97             uid = self.context.uid
98             ctx = self.context.context.copy()
99             ctx.update(self.dctx)
100             ctx.update({'uid': uid, 'dbname': self.context.dbname })
101             ctx['node_classname'] = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
102             dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx)
103             sdomain = [(prop_ref_field, '=', False),('namespace', '=', ns), ('name','=', prop)]
104             if res_id:
105                 sdomain = ['|', (prop_ref_field, '=', res_id)] + sdomain
106             prop_ids = propobj.search(cr, uid, sdomain, context=ctx)
107             if prop_ids:
108                 pbro = propobj.browse(cr, uid, prop_ids[0], context=ctx)
109                 val = pbro.value
110                 if pbro.do_subst:
111                     if val.startswith("('") and val.endswith(")"):
112                         glbls = { 'urlquote': urllib.quote, }
113                         val = eval(val, glbls, ctx)
114                     else:
115                         val = val % ctx
116                 return val
117         return None
118
119 class node_dir(node_acl_mixin, nodes.node_dir):
120     """ override node_dir and add DAV functionality
121     """
122     DAV_PROPS = { "DAV:": ('owner', 'group', 
123                             'supported-privilege-set', 
124                             'current-user-privilege-set'), 
125                 }
126     DAV_M_NS = { "DAV:" : '_get_dav',}
127     http_options = { 'DAV': ['access-control',] }
128
129     def get_dav_resourcetype(self, cr):
130         return ('collection', 'DAV:')
131
132     def get_dav_props(self, cr):
133         return self._get_dav_props_hlpr(cr, nodes.node_dir, 
134                 'document.webdav.dir.property', 'dir_id', self.dir_id)
135
136     def get_dav_eprop(self, cr, ns, prop):
137         return self._get_dav_eprop_hlpr(cr, ns, prop, nodes.node_dir,
138                 'document.webdav.dir.property', 'dir_id', self.dir_id)
139
140
141 class node_file(node_acl_mixin, nodes.node_file):
142     DAV_PROPS = { "DAV:": ('owner', 'group', 
143                             'supported-privilege-set', 
144                             'current-user-privilege-set'), 
145                 }
146     DAV_M_NS = { "DAV:" : '_get_dav',}
147     http_options = { 'DAV': ['access-control', ] }
148     pass
149
150     def get_dav_resourcetype(self, cr):
151         return ''
152
153     def get_dav_props(self, cr):
154         return self._get_dav_props_hlpr(cr, nodes.node_file, 
155                 None, 'file_id', self.file_id)
156                 #'document.webdav.dir.property', 'dir_id', self.dir_id)
157
158     #def get_dav_eprop(self, cr, ns, prop):
159
160 class node_database(nodes.node_database):
161     def get_dav_resourcetype(self, cr):
162         return ('collection', 'DAV:')
163
164     def get_dav_props(self, cr):
165         return self._get_dav_props_hlpr(cr, nodes.node_database,
166                 'document.webdav.dir.property', 'dir_id', False)
167
168     def get_dav_eprop(self, cr, ns, prop):
169         return self._get_dav_eprop_hlpr(cr, nodes.node_database, ns, prop,
170                 'document.webdav.dir.property', 'dir_id', False)
171
172 class node_res_obj(node_acl_mixin, nodes.node_res_obj):
173     DAV_PROPS = { "DAV:": ('owner', 'group', 
174                             'supported-privilege-set', 
175                             'current-user-privilege-set'), 
176                 }
177     DAV_M_NS = { "DAV:" : '_get_dav',}
178     http_options = { 'DAV': ['access-control',] }
179
180     def get_dav_resourcetype(self, cr):
181         return ('collection', 'DAV:')
182
183     def get_dav_props(self, cr):
184         return self._get_dav_props_hlpr(cr, nodes.node_res_obj, 
185                 'document.webdav.dir.property', 'dir_id', self.dir_id)
186
187     def get_dav_eprop(self, cr, ns, prop):
188         return self._get_dav_eprop_hlpr(cr, ns, prop, nodes.node_res_obj,
189                 'document.webdav.dir.property', 'dir_id', self.dir_id)
190
191
192 class node_res_dir(node_acl_mixin, nodes.node_res_dir):
193     DAV_PROPS = { "DAV:": ('owner', 'group', 
194                             'supported-privilege-set', 
195                             'current-user-privilege-set'), 
196                 }
197     DAV_M_NS = { "DAV:" : '_get_dav',}
198     http_options = { 'DAV': ['access-control',] }
199     res_obj_class = node_res_obj
200
201     def get_dav_resourcetype(self, cr):
202         return ('collection', 'DAV:')
203
204     def get_dav_props(self, cr):
205         return self._get_dav_props_hlpr(cr, nodes.node_res_dir, 
206                 'document.webdav.dir.property', 'dir_id', self.dir_id)
207
208     def get_dav_eprop(self, cr, ns, prop):
209         return self._get_dav_eprop_hlpr(cr, ns, prop, nodes.node_res_dir,
210                 'document.webdav.dir.property', 'dir_id', self.dir_id)
211
212 # Some copies, so that this module can replace 'from document import nodes'
213 get_node_context = nodes.get_node_context
214 node_context = nodes.node_context
215 node_class = nodes.node_class
216 node_descriptor = nodes.node_descriptor
217
218
219 #eof