Esempio n. 1
0
def traversePathElement(obj, name, further_path, default=_marker,
                        traversable=None, request=None):
    """
    Traverse a single step *name* relative to the given object.

    This is used to implement
    :meth:`zope.traversing.interfaces.ITraversalAPI.traverseName`.

    :param str name: must be a string.  '.' and '..' are treated
        specially, as well as names starting with '@' or '+'.
        Otherwise *name* will be treated as a single path segment.
    :param list further_path: a list of names still to be traversed.
        This method is allowed to change the contents of
        *further_path*.

    :keyword ITraversable traversable: You can explicitly pass in
        an `~zope.traversing.interfaces.ITraversable` as the
        *traversable* argument.  If you do not, the given object will
        be adapted to ``ITraversable``.

    :keyword request: assed in when traversing from presentation
        code.  This allows paths like ``@@foo`` to work.

    :raises zope.location.interfaces.LocationError: if *path* cannot
        be found and '*default* was not provided.
    """
    __traceback_info__ = (obj, name)

    if name == '.':
        return obj

    if name == '..':
        return obj.__parent__

    if name and name[:1] in '@+':
        ns, nm = nsParse(name)
        if ns:
            return namespaceLookup(ns, nm, obj, request)
    else:
        nm = name

    if traversable is None:
        traversable = ITraversable(obj, None)
        if traversable is None:
            raise LocationError('No traversable adapter found', obj)

    try:
        return traversable.traverse(nm, further_path)
    except UnicodeEncodeError:
        # If we're on Python 2, and nm was a unicode string, and the traversable
        # tried to do an attribute lookup, the nm would have been encoded using the
        # system encoding (usually ascii). Failure to encode means invalid attribute
        # name.
        if default is not _marker:
            return default
        raise LocationError(obj, name)
    except LocationError:
        if default is not _marker:
            return default
        raise
Esempio n. 2
0
def traversePathElement(obj,
                        name,
                        further_path,
                        default=_marker,
                        traversable=None,
                        request=None):
    """Traverse a single step 'name' relative to the given object.

    'name' must be a string. '.' and '..' are treated specially, as well as
    names starting with '@' or '+'. Otherwise 'name' will be treated as a
    single path segment.

    'further_path' is a list of names still to be traversed.  This method
    is allowed to change the contents of 'further_path'.

    You can explicitly pass in an ITraversable as the 'traversable'
    argument. If you do not, the given object will be adapted to ITraversable.

    'request' is passed in when traversing from presentation code. This
    allows paths like @@foo to work.

    Raises LocationError if path cannot be found and 'default' was
    not provided.

    """
    __traceback_info__ = (obj, name)

    if name == '.':
        return obj

    if name == '..':
        return obj.__parent__

    if name and name[:1] in '@+':
        ns, nm = nsParse(name)
        if ns:
            return namespaceLookup(ns, nm, obj, request)
    else:
        nm = name

    if traversable is None:
        traversable = ITraversable(obj, None)
        if traversable is None:
            raise LocationError('No traversable adapter found', obj)

    try:
        return traversable.traverse(nm, further_path)
    except UnicodeEncodeError:
        # If we're on Python 2, and nm was a unicode string, and the traversable
        # tried to do an attribute lookup, the nm would have been encoded using the
        # system encoding (usually ascii). Failure to encode means invalid attribute
        # name.
        if default is not _marker:
            return default
        raise LocationError(obj, name)
    except LocationError:
        if default is not _marker:
            return default
        raise
