Exemple #1
0
 def __call__(self, request):
     path = decode_path_info(request.environ['PATH_INFO'])
     ob = resources[path]
     traversed = split_path_info(path)
     return {'context':ob, 'view_name':'','subpath':(),
             'traversed':traversed, 'virtual_root':ob,
             'virtual_root_path':(), 'root':ob}
Exemple #2
0
def canonical_redirect(event):
    request = event["request"]

    # Ignore subrequests
    if len(manager.stack) > 1:
        return

    if request.method not in ("GET", "HEAD"):
        return
    if request.response.status_int != 200:
        return
    if not request.environ.get("encoded.canonical_redirect", True):
        return
    if request.path_info == "/":
        return

    canonical_path = event.rendering_val.get("@id", None)
    if canonical_path is None:
        return
    canonical_path = canonical_path.split("?", 1)[0]

    request_path = _join_path_tuple(("",) + split_path_info(request.path_info))
    if request_path == canonical_path.rstrip("/") and request.path_info.endswith("/") == canonical_path.endswith("/"):
        return

    if "/@@" in request.path_info:
        return

    qs = request.query_string
    location = canonical_path + ("?" if qs else "") + qs
    raise HTTPMovedPermanently(location=location)
Exemple #3
0
 def __call__(self, request):
     path = decode_path_info(request.environ['PATH_INFO'])
     ob = resources[path]
     traversed = split_path_info(path)
     return {'context':ob, 'view_name':'','subpath':(),
             'traversed':traversed, 'virtual_root':ob,
             'virtual_root_path':(), 'root':ob}
Exemple #4
0
def canonical_redirect(event):
    request = event['request']

    # Ignore subrequests
    if len(manager.stack) > 1:
        return

    if request.method not in ('GET', 'HEAD'):
        return
    if request.response.status_int != 200:
        return
    if not request.environ.get('clincoded.canonical_redirect', True):
        return
    if request.path_info == '/':
        return

    canonical_path = event.rendering_val.get('@id', None)
    if canonical_path is None:
        return
    canonical_path = canonical_path.split('?', 1)[0]

    request_path = _join_path_tuple(('', ) +
                                    split_path_info(request.path_info))
    if (request_path == canonical_path.rstrip('/') and
            request.path_info.endswith('/') == canonical_path.endswith('/')):
        return

    if '/@@' in request.path_info:
        return

    qs = request.query_string
    location = canonical_path + ('?' if qs else '') + qs
    raise HTTPMovedPermanently(location=location)
Exemple #5
0
def canonical_redirect(event):
    request = event['request']

    # Ignore subrequests
    if len(manager.stack) > 1:
        return

    if request.method not in ('GET', 'HEAD'):
        return
    if request.response.status_int != 200:
        return
    if not request.environ.get('encoded.canonical_redirect', True):
        return
    if request.path_info == '/':
        return

    canonical_path = event.rendering_val.get('@id', None)
    if canonical_path is None:
        return
    canonical_path = canonical_path.split('?', 1)[0]

    request_path = _join_path_tuple(('',) + split_path_info(request.path_info))
    if (request_path == canonical_path.rstrip('/') and
            request.path_info.endswith('/') == canonical_path.endswith('/')):
        return

    if '/@@' in request.path_info:
        return

    qs = request.query_string
    location = canonical_path + ('?' if qs else '') + qs
    raise HTTPMovedPermanently(location=location)
Exemple #6
0
    def __call__(self, request):
        """ The first part of this function is copied without changes from
        :meth:`pyramid.traversal.ResourceTreeTraverser.__call__`.

        :param request: Current request
        :type request: :class:`pyramid.request.Request`

        :return: Traversal info dictionary
        :rtype: see :func:`pyramid.traversal.traverse`
        """

        subpath, vpath, vroot_tuple = self._extract_from_request(request)

        root = self.root

        # Part 2:
        vs = self.VIEW_SELECTOR
        lvs = len(vs)
        result = {
            "context": root,
            "view_name": empty,
            "subpath": subpath,
            "traversed": (),
            "virtual_root": root,
            "virtual_root_path": vroot_tuple,
            "root": root,
        }

        if vpath == slash:
            return result
        else:
            vpath_tuple = split_path_info(vpath)
            traversed_nodes = self.traverse(root, vpath_tuple)
            if not traversed_nodes:
                view_name = vpath_tuple[0]
                if view_name[:lvs] == vs:
                    view_name = view_name[lvs:]
                result["view_name"] = view_name
                result["subpath"] = vpath_tuple[1:]
                return result
            traversed = vpath_tuple[: len(traversed_nodes)]
            subpath = list(vpath_tuple[len(traversed_nodes) :])
            if subpath:
                view_name = subpath.pop(0)
                if view_name[:lvs] == vs:
                    view_name = view_name[lvs:]
            else:
                view_name = empty
            return {
                "context": traversed_nodes[-1],
                "view_name": view_name,
                "subpath": subpath,
                "traversed": traversed,
                "virtual_root": root,
                "virtual_root_path": vroot_tuple,
                "root": root,
            }
