Ejemplo n.º 1
0
def getParent(obj):
    """Returns the container the object was traversed via.

    Returns None if the object is a containment root.
    Raises TypeError if the object doesn't have enough context to get the
    parent.
    """
    try:
        location_info = ILocationInfo(obj)
    except TypeError:
        pass
    else:
        return location_info.getParent()

    # XXX Keep the old implementation as the fallback behaviour in the case
    # that obj doesn't have a location parent. This seems advisable as the
    # 'parent' is sometimes taken to mean the traversal parent, and the
    # __parent__ attribute is used for both.

    if IRoot.providedBy(obj):
        return None

    parent = getattr(obj, '__parent__', None)
    if parent is not None:
        return parent

    raise TypeError("Not enough context information to get parent", obj)
Ejemplo n.º 2
0
def getParent(obj):
    """
    Returns the container the object was traversed via.

    See `ITraversalAPI` for details.
    """
    try:
        location_info = ILocationInfo(obj)
    except TypeError:
        pass
    else:
        return location_info.getParent()

    # XXX Keep the old implementation as the fallback behaviour in the case
    # that obj doesn't have a location parent. This seems advisable as the
    # 'parent' is sometimes taken to mean the traversal parent, and the
    # __parent__ attribute is used for both.

    if IRoot.providedBy(obj):
        return None

    parent = getattr(obj, '__parent__', None)
    if parent is not None:
        return parent

    raise TypeError("Not enough context information to get parent", obj)
Ejemplo n.º 3
0
 def __call__(self, *args, **kwargs):
     conn = self.get_connection()
     try:
         with transaction.manager:
             if 'oid' in kwargs and not 'context' in kwargs:
                 oid = kwargs.pop('oid')
                 kwargs['context'] = conn.get(oid)
             if 'context' in kwargs:
                 location_info = ILocationInfo(kwargs['context'])
                 setSite(location_info.getNearestSite())
             return self.run(*args, **kwargs)
     except Exception as e:
         self.retry(exc=e)
Ejemplo n.º 4
0
def getName(obj):
    """
    Get the name an object was traversed via.

    See `ITraversalAPI` for details.
    """
    return ILocationInfo(obj).getName()
Ejemplo n.º 5
0
def getRoot(obj):
    """
    Returns the root of the traversal for the given object.

    See `ITraversalAPI` for details.
    """
    return ILocationInfo(obj).getRoot()
Ejemplo n.º 6
0
    def traverse(self, path, default=_marker, request=None):
        if not path:
            return self.context

        if isinstance(path, six.string_types):
            path = path.split('/')
            if len(path) > 1 and not path[-1]:
                # Remove trailing slash
                path.pop()
        else:
            path = list(path)

        path.reverse()
        pop = path.pop

        curr = self.context
        if not path[-1]:
            # Start at the root
            pop()
            curr = ILocationInfo(self.context).getRoot()
        try:
            while path:
                name = pop()
                curr = traversePathElement(curr, name, path, request=request)

            return curr
        except LocationError:
            if default == _marker:
                raise
            return default
Ejemplo n.º 7
0
def getPath(obj):
    """
    Returns a string representing the physical path to the object.

    See `ITraversalAPI` for details.
    """
    return ILocationInfo(obj).getPath()
Ejemplo n.º 8
0
def getParents(obj):
    """
    Returns a list starting with the given object's parent followed by
    each of its parents.

    See `ITraversalAPI` for details.
    """
    return ILocationInfo(obj).getParents()
Ejemplo n.º 9
0
def getParents(obj):
    """Returns a list starting with the given object's parent followed by
    each of its parents.

    Raises a TypeError if the context doesn't go all the way down to
    a containment root.
    """
    return ILocationInfo(obj).getParents()
