def _get_dav_eprop_hlpr(self, cr, ns, prop, par_class, prop_model, prop_ref_field, res_id): """ Helper for get dav eprop, usable in subclasses @param namespace the one to search for @param name Name to search for @param par_class The parent class @param prop_model The name of the orm model holding the properties @param prop_ref_field The name of the field at prop_model pointing to us @param res_id the id of self in the corresponing orm table, that should match prop_model.prop_ref_field """ ret = par_class.get_dav_eprop(self, cr, ns, prop) if ret is not None: return ret if prop_model: propobj = self.context._dirobj.pool.get(prop_model) uid = self.context.uid ctx = self.context.context.copy() ctx.update(self.dctx) ctx.update({'uid': uid, 'dbname': self.context.dbname}) ctx['node_classname'] = "%s.%s" % (self.__class__.__module__, self.__class__.__name__) dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx) sdomain = [(prop_ref_field, '=', False), ('namespace', '=', ns), ('name', '=', prop)] if res_id: sdomain = ['|', (prop_ref_field, '=', res_id)] + sdomain prop_ids = propobj.search(cr, uid, sdomain, context=ctx) if prop_ids: pbro = propobj.browse(cr, uid, prop_ids[0], context=ctx) val = pbro.value if pbro.do_subst: if val.startswith("('") and val.endswith(")"): glbls = { 'urlquote': urllib.quote, } val = eval(val, glbls, ctx) else: val = val % ctx return val return None
def _get_dav_eprop_hlpr(self, cr, ns, prop, par_class, prop_model, prop_ref_field, res_id): """ Helper for get dav eprop, usable in subclasses @param namespace the one to search for @param name Name to search for @param par_class The parent class @param prop_model The name of the orm model holding the properties @param prop_ref_field The name of the field at prop_model pointing to us @param res_id the id of self in the corresponing orm table, that should match prop_model.prop_ref_field """ ret = par_class.get_dav_eprop(self, cr, ns, prop) if ret is not None: return ret if prop_model: propobj = self.context._dirobj.pool.get(prop_model) uid = self.context.uid ctx = self.context.context.copy() ctx.update(self.dctx) ctx.update({'uid': uid, 'dbname': self.context.dbname }) ctx['node_classname'] = "%s.%s" % (self.__class__.__module__, self.__class__.__name__) dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx) sdomain = [(prop_ref_field, '=', False),('namespace', '=', ns), ('name','=', prop)] if res_id: sdomain = ['|', (prop_ref_field, '=', res_id)] + sdomain prop_ids = propobj.search(cr, uid, sdomain, context=ctx) if prop_ids: pbro = propobj.browse(cr, uid, prop_ids[0], context=ctx) val = pbro.value if pbro.do_subst: if val.startswith("('") and val.endswith(")"): glbls = { 'urlquote': urllib.quote, } val = eval(val, glbls, ctx) else: val = val % ctx return val return None
def _dav_lock_hlpr(self, cr, lock_data, par_class, prop_model, prop_ref_field, res_id): """ Helper, which uses the dav properties table for placing locks @param lock_data a dictionary of input to this function. @return list of tuples, DAV:activelock _contents_ structure. See webdav.py:class Prop2Xml() for semantics Note: although the DAV response shall be an <activelock/>, this function will only return the elements inside the activelock, because the calling function needs to append the <lockroot/> in it. See webdav.py:mk_lock_response() In order to reuse code, this function can be called with lock_data['unlock_mode']=True, in order to unlock. @return bool in unlock mode, (davstruct, prop_id, token) in lock/refresh, or (False, prop_id, token) if already locked, or (False, False, False) if lock not found to refresh """ assert prop_model assert res_id assert isinstance(lock_data, dict), '%r' % lock_data propobj = self.context._dirobj.pool.get(prop_model) uid = self.context.uid ctx = self.context.context.copy() ctx.update(self.dctx) ctx.update({'uid': uid, 'dbname': self.context.dbname }) ctx['node_classname'] = "%s.%s" % (self.__class__.__module__, self.__class__.__name__) dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx) sdomain = [(prop_ref_field, '=', res_id), ('namespace', '=', 'DAV:'), ('name','=', 'lockdiscovery')] props_to_delete = [] lock_found = False lock_val = None tmout2 = int(lock_data.get('timeout', 3*3600)) prop_ids = propobj.search(cr, uid, sdomain, context=ctx) if prop_ids: for pbro in propobj.browse(cr, uid, prop_ids, context=ctx): val = pbro.value if pbro.do_subst: if val.startswith("('") and val.endswith(")"): glbls = { 'urlquote': urllib.quote, } val = eval(val, glbls, ctx) else: # all locks should be at "subst" format continue if not (val and isinstance(val, tuple) and val[0:2] == ( 'activelock','DAV:')): # print "Value is not activelock:", val continue old_token = False old_owner = False try: # discover the timeout. If anything goes wrong, delete # the lock (cleanup) tmout = False for parm in val[2]: if parm[1] != 'DAV:': continue if parm[0] == 'timeout': if isinstance(parm[2], basestring) \ and parm[2].startswith('Second-'): tmout = int(parm[2][7:]) elif parm[0] == 'locktoken': if isinstance(parm[2], basestring): old_token = parm[2] elif isinstance(parm[2], tuple) and \ parm[2][0:2] == ('href','DAV:'): old_token = parm[2][2] else: # print "Mangled token in DAV property: %r" % parm[2] props_to_delete.append(pbro.id) continue elif parm[0] == 'owner': old_owner = parm[2] # not used yet if tmout: mdate = pbro.write_date or pbro.create_date mdate = time.mktime(time.strptime(mdate,'%Y-%m-%d %H:%M:%S')) if mdate + tmout < time.time(): props_to_delete.append(pbro.id) continue else: props_to_delete.append(pbro.id) continue except ValueError: props_to_delete.append(pbro.id) continue # A valid lock is found here if lock_data.get('refresh', False): if old_token != lock_data.get('token'): continue # refresh mode. Just touch anything and the ORM will update # the write uid+date, won't it? # Note: we don't update the owner, because incoming refresh # wouldn't have a body, anyway. propobj.write(cr, uid, [pbro.id,], { 'name': 'lockdiscovery'}) elif lock_data.get('unlock_mode', False): if old_token != lock_data.get('token'): continue props_to_delete.append(pbro.id) lock_found = pbro.id lock_val = val if tmout2 > 3*3600: # 3 hours maximum tmout2 = 3*3600 elif tmout2 < 300: # 5 minutes minimum, but an unlock request can always # break it at any time. Ensures no negative values, either. tmout2 = 300 if props_to_delete: # explicitly delete, as admin, any of the ids we have identified. propobj.unlink(cr, SUPERUSER_ID, props_to_delete) if lock_data.get('unlock_mode', False): return lock_found and True elif (not lock_found) and not (lock_data.get('refresh', False)): # Create a new lock, attach and return it. new_token = uuid.uuid4().urn lock_val = ('activelock', 'DAV:', [ ('locktype', 'DAV:', (lock_data.get('locktype',False) or 'write','DAV:')), ('lockscope', 'DAV:', (lock_data.get('lockscope',False) or 'exclusive','DAV:')), # ? ('depth', 'DAV:', lock_data.get('depth','0') ), ('timeout','DAV:', 'Second-%d' % tmout2), ('locktoken', 'DAV:', ('href', 'DAV:', new_token)), # ('lockroot', 'DAV: ..., we don't store that, appended by caller ]) new_owner = lock_data.get('lockowner',False) or ctx.get('username', False) if new_owner: lock_val[2].append( ('owner', 'DAV:', new_owner) ) prop_id = propobj.create(cr, uid, { prop_ref_field: res_id, 'namespace': 'DAV:', 'name': 'lockdiscovery', 'do_subst': True, 'value': repr(lock_val) }) return (lock_val[2], prop_id, new_token ) elif not lock_found: # and refresh return (False, False, False) elif lock_found and not lock_data.get('refresh', False): # already locked return (False, lock_found, old_token) else: return (lock_val[2], lock_found, old_token )
def _dav_lock_hlpr(self, cr, lock_data, par_class, prop_model, prop_ref_field, res_id): """ Helper, which uses the dav properties table for placing locks @param lock_data a dictionary of input to this function. @return list of tuples, DAV:activelock _contents_ structure. See webdav.py:class Prop2Xml() for semantics Note: although the DAV response shall be an <activelock/>, this function will only return the elements inside the activelock, because the calling function needs to append the <lockroot/> in it. See webdav.py:mk_lock_response() In order to reuse code, this function can be called with lock_data['unlock_mode']=True, in order to unlock. @return bool in unlock mode, (davstruct, prop_id, token) in lock/refresh, or (False, prop_id, token) if already locked, or (False, False, False) if lock not found to refresh """ assert prop_model assert res_id assert isinstance(lock_data, dict), '%r' % lock_data propobj = self.context._dirobj.pool.get(prop_model) uid = self.context.uid ctx = self.context.context.copy() ctx.update(self.dctx) ctx.update({'uid': uid, 'dbname': self.context.dbname }) ctx['node_classname'] = "%s.%s" % (self.__class__.__module__, self.__class__.__name__) dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx) sdomain = [(prop_ref_field, '=', res_id), ('namespace', '=', 'DAV:'), ('name','=', 'lockdiscovery')] props_to_delete = [] lock_found = False lock_val = None tmout2 = int(lock_data.get('timeout', 3*3600)) prop_ids = propobj.search(cr, uid, sdomain, context=ctx) if prop_ids: for pbro in propobj.browse(cr, uid, prop_ids, context=ctx): val = pbro.value if pbro.do_subst: if val.startswith("('") and val.endswith(")"): glbls = { 'urlquote': urllib.quote, } val = eval(val, glbls, ctx) else: # all locks should be at "subst" format continue if not (val and isinstance(val, tuple) and val[0:2] == ( 'activelock','DAV:')): # print "Value is not activelock:", val continue old_token = False old_owner = False try: # discover the timeout. If anything goes wrong, delete # the lock (cleanup) tmout = False for parm in val[2]: if parm[1] != 'DAV:': continue if parm[0] == 'timeout': if isinstance(parm[2], basestring) \ and parm[2].startswith('Second-'): tmout = int(parm[2][7:]) elif parm[0] == 'locktoken': if isinstance(parm[2], basestring): old_token = parm[2] elif isinstance(parm[2], tuple) and \ parm[2][0:2] == ('href','DAV:'): old_token = parm[2][2] else: # print "Mangled token in DAV property: %r" % parm[2] props_to_delete.append(pbro.id) continue elif parm[0] == 'owner': old_owner = parm[2] # not used yet if tmout: mdate = pbro.write_date or pbro.create_date mdate = time.mktime(time.strptime(mdate,'%Y-%m-%d %H:%M:%S')) if mdate + tmout < time.time(): props_to_delete.append(pbro.id) continue else: props_to_delete.append(pbro.id) continue except ValueError: props_to_delete.append(pbro.id) continue # A valid lock is found here if lock_data.get('refresh', False): if old_token != lock_data.get('token'): continue # refresh mode. Just touch anything and the ORM will update # the write uid+date, won't it? # Note: we don't update the owner, because incoming refresh # wouldn't have a body, anyway. propobj.write(cr, uid, [pbro.id,], { 'name': 'lockdiscovery'}) elif lock_data.get('unlock_mode', False): if old_token != lock_data.get('token'): continue props_to_delete.append(pbro.id) lock_found = pbro.id lock_val = val if tmout2 > 3*3600: # 3 hours maximum tmout2 = 3*3600 elif tmout2 < 300: # 5 minutes minimum, but an unlock request can always # break it at any time. Ensures no negative values, either. tmout2 = 300 if props_to_delete: # explicitly delete, as admin, any of the ids we have identified. propobj.unlink(cr, 1, props_to_delete) if lock_data.get('unlock_mode', False): return lock_found and True elif (not lock_found) and not (lock_data.get('refresh', False)): # Create a new lock, attach and return it. new_token = uuid.uuid4().urn lock_val = ('activelock', 'DAV:', [ ('locktype', 'DAV:', (lock_data.get('locktype',False) or 'write','DAV:')), ('lockscope', 'DAV:', (lock_data.get('lockscope',False) or 'exclusive','DAV:')), # ? ('depth', 'DAV:', lock_data.get('depth','0') ), ('timeout','DAV:', 'Second-%d' % tmout2), ('locktoken', 'DAV:', ('href', 'DAV:', new_token)), # ('lockroot', 'DAV: ..., we don't store that, appended by caller ]) new_owner = lock_data.get('lockowner',False) or ctx.get('username', False) if new_owner: lock_val[2].append( ('owner', 'DAV:', new_owner) ) prop_id = propobj.create(cr, uid, { prop_ref_field: res_id, 'namespace': 'DAV:', 'name': 'lockdiscovery', 'do_subst': True, 'value': repr(lock_val) }) return (lock_val[2], prop_id, new_token ) elif not lock_found: # and refresh return (False, False, False) elif lock_found and not lock_data.get('refresh', False): # already locked return (False, lock_found, old_token) else: return (lock_val[2], lock_found, old_token )