Exemple #7
0
    def __call__(self, request):
        """ The first part of this function is copied without changes from
        :meth:`pyramid.traversal.ResourceTreeTraverser.__call__`.

        :param request: Current request
        :type request: :class:`pyramid.request.Request`

        :return: Traversal info dictionary
        :rtype: see :func:`pyramid.traversal.traverse`
        """

        subpath, vpath, vroot_tuple = self._extract_from_request(request)

        root = self.root

        # Part 2:
        vs = self.VIEW_SELECTOR
        lvs = len(vs)
        result = {
            'context': root,
            'view_name': empty,
            'subpath': subpath,
            'traversed': (),
            'virtual_root': root,
            'virtual_root_path': vroot_tuple,
            'root': root
        }

        if vpath == slash:
            return result
        else:
            vpath_tuple = split_path_info(vpath)
            traversed_nodes = self.traverse(root, vpath_tuple)
            if not traversed_nodes:
                view_name = vpath_tuple[0]
                if view_name[:lvs] == vs:
                    view_name = view_name[lvs:]
                result['view_name'] = view_name
                result['subpath'] = vpath_tuple[1:]
                return result
            traversed = vpath_tuple[:len(traversed_nodes)]
            subpath = list(vpath_tuple[len(traversed_nodes):])
            if subpath:
                view_name = subpath.pop(0)
                if view_name[:lvs] == vs:
                    view_name = view_name[lvs:]
            else:
                view_name = empty
            return {
                'context': traversed_nodes[-1],
                'view_name': view_name,
                'subpath': subpath,
                'traversed': traversed,
                'virtual_root': root,
                'virtual_root_path': vroot_tuple,
                'root': root
            }
Exemple #8
0
 def matcher(path):
     m = match(path)
     if m is None:
         return None
     d = {}
     for k, v in m.groupdict().items():
         if k == remainder:
             d[k] = split_path_info(v)
         else:
             d[k] = v
     return d
Exemple #9
0
 def matcher(path):
     m = match(path)
     if m is None:
         return None
     d = {}
     for k, v in m.groupdict().items():
         if k == remainder:
             d[k] = split_path_info(v)
         else:
             d[k] = v
     return d
Exemple #10
0
 def __call__(self, request):
     path = request.path_info
     ob = resources[path]
     traversed = split_path_info(path)
     return {
         'context': ob,
         'view_name': '',
         'subpath': (),
         'traversed': traversed,
         'virtual_root': ob,
         'virtual_root_path': (),
         'root': ob,
     }
Exemple #11
0
 def __call__(self, request):
     path = request.path_info
     ob = resources[path]
     traversed = split_path_info(path)
     return {
         'context': ob,
         'view_name': '',
         'subpath': (),
         'traversed': traversed,
         'virtual_root': ob,
         'virtual_root_path': (),
         'root': ob,
     }
Exemple #12
0
    def _extract_from_request(request):  # pragma: no cover
        """ Extract subpath, vpath and vroot_tuple from the request.  The
        contents of this method is just a copy from the base class'
        implementation.

        :param request: Current request
        :type request: :class:`pyramid.request.Request`

        :return: (subpath, vpath, vroot_tuple)
        :rtype: tuple
        """

        environ = request.environ
        matchdict = request.matchdict
        if matchdict is not None:
            path = matchdict.get('traverse', slash) or slash
            if is_nonstr_iter(path):
                path = '/' + slash.join(path) or slash
            subpath = matchdict.get('subpath', ())
            if not is_nonstr_iter(subpath):
                subpath = split_path_info(subpath)
        else:
            subpath = ()
            try:
                path = request.path_info or slash
            except KeyError:
                path = slash
            except UnicodeDecodeError as e:
                raise URLDecodeError(e.encoding, e.object, e.start, e.end,
                                     e.reason)
        if VH_ROOT_KEY in environ:
            vroot_path = decode_path_info(environ[VH_ROOT_KEY])
            vroot_tuple = split_path_info(vroot_path)
            vpath = vroot_path + path
        else:
            vroot_tuple = ()
            vpath = path
        return subpath, vpath, vroot_tuple