Esempio n. 3
0
def traversePathElement(obj, name, further_path, default=_marker,
                        traversable=None, request=None):
    """Traverse a single step 'name' relative to the given object.

    'name' must be a string. '.' and '..' are treated specially, as well as
    names starting with '@' or '+'. Otherwise 'name' will be treated as a
    single path segment.

    'further_path' is a list of names still to be traversed.  This method
    is allowed to change the contents of 'further_path'.

    You can explicitly pass in an ITraversable as the 'traversable'
    argument. If you do not, the given object will be adapted to ITraversable.

    'request' is passed in when traversing from presentation code. This
    allows paths like @@foo to work.

    Raises LocationError if path cannot be found and 'default' was
    not provided.

    """
    __traceback_info__ = (obj, name)

    if name == '.':
        return obj

    if name == '..':
        return obj.__parent__
 
    if name and name[:1] in '@+':
        ns, nm = nsParse(name)
        if ns:
            return namespaceLookup(ns, nm, obj, request)
    else:
        nm = name

    if traversable is None:
        traversable = ITraversable(obj, None)
        if traversable is None:
            raise LocationError('No traversable adapter found', obj)

    try:
        return traversable.traverse(nm, further_path)
    except LocationError:
        if default is not _marker:
            return default
        else:
            raise

    return obj
Esempio n. 4
0
def path_traverse(base, econtext, call, path_items):
    if path_items:
        request = econtext.get("request")
        path_items = list(path_items)
        path_items.reverse()

        while path_items:
            name = path_items.pop()
            ns_used = ":" in name
            if ns_used:
                namespace, name = name.split(":", 1)
                base = z3c.pt.namespaces.function_namespaces[namespace](base)
                if ITraversable.providedBy(base):
                    base = traversePathElement(base,
                                               name,
                                               path_items,
                                               request=request)

                    # base = proxify(base)

                    continue

            # special-case dicts for performance reasons
            if isinstance(base, dict):
                next = base.get(name, _marker)
            else:
                next = getattr(base, name, _marker)

            if next is not _marker:
                base = next
                if ns_used and isinstance(base, MethodType):
                    base = base()
                # The bytecode peephole optimizer removes the next line:
                continue  # pragma: no cover
            else:
                base = traversePathElement(base,
                                           name,
                                           path_items,
                                           request=request)

            # if not isinstance(base, (basestring, tuple, list)):
            #    base = proxify(base)

    if call and getattr(base, "__call__", _marker) is not _marker:
        return base()

    return base
Esempio n. 5
0
def path_traverse(base, econtext, call, path_items):
    if path_items:
        request = econtext.get('request')
        path_items = list(path_items)
        path_items.reverse()

        while len(path_items):
            name = path_items.pop()
            ns_used = ':' in name
            if ns_used:
                namespace, name = name.split(':', 1)
                base = z3c.pt.namespaces.function_namespaces[namespace](base)
                if ITraversable.providedBy(base):
                    base = traversePathElement(base,
                                               name,
                                               path_items,
                                               request=request)

                    # base = proxify(base)

                    continue

            # special-case dicts for performance reasons
            if isinstance(base, dict):
                next = base.get(name, _marker)
            else:
                next = getattr(base, name, _marker)

            if next is not _marker:
                base = next
                if ns_used and isinstance(base, MethodType):
                    base = base()
                continue
            else:
                base = traversePathElement(base,
                                           name,
                                           path_items,
                                           request=request)

            # if not isinstance(base, (basestring, tuple, list)):
            #    base = proxify(base)

    if call and getattr(base, '__call__', _marker) is not _marker:
        return base()

    return base
Esempio n. 6
0
def path_traverse(base, econtext, call, path_items):
    if path_items:
        request = econtext.get("request")
        path_items = list(path_items)
        path_items.reverse()

        while path_items:
            name = path_items.pop()
            ns_used = ":" in name
            if ns_used:
                namespace, name = name.split(":", 1)
                base = z3c.pt.namespaces.function_namespaces[namespace](base)
                if ITraversable.providedBy(base):
                    base = traversePathElement(
                        base, name, path_items, request=request
                    )

                    # base = proxify(base)

                    continue

            # special-case dicts for performance reasons
            if isinstance(base, dict):
                next = base.get(name, _marker)
            else:
                next = getattr(base, name, _marker)

            if next is not _marker:
                base = next
                if ns_used and isinstance(base, MethodType):
                    base = base()
                # The bytecode peephole optimizer removes the next line:
                continue  # pragma: no cover
            else:
                base = traversePathElement(
                    base, name, path_items, request=request
                )

            # if not isinstance(base, (basestring, tuple, list)):
            #    base = proxify(base)

    if call and getattr(base, "__call__", _marker) is not _marker:
        return base()

    return base