Ejemplo n.º 10
0
def find_interface(resource, interface, strict=True): # pylint:disable=inconsistent-return-statements
    """
    Given an object, find the first object in its lineage providing
    the given interface.

    This is similar to :func:`nti.traversal.location.find_interface`,
    but, as with :func:`resource_path` requires the strict adherence
    to the resource tree, unless ``strict`` is set to ``False``.

    :keyword bool strict: Deprecated. Do not use. Non-strict
        lineage is broken lineage.
    """
    if not strict:
        return _p_find_interface(resource, interface)
    # pylint: disable=too-many-function-args
    lineage = ILocationInfo(resource).getParents()
    lineage.insert(0, resource)
    for item in lineage:
        if interface.providedBy(item):
            return item
Ejemplo n.º 11
0
def resource_path(res):
    # This function is somewhat more flexible than Pyramid's, and
    # also more strict. It requires strings (not None, for example)
    # and bottoms out at an IRoot. This helps us get things right.
    # It is probably also a bit slower.
    # Could probably use a __traceback_supplement__ for this
    _known_parents = []

    # Ask for the parents; we do this instead of getPath() and url_quote
    # to work properly with unicode paths through the magic of pyramid
    loc_info = ILocationInfo(res)
    try:
        # pylint: disable=too-many-function-args
        parents = loc_info.getParents()
    except TypeError:  # "Not enough context information to get all parents"
        # This is a programming/design error: some object is not where it
        # should be
        _known_parents.extend(LocationIterator(res))
        logger.exception("Failed to get all parents of %r; known parents: %s",
                         res, _known_parents)
        raise

    if parents:
        # Take the root off, it's implicit and has a name of None
        parents.pop()

    # Put it in the order pyramid expects, root first
    # (root is added only to the names to avoid prepending)
    parents.reverse()
    parents.append(res)
    # And let pyramid construct the URL, doing proper escaping and
    # also caching.
    names = ['']  # Bottom out at the root
    for p in parents:
        name = p.__name__
        if name is None:
            __traceback_info__ = p
            raise TypeError("Element in the hierarchy is missing __name__")
        names.append(name)
    return join_path_tuple(tuple(names))
Ejemplo n.º 12
0
 def _visitSublocations(self) :
     """Restricts the access to the objects that live within
     the nearest site if the catalog itself is locatable.
     """
     uidutil = None
     locatable = ILocationInfo(self, None)
     if locatable is not None :
         site = locatable.getNearestSite()
         sm = site.getSiteManager()
         uidutil = sm.queryUtility(IIntIds)
         if uidutil not in [c.component for c in sm.registeredUtilities()]:
             # we do not have a local inits utility
             uidutil = component.getUtility(IIntIds, context=self)
             for uid in uidutil:
                 obj = uidutil.getObject(uid)
                 if location.inside(obj, site) :
                     yield uid, obj
             return
     if uidutil is None:
         uidutil = component.getUtility(IIntIds)
     for uid in uidutil:
         yield uid, uidutil.getObject(uid)
Ejemplo n.º 13
0
    def annotate(self, txn, request, ob):
        """Set some useful meta-information on the transaction.

        This information is used by the undo framework, for example.
        """
        if request.principal is not None:
            txn.setUser(request.principal.id)

        # Work around methods that are usually used for views
        bare = removeSecurityProxy(ob)
        if isinstance(bare, instancemethod):
            ob = bare.im_self

        # set the location path
        path = None
        location = ILocationInfo(ob, None)
        if location is not None:
            # Views are made children of their contexts, but that
            # doesn't necessarily mean that we can fully resolve the
            # path. E.g. the family tree of a resource cannot be
            # resolved completely, as the site manager is a dead end.
            try:
                path = location.getPath()
            except (AttributeError, TypeError):
                pass
        if path is not None:
            txn.setExtendedInfo('location', path)

        # set the request type
        iface = IRequest
        for iface in providedBy(request):
            if iface.extends(IRequest):
                break
        iface_dotted = '%s.%s' % (iface.__module__, iface.getName())
        txn.setExtendedInfo('request_type', iface_dotted)
        return txn