Exemple #13
0
    def _extract_from_request(request):  # pragma: no cover
        """ Extract subpath, vpath and vroot_tuple from the request.  The
        contents of this method is just a copy from the base class'
        implementation.

        :param request: Current request
        :type request: :class:`pyramid.request.Request`

        :return: (subpath, vpath, vroot_tuple)
        :rtype: tuple
        """

        environ = request.environ
        matchdict = request.matchdict
        if matchdict is not None:
            path = matchdict.get('traverse', slash) or slash
            if is_nonstr_iter(path):
                path = '/' + slash.join(path) or slash
            subpath = matchdict.get('subpath', ())
            if not is_nonstr_iter(subpath):
                subpath = split_path_info(subpath)
        else:
            subpath = ()
            try:
                path = request.path_info or slash
            except KeyError:
                path = slash
            except UnicodeDecodeError as e:
                raise URLDecodeError(e.encoding, e.object, e.start, e.end,
                                     e.reason)
        if VH_ROOT_KEY in environ:
            vroot_path = decode_path_info(environ[VH_ROOT_KEY])
            vroot_tuple = split_path_info(vroot_path)
            vpath = vroot_path + path
        else:
            vroot_tuple = ()
            vpath = path
        return subpath, vpath, vroot_tuple
Exemple #14
0
def canonical_redirect(event):
    request = event['request']

    # Ignore subrequests
    if len(manager.stack) > 1:
        return

    if request.method not in ('GET', 'HEAD'):
        return
    if request.response.status_int != 200:
        return
    if not request.environ.get('encoded.canonical_redirect', True):
        return
    if request.path_info == '/':
        return

    if not isinstance(event.rendering_val, dict):
        return

    canonical = event.rendering_val.get('@id', None)
    if canonical is None:
        return
    canonical_path, _, canonical_qs = canonical.partition('?')

    request_path = _join_path_tuple(('', ) +
                                    split_path_info(request.path_info))
    if (request_path == canonical_path.rstrip('/')
            and request.path_info.endswith('/') == canonical_path.endswith('/')
            and (canonical_qs in ('', request.query_string))):
        return

    if '/@@' in request.path_info:
        return

    if (parse_qs(canonical_qs) == parse_qs(request.query_string)
            and '/suggest' in request_path):
        return

    qs = canonical_qs or request.query_string
    location = canonical_path + ('?' if qs else '') + qs
    raise HTTPMovedPermanently(location=location)
Exemple #15
0
def canonical_redirect(event):
    request = event['request']

    # Ignore subrequests
    if len(manager.stack) > 1:
        return

    if request.method not in ('GET', 'HEAD'):
        return
    if request.response.status_int != 200:
        return
    if not request.environ.get('encoded.canonical_redirect', True):
        return
    if request.path_info == '/':
        return

    if not isinstance(event.rendering_val, dict):
        return

    canonical = event.rendering_val.get('@id', None)
    if canonical is None:
        return
    canonical_path, _, canonical_qs = canonical.partition('?')

    request_path = _join_path_tuple(('',) + split_path_info(request.path_info))
    if (request_path == canonical_path.rstrip('/') and
            request.path_info.endswith('/') == canonical_path.endswith('/') and
            (canonical_qs in ('', request.query_string))):
        return

    if '/@@' in request.path_info:
        return

    qs = canonical_qs or request.query_string
    # add redirect information to the query string, but not for the routes specified below
    if not any(route in canonical_path for route in ['/search/', '/browse/', '/metadata/']):
        redir_qs = (qs + '&' if qs else '') + urlencode([('redirected_from', request.path_info)])
    else:
        redir_qs = qs
    location = canonical_path + ('?' if redir_qs else '') + redir_qs
    raise HTTPMovedPermanently(location=location, detail="Redirected from " + str(request.path_info))