Esempio n. 7
0
def path_traverse(base, econtext, call, path_items):
    if path_items:
        request = econtext.get('request')
        path_items = list(path_items)
        path_items.reverse()

        while len(path_items):
            name = path_items.pop()
            ns_used = ':' in name
            if ns_used:
                namespace, name = name.split(':', 1)
                base = z3c.pt.namespaces.function_namespaces[namespace](base)
                if ITraversable.providedBy(base):
                    base = traversePathElement(
                        base, name, path_items, request=request)

                    # base = proxify(base)

                    continue

            # special-case dicts for performance reasons
            if isinstance(base, dict):
                next = base.get(name, _marker)
            else:
                next = getattr(base, name, _marker)

            if next is not _marker:
                base = next
                if ns_used and isinstance(base, MethodType):
                    base = base()
                continue
            else:
                base = traversePathElement(
                    base, name, path_items, request=request)

            # if not isinstance(base, (basestring, tuple, list)):
            #    base = proxify(base)

    if call and getattr(base, '__call__', _marker) is not _marker:
        return base()

    return base
Esempio n. 8
0
 def testImplementsITraversable(self):
     self.assertTrue(ITraversable.providedBy(DefaultTraversable(None)))
Esempio n. 9
0
    def traverse(self, name, remaining):
        """Acquire a name

        Let's set up some example data:

          >>> class testcontent(object):
          ...     zope.interface.implements(ITraversable)
          ...     def traverse(self, name, remaining):
          ...         v = getattr(self, name, None)
          ...         if v is None:
          ...             raise LocationError(self, name)
          ...         return v
          ...     def __repr__(self):
          ...         return 'splat'

          >>> ob = testcontent()
          >>> ob.a = 1
          >>> ob.__parent__ = testcontent()
          >>> ob.__parent__.b = 2
          >>> ob.__parent__.__parent__ = testcontent()
          >>> ob.__parent__.__parent__.c = 3

        And acquire some names:

          >>> adapter = acquire(ob)

          >>> adapter.traverse('a', ())
          1

          >>> adapter.traverse('b', ())
          2

          >>> adapter.traverse('c', ())
          3

          >>> adapter.traverse('d', ())
          Traceback (most recent call last):
          ...
          LocationError: (splat, 'd')
        """
        i = 0
        ob = self.context
        while i < 200:
            i += 1
            traversable = ITraversable(ob, None)
            if traversable is not None:
                try:
                    # ??? what do we do if the path gets bigger?
                    path = []
                    next = traversable.traverse(name, path)
                    if path:
                        continue
                except LocationError:
                    pass

                else:
                    return next

            ob = getattr(ob, '__parent__', None)
            if ob is None:
                raise LocationError(self.context, name)

        raise ExcessiveDepth(self.context, name)
