def _get_mailto(context, peopledir): mailinglist = context.get("mailinglist") if mailinglist is not None: pd_path = resource_path_tuple(peopledir) report_path = resource_path_tuple(context) mail_name = "+".join(report_path[len(pd_path) :]) system_email_domain = get_setting(context, "system_email_domain") system_list_subdomain = get_setting(context, "system_list_subdomain", system_email_domain) return "mailto:%s@%s" % (mailinglist.short_address, system_list_subdomain)
def object_will_be_added(event): """ Objects added to folders must always have an __objectid__. This must be an :class:`substanced.event.ObjectWillBeAdded` event subscriber so that a resulting object will have an __objectid__ within the (more convenient) :class:`substanced.event.ObjectAdded` fired later.""" obj = event.object parent = event.parent objectmap = find_service(parent, 'objectmap') if objectmap is None: return if getattr(obj, '__parent__', None): raise ValueError( 'obj %s added to folder %s already has a __parent__ attribute, ' 'please remove it completely from its existing parent (%s) before ' 'trying to readd it to this one' % (obj, parent, obj.__parent__) ) basepath = resource_path_tuple(event.parent) name = event.name for node in postorder(obj): node_path = node_path_tuple(node) path_tuple = basepath + (name,) + node_path[1:] # the below gives node an objectid; if the will-be-added event is # the result of a duplication, replace the oid of the node with a new # one objectmap.add(node, path_tuple, replace_oid=event.duplicating)
def breadcrumbs(self): curr = self.request.root crumbs = [curr] for name in resource_path_tuple(self.context)[1:]: obj = curr[name] crumbs.append(obj) curr = obj return crumbs
def _get_path_tuple(self, obj_objectid_or_path_tuple): path_tuple = None if hasattr(obj_objectid_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_objectid_or_path_tuple) elif isinstance(obj_objectid_or_path_tuple, INT_TYPES): path_tuple = self.objectid_to_path.get(obj_objectid_or_path_tuple) elif isinstance(obj_objectid_or_path_tuple, tuple): path_tuple = obj_objectid_or_path_tuple return path_tuple
def _get_path_tuple(self, obj_or_path_tuple): if hasattr(obj_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_or_path_tuple) elif isinstance(obj_or_path_tuple, tuple): path_tuple = obj_or_path_tuple else: raise ValueError('must provide a traversable object or a ' 'path tuple, got %s' % (obj_or_path_tuple, )) return path_tuple
def add(self, name, other, send_events=True, reserved_names=(), duplicating=False, moving=False, registry=None): """ Same as ``__setitem__``. If ``send_events`` is False, suppress the sending of folder events. Don't allow names in the ``reserved_names`` sequence to be added. If ``duplicating`` is True, oids will be replaced in objectmap. This method returns the name used to place the subobject in the folder (a derivation of ``name``, usually the result of ``self.check_name(name)``). """ if registry is None: registry = get_current_registry() name = self.check_name(name, reserved_names) if getattr(other, "__parent__", None): raise ValueError( "obj %s added to folder %s already has a __parent__ attribute, " "please remove it completely from its existing parent (%s) " "before trying to readd it to this one" % (other, self, self.__parent__) ) objectmap = find_objectmap(self) if objectmap is not None: basepath = resource_path_tuple(self) for node in postorder(other): node_path = node_path_tuple(node) path_tuple = basepath + (name,) + node_path[1:] # the below gives node an objectid; if the will-be-added event # is the result of a duplication, replace the oid of the node # with a new one objectmap.add(node, path_tuple, replace_oid=duplicating) if send_events: event = ObjectWillBeAdded(other, self, name, duplicating=duplicating, moving=moving) self._notify(event, registry) other.__parent__ = self other.__name__ = name self.data[name] = other self._num_objects.change(1) if self._order is not None: self._order += (name,) if send_events: event = ObjectAdded(other, self, name, duplicating=duplicating, moving=moving) self._notify(event, registry) return name
def _get_path_tuple(self, obj_or_path_tuple): if hasattr(obj_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_or_path_tuple) elif isinstance(obj_or_path_tuple, tuple): path_tuple = obj_or_path_tuple else: raise ValueError( 'must provide a traversable object or a ' 'path tuple, got %s' % (obj_or_path_tuple,)) return path_tuple
def objectid_for(self, obj_or_path_tuple): """ Returns an objectid or ``None``, given an object or a path tuple""" if isinstance(obj_or_path_tuple, tuple): path_tuple = obj_or_path_tuple elif hasattr(obj_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_or_path_tuple) else: raise ValueError( 'objectid_for accepts a traversable object or a path tuple, ' 'got %s' % (obj_or_path_tuple,)) return self.path_to_objectid.get(path_tuple)
def objectid_for(self, obj_or_path_tuple): """ Returns an objectid or ``None``, given an object or a path tuple""" if isinstance(obj_or_path_tuple, tuple): path_tuple = obj_or_path_tuple elif hasattr(obj_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_or_path_tuple) else: raise ValueError( 'objectid_for accepts a traversable object or a path tuple, ' 'got %s' % (obj_or_path_tuple, )) return self.path_to_objectid.get(path_tuple)
def _parse_path(self, obj_or_path): path_tuple = obj_or_path if hasattr(obj_or_path, '__parent__'): path_tuple = resource_path_tuple(obj_or_path) elif isinstance(obj_or_path, basestring): tmp = filter(None, url_unquote_text(obj_or_path).split(u'/')) path_tuple = (u'',) + tuple(tmp) elif not isinstance(obj_or_path, tuple): raise ValueError( 'Must be object, path string, or tuple, not %s' % ( obj_or_path,)) return path_tuple
def _parse_path(self, obj_or_path): depth = self.depth include_origin = self.include_origin path_tuple = obj_or_path if hasattr(obj_or_path, '__parent__'): path_tuple = resource_path_tuple(obj_or_path) elif isinstance(obj_or_path, basestring): path_tuple, depth, include_origin = self._parse_path_str( obj_or_path) elif not isinstance(obj_or_path, tuple): raise ValueError('Must be object, path string, or tuple, not %s' % (obj_or_path, )) return path_tuple, depth, include_origin
def create_dummy_resources(parent=None, count=1): """Create dummy resources and add it to the parent objectmap.""" from pyramid.traversal import resource_path_tuple resources = () for x in range(count): resource = testing.DummyResource(__parent__=parent) oid = parent.__objectmap__.new_objectid() resource.__oid__ = oid resource.__name__ = str(oid) path = resource_path_tuple(resource) parent[resource.__name__] = resource parent.__objectmap__.add(resource, path) resources = resources + (resource,) return resources[0] if count == 1 else resources
def _parse_path(self, obj_or_path): depth = self.depth include_origin = self.include_origin path_tuple = obj_or_path if hasattr(obj_or_path, '__parent__'): path_tuple = resource_path_tuple(obj_or_path) elif isinstance(obj_or_path, STRING_TYPES): path_tuple, depth, include_origin = self._parse_path_str( obj_or_path) elif not isinstance(obj_or_path, tuple): raise ValueError( 'Must be object, path string, or tuple, not %s' % ( obj_or_path,)) return path_tuple, depth, include_origin
def create_dummy_resources(parent=None, count=1): """Create dummy resources and add it to the parent objectmap.""" from pyramid.traversal import resource_path_tuple resources = () for x in range(count): resource = testing.DummyResource(__parent__=parent) oid = parent.__objectmap__.new_objectid() resource.__oid__ = oid resource.__name__ = str(oid) path = resource_path_tuple(resource) parent[resource.__name__] = resource parent.__objectmap__.add(resource, path) resources = resources + (resource, ) return resources[0] if count == 1 else resources
def test_object_has_a_parent(self): from ..interfaces import IFolder from pyramid.traversal import resource_path_tuple objectmap = DummyObjectMap() site = _makeSite(objectmap=objectmap) bogusroot = testing.DummyModel(__provides__=IFolder) bogusparent2 = testing.DummyModel(__provides__=IFolder) one = testing.DummyModel(__provides__=IFolder) two = testing.DummyModel(__provides__=IFolder) bogusroot['bogusparent2'] = bogusparent2 bogusparent2['one'] = one one['two'] = two self.assertEqual(resource_path_tuple(one), ('', 'bogusparent2', 'one')) event = DummyEvent(one, site) self.assertRaises(ValueError, self._callFUT, event)
def get_breadcrumbs(request, context=None): breadcrumbs = [] req = request if not context: context = request.context pathes = resource_path_tuple(context) resources = [] t = request.root for i, item in enumerate(pathes): t = traverse(t, item)['context'] resources.append((i, t, item)) end = len(resources) for i, resource, item in resources: infos = get_nav_infos(resource, req, item) if i == 0: infos['class'] = 'start' if 0 < i < end-1: infos['class'] = 'middle' if i == end-1: infos['class'] = 'end' breadcrumbs.append(infos) return breadcrumbs
def object_will_be_added(event): """ Objects added to folders must always have an __objectid__. This must be an :class:`substanced.event.ObjectWillBeAdded` event subscriber so that a resulting object will have an __objectid__ within the (more convenient) :class:`substanced.event.ObjectAdded` fired later.""" obj = event.object parent = event.parent objectmap = find_objectmap(parent) if objectmap is None: return if getattr(obj, '__parent__', None): raise ValueError( 'obj %s added to folder %s already has a __parent__ attribute, ' 'please remove it completely from its existing parent (%s) before ' 'trying to readd it to this one' % (obj, parent, obj.__parent__)) basepath = resource_path_tuple(event.parent) name = event.name for node in postorder(obj): node_path = node_path_tuple(node) path_tuple = basepath + (name, ) + node_path[1:] # the below gives node an objectid; if the will-be-added event is # the result of a duplication, replace the oid of the node with a new # one objectmap.add(node, path_tuple, replace_oid=event.duplicating)
def _callFUT(self, resource, *elements): from pyramid.traversal import resource_path_tuple return resource_path_tuple(resource, *elements)
def __call__(self, obj, *arg, **kw): traverse = resource_path_tuple(obj) kw['traverse'] = traverse return self.request.route_path(MANAGE_ROUTE_NAME, *arg, **kw)
def add(self, name, other, send_events=True, reserved_names=(), duplicating=None, moving=None, loading=False, registry=None): """ Same as ``__setitem__``. If ``send_events`` is False, suppress the sending of folder events. Don't allow names in the ``reserved_names`` sequence to be added. If ``duplicating`` not ``None``, it must be the object which is being duplicated; a result of a non-``None`` duplicating means that oids will be replaced in objectmap. If ``moving`` is not ``None``, it must be the folder from which the object is moving; this will be the ``moving`` attribute of events sent by this function too. If ``loading`` is ``True``, the ``loading`` attribute of events sent as a result of calling this method will be ``True`` too. This method returns the name used to place the subobject in the folder (a derivation of ``name``, usually the result of ``self.check_name(name)``). """ if registry is None: registry = get_current_registry() name = self.check_name(name, reserved_names) if getattr(other, '__parent__', None): raise ValueError( 'obj %s added to folder %s already has a __parent__ attribute, ' 'please remove it completely from its existing parent (%s) ' 'before trying to readd it to this one' % ( other, self, self.__parent__) ) with statsd_timer('folder.add'): objectmap = find_objectmap(self) if objectmap is not None: basepath = resource_path_tuple(self) for node in postorder(other): node_path = node_path_tuple(node) path_tuple = basepath + (name,) + node_path[1:] # the below gives node an objectid; if the will-be-added # event is the result of a duplication, replace the oid of # the node with a new one objectmap.add( node, path_tuple, duplicating=duplicating is not None, moving=moving is not None, ) if send_events: event = ObjectWillBeAdded( other, self, name, duplicating=duplicating, moving=moving, loading=loading, ) self._notify(event, registry) other.__parent__ = self other.__name__ = name self.data[name] = other self._num_objects.change(1) if self._order is not None: oid = get_oid(other) self._order += (name,) self._order_oids += (oid,) if send_events: event = ObjectAdded( other, self, name, duplicating=duplicating, moving=moving, loading=loading, ) self._notify(event, registry) return name
def add(self, name, other, send_events=True, reserved_names=(), duplicating=None, moving=None, loading=False, registry=None): """ Same as ``__setitem__``. If ``send_events`` is False, suppress the sending of folder events. Don't allow names in the ``reserved_names`` sequence to be added. If ``duplicating`` not ``None``, it must be the object which is being duplicated; a result of a non-``None`` duplicating means that oids will be replaced in objectmap. If ``moving`` is not ``None``, it must be the folder from which the object is moving; this will be the ``moving`` attribute of events sent by this function too. If ``loading`` is ``True``, the ``loading`` attribute of events sent as a result of calling this method will be ``True`` too. This method returns the name used to place the subobject in the folder (a derivation of ``name``, usually the result of ``self.check_name(name)``). """ if registry is None: registry = get_current_registry() name = self.check_name(name, reserved_names) if getattr(other, '__parent__', None): raise ValueError( 'obj %s added to folder %s already has a __parent__ attribute, ' 'please remove it completely from its existing parent (%s) ' 'before trying to readd it to this one' % (other, self, self.__parent__)) with statsd_timer('folder.add'): objectmap = find_objectmap(self) if objectmap is not None: basepath = resource_path_tuple(self) for node in postorder(other): node_path = node_path_tuple(node) path_tuple = basepath + (name, ) + node_path[1:] # the below gives node an objectid; if the will-be-added # event is the result of a duplication, replace the oid of # the node with a new one objectmap.add( node, path_tuple, duplicating=duplicating is not None, moving=moving is not None, ) if send_events: event = ObjectWillBeAdded( other, self, name, duplicating=duplicating, moving=moving, loading=loading, ) self._notify(event, registry) other.__parent__ = self other.__name__ = name self.data[name] = other self._num_objects.change(1) if self._order is not None: oid = get_oid(other) self._order += (name, ) self._order_oids += (oid, ) if send_events: event = ObjectAdded( other, self, name, duplicating=duplicating, moving=moving, loading=loading, ) self._notify(event, registry) return name
def mgmt_url(self, obj, *arg, **kw): request = self.request traverse = resource_path_tuple(obj) kw['traverse'] = traverse return request.route_url(MANAGE_ROUTE_NAME, *arg, **kw)
def remove(self, obj_objectid_or_path_tuple, moving=False): """ Remove an object from the object map give an object, an object id or a path tuple. If ``moving`` is ``False``, also remove any references added via ``connect`` and any extents related to the removed objects. Return a set of removed oids (including the oid related to the object passed). """ if hasattr(obj_objectid_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_objectid_or_path_tuple) elif isinstance(obj_objectid_or_path_tuple, INT_TYPES): path_tuple = self.objectid_to_path[obj_objectid_or_path_tuple] elif isinstance(obj_objectid_or_path_tuple, tuple): path_tuple = obj_objectid_or_path_tuple else: raise ValueError( 'Value passed to remove must be a traversable ' 'object, an object id, or a path tuple, got %s' % ( (obj_objectid_or_path_tuple,))) pathlen = len(path_tuple) omap = self.pathindex.get(path_tuple) # rationale: if this key isn't present, no path added ever contained it if omap is None: return set() removed = self.family.IF.Set() items = omap.items() removepaths = [] for k, dm in self.pathindex.items(min=path_tuple): if k[:pathlen] == path_tuple: for oidset in dm.values(): removed.update(oidset) for oid in oidset: if oid in self.objectid_to_path: p = self.objectid_to_path[oid] del self.objectid_to_path[oid] del self.path_to_objectid[p] # dont mutate while iterating removepaths.append(k) else: break for k in removepaths: del self.pathindex[k] for x in range(pathlen-1): offset = x + 1 els = path_tuple[:pathlen-offset] omap2 = self.pathindex[els] for level, oidset in items: i = level + offset oidset2 = omap2[i] for oid in oidset: if oid in oidset2: oidset2.remove(oid) # adding to removed and removing from # objectid_to_path and path_to_objectid should have # been taken care of above in the for k, dm in # self.pathindex.items() loop assert oid in removed, oid assert not oid in self.objectid_to_path, oid if not oidset2: del omap2[i] if not moving: self.referencemap.remove(removed) self.extentmap.remove(removed) return removed
def remove(self, obj_objectid_or_path_tuple, references=True): """ Remove an object from the object map give an object, an object id or a path tuple. If ``references`` is True, also remove any references added via ``connect``, otherwise leave them there (e.g. when moving an object).""" if hasattr(obj_objectid_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_objectid_or_path_tuple) elif isinstance(obj_objectid_or_path_tuple, (int, long)): path_tuple = self.objectid_to_path[obj_objectid_or_path_tuple] elif isinstance(obj_objectid_or_path_tuple, tuple): path_tuple = obj_objectid_or_path_tuple else: raise ValueError('Value passed to remove must be a traversable ' 'object, an object id, or a path tuple, got %s' % ((obj_objectid_or_path_tuple, ))) pathlen = len(path_tuple) omap = self.pathindex.get(path_tuple) # rationale: if this key isn't present, no path added ever contained it if omap is None: return set() removed = set() items = omap.items() removepaths = [] for k, dm in self.pathindex.items(min=path_tuple): if k[:pathlen] == path_tuple: for oidset in dm.values(): removed.update(oidset) for oid in oidset: if oid in self.objectid_to_path: p = self.objectid_to_path[oid] del self.objectid_to_path[oid] del self.path_to_objectid[p] # dont mutate while iterating removepaths.append(k) else: break for k in removepaths: del self.pathindex[k] for x in range(pathlen - 1): offset = x + 1 els = path_tuple[:pathlen - offset] omap2 = self.pathindex[els] for level, oidset in items: i = level + offset oidset2 = omap2[i] for oid in oidset: if oid in oidset2: oidset2.remove(oid) # adding to removed and removing from objectid_to_path # and path_to_objectid should have been taken care of # above in the for k, dm in self.pathindex.items() # loop assert oid in removed, oid assert not oid in self.objectid_to_path, oid if not oidset2: del omap2[i] if references: self.referencemap.remove(removed) return removed
def __call__(self, context, request): return resource_path_tuple(context) == self.val
def mgmt_path(request, obj, *arg, **kw): traverse = resource_path_tuple(obj) kw['traverse'] = traverse return request.route_path(MANAGE_ROUTE_NAME, *arg, **kw)
def pencil_icon(resource, request): traverse = resource_path_tuple(resource)[1:] url = request.route_url('sdexternaledit', traverse=traverse) return ' <a href="%s"><i class="icon-pencil"></i></a>' % url
def remove(self, obj_objectid_or_path_tuple, references=True): """ Remove an object from the object map give an object, an object id or a path tuple. If ``references`` is True, also remove any references added via ``connect``, otherwise leave them there (e.g. when moving an object).""" if hasattr(obj_objectid_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_objectid_or_path_tuple) elif isinstance(obj_objectid_or_path_tuple, int): path_tuple = self.objectid_to_path[obj_objectid_or_path_tuple] elif isinstance(obj_objectid_or_path_tuple, tuple): path_tuple = obj_objectid_or_path_tuple else: raise ValueError( 'Value passed to remove must be a traversable ' 'object, an object id, or a path tuple, got %s' % ( (obj_objectid_or_path_tuple,))) pathlen = len(path_tuple) omap = self.pathindex.get(path_tuple) # rationale: if this key isn't present, no path added ever contained it if omap is None: return set() removed = set() items = omap.items() removepaths = [] for k, dm in self.pathindex.items(min=path_tuple): if k[:pathlen] == path_tuple: for oidset in dm.values(): removed.update(oidset) for oid in oidset: if oid in self.objectid_to_path: p = self.objectid_to_path[oid] del self.objectid_to_path[oid] del self.path_to_objectid[p] # dont mutate while iterating removepaths.append(k) else: break for k in removepaths: del self.pathindex[k] for x in range(pathlen-1): offset = x + 1 els = path_tuple[:pathlen-offset] omap2 = self.pathindex[els] for level, oidset in items: i = level + offset oidset2 = omap2[i] for oid in oidset: if oid in oidset2: oidset2.remove(oid) # adding to removed and removing from objectid_to_path # and path_to_objectid should have been taken care of # above in the for k, dm in self.pathindex.items() # loop assert oid in removed, oid assert not oid in self.objectid_to_path, oid if not oidset2: del omap2[i] if references: self.referencemap.remove(removed) return removed
def add(self, name, other, send_events=True, reserved_names=(), duplicating=False, moving=False, registry=None): """ Same as ``__setitem__``. If ``send_events`` is False, suppress the sending of folder events. Don't allow names in the ``reserved_names`` sequence to be added. If ``duplicating`` is True, oids will be replaced in objectmap. This method returns the name used to place the subobject in the folder (a derivation of ``name``, usually the result of ``self.check_name(name)``). """ if registry is None: registry = get_current_registry() name = self.check_name(name, reserved_names) if getattr(other, '__parent__', None): raise ValueError( 'obj %s added to folder %s already has a __parent__ attribute, ' 'please remove it completely from its existing parent (%s) ' 'before trying to readd it to this one' % ( other, self, self.__parent__) ) objectmap = find_objectmap(self) if objectmap is not None: basepath = resource_path_tuple(self) for node in postorder(other): node_path = node_path_tuple(node) path_tuple = basepath + (name,) + node_path[1:] # the below gives node an objectid; if the will-be-added event # is the result of a duplication, replace the oid of the node # with a new one objectmap.add(node, path_tuple, replace_oid=duplicating) if send_events: event = ObjectWillBeAdded( other, self, name, duplicating=duplicating, moving=moving ) self._notify(event, registry) other.__parent__ = self other.__name__ = name self.data[name] = other self._num_objects.change(1) if self._order is not None: self._order += (name,) if send_events: event = ObjectAdded( other, self, name, duplicating=duplicating, moving=moving ) self._notify(event, registry) return name
def remove(self, obj_objectid_or_path_tuple, moving=False): """ Remove an object from the object map give an object, an object id or a path tuple. If ``moving`` is ``False``, also remove any references added via ``connect`` and any extents related to the removed objects. Return a set of removed oids (including the oid related to the object passed). """ if hasattr(obj_objectid_or_path_tuple, '__parent__'): path_tuple = resource_path_tuple(obj_objectid_or_path_tuple) elif isinstance(obj_objectid_or_path_tuple, INT_TYPES): path_tuple = self.objectid_to_path[obj_objectid_or_path_tuple] elif isinstance(obj_objectid_or_path_tuple, tuple): path_tuple = obj_objectid_or_path_tuple else: raise ValueError('Value passed to remove must be a traversable ' 'object, an object id, or a path tuple, got %s' % ((obj_objectid_or_path_tuple, ))) pathlen = len(path_tuple) omap = self.pathindex.get(path_tuple) # rationale: if this key isn't present, no path added ever contained it if omap is None: return set() removed = self.family.IF.Set() items = omap.items() removepaths = [] for k, dm in self.pathindex.items(min=path_tuple): if k[:pathlen] == path_tuple: for oidset in dm.values(): removed.update(oidset) for oid in oidset: if oid in self.objectid_to_path: p = self.objectid_to_path[oid] del self.objectid_to_path[oid] del self.path_to_objectid[p] # dont mutate while iterating removepaths.append(k) else: break for k in removepaths: del self.pathindex[k] for x in range(pathlen - 1): offset = x + 1 els = path_tuple[:pathlen - offset] omap2 = self.pathindex[els] for level, oidset in items: i = level + offset oidset2 = omap2[i] for oid in oidset: if oid in oidset2: oidset2.remove(oid) # adding to removed and removing from # objectid_to_path and path_to_objectid should have # been taken care of above in the for k, dm in # self.pathindex.items() loop assert oid in removed, oid assert not oid in self.objectid_to_path, oid if not oidset2: del omap2[i] if not moving: self.referencemap.remove(removed) self.extentmap.remove(removed) return removed
def __call__(self, context, request): if getattr(context, '__name__', _marker) is not _marker: return resource_path_tuple(context) == self.val return False
def namespace(self): return '.'.join(resource_path_tuple(self)[1:])