Exemple #16
0
def canonical_redirect(event):
    request = event['request']

    # Ignore subrequests
    if len(manager.stack) > 1:
        return

    if request.method not in ('GET', 'HEAD'):
        return
    if request.response.status_int != 200:
        return
    if not request.environ.get('encoded.canonical_redirect', True):
        return
    if request.path_info == '/':
        return

    if not isinstance(event.rendering_val, dict):
        return

    canonical = event.rendering_val.get('@id', None)
    if canonical is None:
        return
    canonical_path, _, canonical_qs = canonical.partition('?')

    request_path = _join_path_tuple(('',) + split_path_info(request.path_info))   
    if (request_path == canonical_path.rstrip('/') and
            request.path_info.endswith('/') == canonical_path.endswith('/') and
            (canonical_qs in ('', request.query_string))):
        return

    if '/@@' in request.path_info:
        return

    if (parse_qs(canonical_qs) == parse_qs(request.query_string) and
            '/suggest' in request_path):
        return

    qs = canonical_qs or request.query_string
    location = canonical_path + ('?' if qs else '') + qs
    raise HTTPMovedPermanently(location=location)
Exemple #17
0
 def matcher(path):
     # This function really wants to consume Unicode patterns natively,
     # but if someone passes us a bytestring, we allow it by converting it
     # to Unicode using the ASCII decoding.  We decode it using ASCII
     # because we don't want to accept bytestrings with high-order
     # characters in them here as we have no idea what the encoding
     # represents.
     if path.__class__ is not text_type:
         path = text_(path, 'ascii')
     m = match(path)
     if m is None:
         return None
     d = {}
     for k, v in m.groupdict().items():
         # k and v will be Unicode 2.6.4 and lower doesnt accept unicode
         # kwargs as **kw, so we explicitly cast the keys to native
         # strings in case someone wants to pass the result as **kw
         nk = native_(k, 'ascii')
         if k == remainder:
             d[nk] = split_path_info(v)
         else:
             d[nk] = v
     return d
 def matcher(path):
     # This function really wants to consume Unicode patterns natively,
     # but if someone passes us a bytestring, we allow it by converting it
     # to Unicode using the ASCII decoding.  We decode it using ASCII
     # because we don't want to accept bytestrings with high-order
     # characters in them here as we have no idea what the encoding
     # represents.
     if path.__class__ is not text_type:
         path = text_(path, 'ascii')
     m = match(path)
     if m is None:
         return None
     d = {}
     for k, v in m.groupdict().items():
         # k and v will be Unicode 2.6.4 and lower doesnt accept unicode
         # kwargs as **kw, so we explicitly cast the keys to native
         # strings in case someone wants to pass the result as **kw
         nk = native_(k, 'ascii')
         if k == remainder:
             d[nk] = split_path_info(v)
         else:
             d[nk] = v
     return d