Ejemplo n.º 14
0
def find_nearest_site(context, root=None, ignore=None):
    """
    Find the nearest :class:`ISite` in the lineage of *context*.

    :param context: The object whose lineage to search.
        If this object cannot be adapted to `ILocationInfo`, then we attempt
        to adapt ``context.target`` and get its site; failing that, we return the
        *root*.
    :param ignore: If the `ILocationInfo` of the *context* can be
       retrieved, but the :meth:`.ILocationInfo.getNearestSite` cannot, then,
       if *ignore* is given, and *context* provides that interface,
       return the *root*. This makes no sense and is deprecated.
    :return: The nearest site. Possibly the root site.

    .. deprecated:: 1.0
       Relying on the fallback to ``context.target`` and *root* is deprecated;
       the *ignore* parameter is deprecated. All of these things signal a broken
       resource tree.
    """
    try:
        loc_info = ILocationInfo(context)
    except TypeError:
        # Not adaptable (not located). What about the target?
        try:
            # pylint: disable=too-many-function-args
            loc_info = ILocationInfo(context.target)
            warnings.warn(
                "Relying on ``context.target`` is deprecated. "
                "Register an ILocationInfo adapter for ``context`` instead.",
                FutureWarning,
                stacklevel=2
            )
            nearest_site = loc_info.getNearestSite()
        except (TypeError, AttributeError):
            # Nothing. Assume the main site/root
            nearest_site = root
    else:
        # Located. Better be able to get a site, otherwise we have a
        # broken chain.
        try:
            # pylint: disable=too-many-function-args
            nearest_site = loc_info.getNearestSite()
        except TypeError:
            # Convertible, but not located correctly.
            if ignore is None or not ignore.providedBy(context):
                raise
            warnings.warn(
                "The ignore argument is deprecated. "
                "Register an appropriate ILocationInfo instead.",
                FutureWarning,
                stacklevel=2
            )
            nearest_site = root

    return nearest_site
Ejemplo n.º 15
0
    def test(self):
        zope.traversing.testing.setUp()

        root = Root()
        f1 = contained(C(), root, name='f1')
        f2 = contained(SiteManagerContainer(), f1, name='f2')
        f3 = contained(C(), f2, name='f3')

        adapter = ILocationInfo(f3)

        self.assertEqual(adapter.getPath(), '/f1/f2/f3')
        self.assertEqual(adapter.getName(), 'f3')
        self.assertEqual(adapter.getRoot(), root)
        self.assertEqual(adapter.getNearestSite(), root)

        f2.setSiteManager(LocalSiteManager(f2))
        self.assertEqual(adapter.getNearestSite(), f2)
    def test(self):
        zope.traversing.testing.setUp()

        root = Root()
        f1 = contained(C(), root, name='f1')
        f2 = contained(SiteManagerContainer(), f1, name='f2')
        f3 = contained(C(), f2, name='f3')
        
        adapter = ILocationInfo(f3)

        self.assertEqual(adapter.getPath(), '/f1/f2/f3')
        self.assertEqual(adapter.getName(), 'f3')
        self.assertEqual(adapter.getRoot(), root)
        self.assertEqual(adapter.getNearestSite(), root)

        f2.setSiteManager(LocalSiteManager(f2))
        self.assertEqual(adapter.getNearestSite(), f2)
Ejemplo n.º 17
0
def getName(obj):
    """Get the name an object was traversed via
    """
    return ILocationInfo(obj).getName()
Ejemplo n.º 18
0
def getPath(obj):
    """Returns a string representing the physical path to the object.
    """
    return ILocationInfo(obj).getPath()
Ejemplo n.º 19
0
def getRoot(obj):
    """Returns the root of the traversal for the given object.
    """
    return ILocationInfo(obj).getRoot()
Ejemplo n.º 20
0
 def name(self):
     # This method is filter
     try:
         return ILocationInfo(self.context).getName()
     except TypeError:
         return u''