Esempio n. 10
0
    def traverse(self, name, remaining):
        """
        Acquire a name

        Let's set up some example data::

          >>> @zope.interface.implementer(ITraversable)
          ... class testcontent(object):
          ...     def traverse(self, name, remaining):
          ...         v = getattr(self, name, None)
          ...         if v is None:
          ...             raise LocationError(self, name)
          ...         return v
          ...     def __repr__(self):
          ...         return 'splat'

          >>> ob = testcontent()
          >>> ob.a = 1
          >>> ob.__parent__ = testcontent()
          >>> ob.__parent__.b = 2
          >>> ob.__parent__.__parent__ = testcontent()
          >>> ob.__parent__.__parent__.c = 3

        And acquire some names:

          >>> adapter = acquire(ob)

          >>> adapter.traverse('a', ())
          1

          >>> adapter.traverse('b', ())
          2

          >>> adapter.traverse('c', ())
          3

          >>> adapter.traverse('d', ())
          Traceback (most recent call last):
          ...
          LocationError: (splat, 'd')
        """
        i = 0
        ob = self.context
        while i < 200:
            i += 1
            traversable = ITraversable(ob, None)
            if traversable is not None:
                try:
                    # ??? what do we do if the path gets bigger?
                    path = []
                    next = traversable.traverse(name, path)
                    if path:
                        continue
                except LocationError:
                    pass

                else:
                    return next

            ob = getattr(ob, '__parent__', None)
            if ob is None:
                raise LocationError(self.context, name)

        raise ExcessiveDepth(self.context, name)
Esempio n. 11
0
 def testImplementsITraversable(self):
     self.failUnless(ITraversable.providedBy(DefaultTraversable(None)))
Esempio n. 12
0
 def testImplementsITraversable(self):
     self.failUnless(ITraversable.providedBy(DefaultTraversable(None)))
 def __call__(self, text, file_path=None):
     dom = getDom(text)
     if not dom:
         return text
     for link in dom.cssselect('a[href],img[src]'):
         link = LinkElement(link)
         url = link.val.rstrip('/').strip()
         match_path = url.replace('%20', ' ').lstrip('/').strip()
         if type(match_path) == unicode:
             match_path = match_path.encode('utf-8')
         obj = self.context.unrestrictedTraverse(match_path, None)
         ext = match_path.split('.')[-1].lower()
         ext = ext in ('png', 'jpg', 'gif', 'jpeg') and ext or 'jpg'
         if obj and isinstance(obj, ATImage) or (
             hasattr(obj, 'getBlobWrapper') and \
                 'image' in obj.getBlobWrapper().getContentType()):
             link.set(url + '/image.%s' % ext)
         elif obj and isinstance(obj, ArchetypesImage):
             # it's a scale, always use image.jpg extension
             link.set(url + '/image.jpg')
         if not obj:
             try:
                 path, filename = match_path.rsplit('/', 1)
             except ValueError:
                 continue
             fieldname = filename.split('_', 1)[0]
             obj = self.context.restrictedTraverse('/'.join((path, fieldname)), None)
             if not obj:
                 # not all fields are traversable
                 obj = self.context.restrictedTraverse(path, None)
                 if IImageScaling.providedBy(obj) or \
                     ITraversable.providedBy(obj):
                     # we can't do anything with the @@images view yet here...
                     obj = None
                 if obj and hasattr(obj, 'getField'):
                     field = obj.getField(fieldname)
                     if field:
                         obj = field.get(obj)
             if PLONE_APP_BLOB_INSTALLED and IBlobWrapper.providedBy(obj):
                 link.set(url + '/image.jpg')
             if not obj:
                 if '/@@images/' in match_path:
                     parent_path, image_name = match_path.split('/@@images/')
                     spl_img_name = image_name.split('/')
                     if len(spl_img_name) == 1:
                         # no scalename in path
                         uid = spl_img_name[0]
                         if '-' in uid:
                             # seems to be actual uid for a custom scale here...
                             # it should written out as [uid].[ext]
                             new_path = '/'.join((parent_path, uid))
                         else:
                             # just use original if we can't figure this out...
                             new_path = '/'.join((parent_path, 'image.%s' % ext))
                     else:
                         # scalename in path
                         fieldname, scalename = spl_img_name
                         new_path = '/'.join((parent_path, '_'.join((fieldname, scalename))))
                         new_path = new_path + '/image.jpg'
                     new_path = '/' + new_path.lstrip('/')
                     link.set(new_path)
     return unicode(dom)