Exemple #19
0
    def __call__(self, request):
        # pylint: disable=too-many-locals,too-many-branches,too-many-statements
        environ = request.environ
        matchdict = request.matchdict

        if matchdict is not None:
            path = matchdict.get('traverse', slash) or slash
            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 = '/' + slash.join(path) or slash

            subpath = matchdict.get('subpath', ())
            if not is_nonstr_iter(subpath):
                # 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:
            subpath = ()
            try:
                # empty if mounted under a path in mod_wsgi, for example
                path = request.path_info or slash
            except KeyError:
                # if environ['PATH_INFO'] is just not there
                path = slash
            except UnicodeDecodeError as exc:
                raise URLDecodeError(exc.encoding, exc.object, exc.start, exc.end, exc.reason) \
                    from exc

        if VH_ROOT_KEY in environ:
            # HTTP_X_VHM_ROOT
            vroot_path = decode_path_info(environ[VH_ROOT_KEY])
            vroot_tuple = split_path_info(vroot_path)
            vpath = vroot_path + path
            vroot_idx = len(vroot_tuple) - 1
        else:
            vroot_tuple = ()
            vpath = path
            vroot_idx = -1

        root = self.root
        obj = vroot = root

        request.registry.notify(BeforeTraverseEvent(root, request))

        if vpath == slash:
            # 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:
            # we do dead reckoning here via tuple slicing instead of
            # pushing and popping temporary lists for speed purposes
            # and this hurts readability; apologies
            i = 0
            plus_selector = self.PLUS_SELECTOR
            ns_selector = self.NAMESPACE_SELECTOR
            view_selector = self.VIEW_SELECTOR
            vpath_tuple = split_path_info(vpath)

            for segment in vpath_tuple:
                if obj is not root:
                    request.registry.notify(BeforeTraverseEvent(obj, request))

                if segment == plus_selector:
                    # check for custom namespace called '+'
                    # currently this namespace is used in PyAMS_default_theme package to get
                    # direct access to a given content
                    traverser = queryMultiAdapter((obj, request), ITraversable,
                                                  '+')
                    if traverser is None:
                        raise NotFound()
                    try:
                        obj = traverser.traverse(
                            vpath_tuple[vroot_idx + i + 2],
                            vpath_tuple[vroot_idx + i + 3:])
                    except IndexError as exc:
                        # the "+" namespace traverser is waiting for additional elements from
                        # input URL so a "+" URL not followed by something else is just an error!
                        raise NotFound() from exc
                    else:
                        i += 1
                        return {
                            'context': obj,
                            'view_name':
                            ''.join(vpath_tuple[vroot_idx + i + 2:]),
                            'subpath': vpath_tuple[i + 2:],
                            'traversed': vpath_tuple[:vroot_idx + i + 2],
                            'virtual_root': vroot,
                            'virtual_root_path': vroot_tuple,
                            'root': root
                        }

                elif segment[:2] == ns_selector:
                    # check for namespace prefixed by '++'
                    # when a namespace is detected, named "ITraversable" multi-adapters are
                    # searched for context and request, or for context, sequentially; a NotFound
                    # exception is raised if traverser can't be found, otherwise it's "traverse"
                    # method is called to get new context
                    nss, name = segment[2:].split(ns_selector, 1)
                    traverser = queryMultiAdapter((obj, request), ITraversable,
                                                  nss)
                    if traverser is None:
                        traverser = queryAdapter(obj, ITraversable, nss)
                    if traverser is None:
                        raise NotFound()
                    obj = traverser.traverse(name,
                                             vpath_tuple[vroot_idx + i + 1:])
                    i += 1
                    continue

                elif segment[:2] == view_selector:
                    # check for view name prefixed by '@@'
                    return {
                        'context': obj,
                        '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:
                    getitem = obj.__getitem__
                except AttributeError:
                    return {
                        'context': obj,
                        '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
                    }

                try:
                    next_item = getitem(segment)
                except KeyError:
                    return {
                        'context': obj,
                        '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:
                    vroot = next_item
                obj = next_item
                i += 1

        if obj is not root:
            request.registry.notify(BeforeTraverseEvent(obj, request))

        return {
            'context': obj,
            'view_name': empty,
            'subpath': subpath,
            'traversed': vpath_tuple,
            'virtual_root': vroot,
            'virtual_root_path': vroot_tuple,
            'root': root
        }
    def __call__(self, request):
        environ = request.environ
        matchdict = request.matchdict

        if matchdict is not None:

            path = matchdict.get('traverse', slash) or slash
            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 = '/' + slash.join(path) or slash

            subpath = matchdict.get('subpath', ())
            if not is_nonstr_iter(subpath):
                # 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:
            # this request did not match a route
            subpath = ()
            try:
                # empty if mounted under a path in mod_wsgi, for example
                path = request.path_info or slash
            except KeyError:
                # if environ['PATH_INFO'] is just not there
                path = slash
            except UnicodeDecodeError as e:
                raise URLDecodeError(e.encoding, e.object, e.start, e.end,
                                     e.reason)

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

        ob = vroot = root = LocationProxy(self.root)

        if vpath == slash: # 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:
            # we do dead reckoning here via tuple slicing instead of
            # pushing and popping temporary lists for speed purposes
            # and this hurts readability; apologies
            i = 0
            view_selector = self.VIEW_SELECTOR
            vpath_tuple = split_path_info(vpath)
            for segment in vpath_tuple:
                if segment[:2] == view_selector:
                    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:
                    getitem = ob.__getitem__
                except AttributeError:
                    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}

                try:
                    next = getitem(segment)
                except KeyError:
                    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}
                next = LocationProxy(next, ob, segment)
                if i == vroot_idx: 
                    vroot = next
                ob = next
                i += 1

        return {'context':ob, 'view_name':empty, 'subpath':subpath,
                'traversed':vpath_tuple, 'virtual_root':vroot,
                'virtual_root_path':vroot_tuple, 'root':root}
Exemple #21
0
    def __call__(self, request):
        try:
            environ = request.environ
        except AttributeError:
            # In BFG 1.0 and before, this API expected an environ
            # rather than a request; some bit of code may still be
            # passing us an environ.  If so, deal.
            environ = request
            depwarn = ('Passing an environ dictionary directly to a traverser '
                       'is deprecated in Pyramid 1.1.  Pass a request object '
                       'instead.')
            warnings.warn(depwarn, DeprecationWarning, 2)

        if 'bfg.routes.matchdict' in environ:
            matchdict = environ['bfg.routes.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):
                # 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:
            # 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:
            # HTTP_X_VHM_ROOT
            vroot_path = decode_path_info(environ[VH_ROOT_KEY])
            vroot_tuple = split_path_info(vroot_path)
            vpath = vroot_path + path  # both will be unicode or asciistr
            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:
            # we do dead reckoning here via tuple slicing instead of
            # pushing and popping temporary lists for speed purposes
            # and this hurts readability; apologies
            i = 0
            view_selector = self.VIEW_SELECTOR
            vpath_tuple = split_path_info(vpath)
            for segment in vpath_tuple:
                if segment[:2] == view_selector:
                    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:
                    # CHANGED: try to use adaper to get the __getitem__ method
                    #try local registry
                    registry = get_current_registry()
                    adapter = registry.queryAdapter(ob, IChildsDictLike)
                    #try global registry
                    if not adapter:
                        adapter = zope.component.queryAdapter(ob,\
                                                        IChildsDictLike)
                    #else use the object directly
                    if not adapter:
                        adapter = ob
                    getitem = adapter.__getitem__
                except AttributeError:
                    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
                    }

                try:
                    next = getitem(segment)
                except KeyError:
                    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:
                    vroot = next
                ob = next
                i += 1

        return {
            'context': ob,
            'view_name': empty,
            'subpath': subpath,
            'traversed': vpath_tuple,
            'virtual_root': vroot,
            'virtual_root_path': vroot_tuple,
            'root': root
        }
Exemple #22
0
    def __call__(self, request):
        environ = request.environ
        matchdict = request.matchdict

        if matchdict is not None:

            path = matchdict.get('traverse', SLASH) or SLASH
            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 = '/' + SLASH.join(path) or SLASH

            subpath = matchdict.get('subpath', ())
            if not is_nonstr_iter(subpath):
                # 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:
            # this request did not match a route
            subpath = ()
            try:
                # empty if mounted under a path in mod_wsgi, for example
                path = request.path_info or SLASH
            except KeyError:
                # if environ['PATH_INFO'] is just not there
                path = SLASH
            except UnicodeDecodeError as e:
                raise URLDecodeError(e.encoding, e.object, e.start, e.end,
                                     e.reason)

        if VH_ROOT_KEY in environ:
            # HTTP_X_VHM_ROOT
            vroot_path = decode_path_info(environ[VH_ROOT_KEY])
            vroot_tuple = split_path_info(vroot_path)
            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 == SLASH:
            vpath_tuple = ()
        else:
            i = 0
            view_selector = self.VIEW_SELECTOR
            vpath_tuple = split_path_info(vpath)
            return traverse(
                i,
                ob,
                view_selector,
                vpath_tuple,
                vroot_idx,
                vroot,
                vroot_tuple,
                root,
                subpath,
            )

        return {
            'context': ob,
            'view_name': "",
            'subpath': subpath,
            'traversed': vpath_tuple,
            'virtual_root': vroot,
            'virtual_root_path': vroot_tuple,
            'root': root
        }
    def __call__(self, request):
        try:
            environ = request.environ
        except AttributeError:
            # In BFG 1.0 and before, this API expected an environ
            # rather than a request; some bit of code may still be
            # passing us an environ.  If so, deal.
            environ = request
            depwarn = ('Passing an environ dictionary directly to a traverser '
                       'is deprecated in Pyramid 1.1.  Pass a request object '
                       'instead.')
            warnings.warn(depwarn, DeprecationWarning, 2)

        if 'bfg.routes.matchdict' in environ:
            matchdict = environ['bfg.routes.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):
                # 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:
            # 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:
            # HTTP_X_VHM_ROOT
            vroot_path = decode_path_info(environ[VH_ROOT_KEY])
            vroot_tuple = split_path_info(vroot_path)
            vpath = vroot_path + path  # both will be unicode or asciistr
            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:
            # we do dead reckoning here via tuple slicing instead of
            # pushing and popping temporary lists for speed purposes
            # and this hurts readability; apologies
            i = 0
            view_selector = self.VIEW_SELECTOR
            vpath_tuple = split_path_info(vpath)
            for segment in vpath_tuple:
                if segment[:2] == view_selector:
                    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:
                    # CHANGED: try to use adaper to get the __getitem__ method
                    #try local registry
                    registry = get_current_registry()
                    adapter = registry.queryAdapter(ob, IChildsDictLike)
                    #try global registry
                    if not adapter:
                        adapter = zope.component.queryAdapter(ob,\
                                                        IChildsDictLike)
                    #else use the object directly
                    if not adapter:
                        adapter = ob
                    getitem = adapter.__getitem__
                except AttributeError:
                    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}

                try:
                    next = getitem(segment)
                except KeyError:
                    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:
                    vroot = next
                ob = next
                i += 1

        return {'context': ob, 'view_name': empty, 'subpath': subpath,
                'traversed': vpath_tuple, 'virtual_root': vroot,
                'virtual_root_path': vroot_tuple, 'root': root}