Esempio n. 14
0
def traversePathElement(obj,
                        name,
                        further_path,
                        default=_marker,
                        traversable=None,
                        request=None):
    """
    Traverse a single step *name* relative to the given object.

    This is used to implement
    :meth:`zope.traversing.interfaces.ITraversalAPI.traverseName`.

    :param str name: must be a string.  '.' and '..' are treated
        specially, as well as names starting with '@' or '+'.
        Otherwise *name* will be treated as a single path segment.
    :param list further_path: a list of names still to be traversed.
        This method is allowed to change the contents of
        *further_path*.

    :keyword ITraversable traversable: You can explicitly pass in
        an `~zope.traversing.interfaces.ITraversable` as the
        *traversable* argument.  If you do not, the given object will
        be adapted to ``ITraversable``.

    :keyword request: assed in when traversing from presentation
        code.  This allows paths like ``@@foo`` to work.

    :raises zope.location.interfaces.LocationError: if *path* cannot
        be found and '*default* was not provided.
    """
    __traceback_info__ = (obj, name)

    if name == '.':
        return obj

    if name == '..':
        return obj.__parent__

    if name and name[:1] in '@+':
        ns, nm = nsParse(name)
        if ns:
            return namespaceLookup(ns, nm, obj, request)
    else:
        nm = name

    if traversable is None:
        traversable = ITraversable(obj, None)
        if traversable is None:
            raise LocationError('No traversable adapter found', obj)

    try:
        return traversable.traverse(nm, further_path)
    except UnicodeEncodeError:
        # If we're on Python 2, and nm was a unicode string, and the traversable
        # tried to do an attribute lookup, the nm would have been encoded using the
        # system encoding (usually ascii). Failure to encode means invalid attribute
        # name.
        if default is not _marker:
            return default
        raise LocationError(obj, name)
    except LocationError:
        if default is not _marker:
            return default
        raise
 def testImplementsITraversable(self):
     self.assertTrue(ITraversable.providedBy(DefaultTraversable(None)))
    def __call__(self, request):  # pylint:disable=too-many-locals,too-many-branches,too-many-statements
        """
        See :meth:`pyramid.interfaces.ITraversar.__call__`.
        """
        # JAM: Unfortunately, the superclass implementation is entirely monolithic
        # and we so we cannot reuse any part of it. Instead,
        # we copy-and-paste it. Unless otherwise noted, comments below are
        # original.

        # JAM: Note the abundance of no covers. These are for features we are
        # not currently using and the code is lifted directly from pyramid.
        environ = request.environ

        if request.matchdict is not None:
            matchdict = request.matchdict

            path = matchdict.get('traverse', '/') or '/'
            if is_nonstr_iter(path):
                # this is a *traverse stararg (not a {traverse})
                # routing has already decoded these elements, so we just
                # need to join them
                path = '/'.join(path) or '/'

            subpath = matchdict.get('subpath', ())
            if not is_nonstr_iter(subpath):  # pragma: no cover
                # this is not a *subpath stararg (just a {subpath})
                # routing has already decoded this string, so we just need
                # to split it
                subpath = split_path_info(subpath)

        else:  # pragma: no cover
            # this request did not match a route
            subpath = ()
            try:
                # empty if mounted under a path in mod_wsgi, for example
                path = decode_path_info(environ['PATH_INFO'] or '/')
            except KeyError:
                path = '/'
            except UnicodeDecodeError as e:
                raise URLDecodeError(e.encoding, e.object, e.start, e.end,
                                     e.reason)

        if VH_ROOT_KEY in environ:  # pragma: no cover
            # HTTP_X_VHM_ROOT
            vroot_path = decode_path_info(environ[VH_ROOT_KEY])
            vroot_tuple = split_path_info(vroot_path)
            # both will (must) be unicode or asciistr
            vpath = vroot_path + path
            vroot_idx = len(vroot_tuple) - 1
        else:
            vroot_tuple = ()
            vpath = path
            vroot_idx = -1

        root = self.root
        ob = vroot = root

        if vpath == '/':  # invariant: vpath must not be empty
            # prevent a call to traversal_path if we know it's going
            # to return the empty tuple
            vpath_tuple = ()
        else:
            i = 0
            view_selector = self.VIEW_SELECTOR
            # A list so that remaining_path can be modified
            vpath_tuple = list(split_path_info(vpath))
            for segment in vpath_tuple:
                # JAM: Fire traversal events, mainly so sites get installed. See
                # zope.publisher.base.
                _notify_before_traverse_event(ob, request)
                # JAM: Notice that checking for '@@' is special cased, and
                # doesn't go through the normal namespace lookup as it would in
                # plain zope traversal. (XXX: Why not?)
                if segment.startswith(view_selector):  # pragma: no cover
                    return {
                        'context': ob,
                        'view_name': segment[2:],
                        'subpath': vpath_tuple[i + 1:],
                        'traversed': vpath_tuple[:vroot_idx + i + 1],
                        'virtual_root': vroot,
                        'virtual_root_path': vroot_tuple,
                        'root': root
                    }

                try:
                    # JAM: This is where we differ. instead of using __getitem__,
                    # we use the traversing machinery.
                    # The zope app would use IPublishTraverser, which
                    # would install security proxies along the way. We probably don't need to
                    # do that? TODO:
                    # NOTE: By passing the request here, we require all traversers
                    # (including the namespace traversers) to be registered as multi-adapters.
                    # None of the default namespaces are. See our
                    # configure.zcml for what is.

                    # JAM: Damn stupid implementation of traversePathElement ignores
                    # the request argument to find a traversable /except/ when a namespace is found.
                    # therefore, we explicitly query for the multi adapter ourself in the non-namespace case
                    # (In the namespace case, we let traversing handle it, because it needs a named adapter
                    # after parsing)
                    traversable = None
                    if segment and segment[0] not in '+@' \
                            and not ITraversable.providedBy(ob):
                        try:
                            # Use the installed component registry
                            # instead of the request registry (which
                            # is the global component registry if
                            # pyramid was configured that way, or a
                            # standalone registry) in case the act of
                            # traversing has changed the site manager;
                            # zope.site.site.threadSiteSubscriber will
                            # do this for each BeforeTraverseEvent
                            # that's fired (though that's not
                            # registered by default).
                            traversable = queryMultiAdapter((ob, request),
                                                            ITraversable)
                        except TypeError:
                            # Some things are registered for "*" (DefaultTraversable)
                            # which means they get called here. If they can't take
                            # two arguments, then we bail. Sucks.
                            pass

                    remaining_path = vpath_tuple[i + 1:]
                    next_ob = ztraversing.traversePathElement(
                        ob,
                        segment,
                        remaining_path,
                        traversable=traversable,
                        request=request)
                    if remaining_path != vpath_tuple[i + 1:]:
                        # Is this if check necessary? It would be faster to
                        # always assign
                        vpath_tuple[i + 1:] = remaining_path
                except LocationError:
                    # LocationError is a type of KeyError. The DefaultTraversable turns
                    # plain KeyError and TypeErrors into LocationError.
                    return {
                        'context': ob,
                        'view_name': segment,
                        'subpath': vpath_tuple[i + 1:],
                        'traversed': vpath_tuple[:vroot_idx + i + 1],
                        'virtual_root': vroot,
                        'virtual_root_path': vroot_tuple,
                        'root': root
                    }
                if i == vroot_idx:  # pragma: no cover
                    vroot = next_ob
                ob = next_ob
                i += 1

        # JAM: Also fire before traversal for the actual context item, since we
        # won't actually traverse into it. Be sure not to fire multiple times
        # for this (E.g., the root). This logic is complicated by the
        # multi-returns above.
        _notify_before_traverse_event(ob, request)

        return {
            'context': ob,
            'view_name': empty,
            'subpath': subpath,
            'traversed': vpath_tuple,
            'virtual_root': vroot,
            'virtual_root_path': vroot_tuple,
            'root': root
        }