Exemple #24
0
    def es_tween(request):
        if request.method not in ('GET', 'HEAD'):
            return handler(request)

        if request.params.get('datastore',
                              default_datastore) != 'elasticsearch':
            return handler(request)

        frame = request.params.get('frame', 'page')
        if frame not in (
                'object',
                'embedded',
                'page',
        ):
            return handler(request)

        # Normalize path
        path_tuple = split_path_info(request.path_info)
        path = _join_path_tuple(('', ) + path_tuple)

        if path in ignore or path.startswith('/static/'):
            return handler(request)

        query = {'filter': {'term': {'paths': path}}, 'version': True}
        data = es.search(index='encoded', body=query)
        hits = data['hits']['hits']
        if len(hits) != 1:
            return handler(request)

        source = hits[0]['_source']
        edits = dict.get(request.session, 'edits', None)
        if edits is not None:
            version = hits[0]['_version']
            linked_uuids = set(source['linked_uuids'])
            embedded_uuids = set(source['embedded_uuids'])
            for xid, updated, linked in edits:
                if xid < version:
                    continue
                if not embedded_uuids.isdisjoint(updated):
                    return handler(request)
                if not linked_uuids.isdisjoint(linked):
                    return handler(request)

        allowed = set(source['principals_allowed']['view'])
        if allowed.isdisjoint(request.effective_principals):
            raise HTTPForbidden()

        if frame == 'page':
            properties = source['embedded']
            request.root = registry.getUtility(IRootFactory)(request)
            collection = request.root.get(properties['@type'][0])
            rendering_val = collection.Item.expand_page(request, properties)

            # Add actions
            ns = {
                'has_permission': es_permission_checker(source, request),
                'item_uri': source['object']['@id'],
                'item_type': collection.item_type,
            }
            actions = calculate_properties(collection.Item,
                                           request,
                                           ns,
                                           category='action')
            if actions:
                rendering_val['actions'] = list(actions.values())

            if ns['has_permission']('audit'):
                rendering_val['audit'] = source['audit']

        else:
            rendering_val = source[frame]
        return render_to_response(None, rendering_val, request)
Exemple #25
0
    def __call__(self, request):
        environ = request.environ
        matchdict = request.matchdict

        if matchdict is not None:

            path = matchdict.get('traverse', SLASH) or SLASH
            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 = '/' + SLASH.join(path) or SLASH

            subpath = matchdict.get('subpath', ())
            if not is_nonstr_iter(subpath):
                # 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:
            # this request did not match a route
            subpath = ()
            try:
                # empty if mounted under a path in mod_wsgi, for example
                path = request.path_info or SLASH
            except KeyError:
                # if environ['PATH_INFO'] is just not there
                path = SLASH
            except UnicodeDecodeError as e:
                raise URLDecodeError(e.encoding, e.object, e.start, e.end,
                                     e.reason)

        if VH_ROOT_KEY in environ:
            # HTTP_X_VHM_ROOT
            vroot_path = decode_path_info(environ[VH_ROOT_KEY])
            vroot_tuple = split_path_info(vroot_path)
            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 == SLASH:
            vpath_tuple = ()
        else:
            i = 0
            view_selector = self.VIEW_SELECTOR
            vpath_tuple = split_path_info(vpath)
            return traverse(
                i,
                ob,
                view_selector,
                vpath_tuple,
                vroot_idx,
                vroot,
                vroot_tuple,
                root,
                subpath,
            )

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