Exemplo n.º 1
0
    def __before_publishing_traverse__(self, arg1, arg2=None):
        """ Pre-traversal hook.
        """
        # XXX hack around a bug(?) in BeforeTraverse.MultiHook
        REQUEST = arg2 or arg1

        notify(BeforeTraverseEvent(self, REQUEST))

        if REQUEST['REQUEST_METHOD'] not in ('GET', 'POST'):
            return

        stack = REQUEST['TraversalRequestNameStack']
        key = stack and stack[-1] or '(Default)'

        # if there's a Zope3-style default view name set and the
        # corresponding view exists, take that in favour of the FTI's
        # default view
        if key == '(Default)':
            viewname = queryDefaultViewName(self, REQUEST)
            if (viewname and queryMultiAdapter(
                (self, REQUEST), name=viewname) is not None):
                stack.append(viewname)
                REQUEST._hacked_path = 1
                return

        ti = self.getTypeInfo()
        method_id = ti and ti.queryMethodID(key, context=self)
        if method_id:
            if key != '(Default)':
                stack.pop()
            if method_id != '(Default)':
                stack.append(method_id)
            REQUEST._hacked_path = 1
Exemplo n.º 2
0
    def __before_publishing_traverse__(self, arg1, arg2=None):
        """ Pre-traversal hook.
        """
        # XXX hack around a bug(?) in BeforeTraverse.MultiHook
        REQUEST = arg2 or arg1

        if REQUEST['REQUEST_METHOD'] not in ('GET', 'POST'):
            return

        stack = REQUEST['TraversalRequestNameStack']
        key = stack and stack[-1] or '(Default)'

        # if there's a Zope3-style default view name set and the
        # corresponding view exists, take that in favour of the FTI's
        # default view
        if key == '(Default)':
            viewname = queryDefaultViewName(self, REQUEST)
            if (viewname and
                queryMultiAdapter((self, REQUEST), name=viewname) is not None):
                stack.append(viewname)
                REQUEST._hacked_path = 1
                return

        ti = self.getTypeInfo()
        method_id = ti and ti.queryMethodID(key, context=self)
        if method_id:
            if key != '(Default)':
                stack.pop()
            if method_id != '(Default)':
                stack.append(method_id)
            REQUEST._hacked_path = 1
Exemplo n.º 3
0
    def handleException(self, object, request, exc_info, retry_allowed=True):
        transaction.abort()
        # TODO handle Retry, ConflictError, etc.
        # TODO handle logging
        exception_type, exception, traceback = exc_info

        loc = object
        if Acquisition.aq_parent(object) is None:
            # Try to get an object, since we apparently have a method
            # Note: We are guaranteed that an object has a location,
            # so just getting the instance the method belongs to is
            # sufficient.
            loc = getattr(loc, 'im_self', loc)
            loc = getattr(loc, '__self__', loc)

        # Give the exception instance its location and look up the
        # view.
        exception = LocationProxy(exception, loc, '')
        name = queryDefaultViewName(exception, request)
        if name is not None:
            # TODO annotate the transaction
            view = queryMultiAdapter((exception, request), name=name)
            if view is not None:
                # XXX should we use mapply here?
                body = self.callObject(request, view)
                request.response.setResult(body)
                transaction.commit()
            else:
                # This is the last resort. We shouldn't get here, but
                # in case we do, we have to set the result to something.
                request.response.setStatus(500)
                request.response.setResult('An error occurred.')
Exemplo n.º 4
0
    def add_container_menu_items(self, context, container):
        request = self.request
        # add a menu item for each user workspace, if we are in an
        # IWorkspaceSectionLayer
        # !+ if user is logged in or if request.layer_data

        if (interfaces.IWorkspaceSectionLayer.providedBy(request)
                or interfaces.IWorkspaceSchedulingSectionLayer.providedBy(
                    request)):
            try:
                workspaces = IAnnotations(request)["layer_data"].get(
                    "workspaces")
            except:
                workspaces = []
            log.info("%s got user workspaces: %s" % (self, workspaces))
            base_url_path = "/workspace"
            for workspace in workspaces:
                log.info("appending menu item for user workspace: %s" %
                         str(workspace))
                self.items.append(
                    url.get_menu_item_descriptor(
                        workspace.full_name,
                        pos_action_in_url(
                            "/workspace/obj-%s" % workspace.group_id,
                            request.getURL()), base_url_path,
                        "obj-%s" % workspace.group_id))

        _url = url.absoluteURL(container, request)

        if IReadContainer.providedBy(container):
            #XXX should be the same in all containers ?
            container = proxy.removeSecurityProxy(container)
            for name, item in container.items():
                if context is None:
                    selected = False
                else:
                    selected = url.same_path_names(context.__name__, name)
                item = proxy.removeSecurityProxy(item)
                if IDCDescriptiveProperties.providedBy(item):
                    title = item.title
                else:
                    props = IDCDescriptiveProperties(item)
                    title = props.title
                # only items with valid title
                if title is not None:
                    self.items.append(
                        url.get_menu_item_descriptor(title, selected, _url,
                                                     name))
        default_view_name = queryDefaultViewName(container, self.request)
        default_view = component.queryMultiAdapter((container, self.request),
                                                   name=default_view_name)
        if hasattr(default_view, "title") and default_view.title is not None:
            self.items.insert(
                0,
                url.get_menu_item_descriptor(
                    default_view.title,
                    sameProxiedObjects(container, self.context), _url))
Exemplo n.º 5
0
    def add_container_menu_items(self, context, container):
        request = self.request
        # add a menu item for each user workspace, if we are in an
        # IWorkspaceSectionLayer
        # !+ if user is logged in or if request.layer_data
        if interfaces.IWorkspaceSectionLayer.providedBy(request):
            try:
                workspaces = IAnnotations(request)["layer_data"].get(
                    "workspaces")
            except:
                workspaces = []
            log.info("%s got user workspaces: %s" % (self, workspaces))
            base_url_path = "/workspace"
            for workspace in workspaces:
                log.info("appending menu item for user workspace: %s" %
                         str(workspace))
                self.items.append(
                    url.get_menu_item_descriptor(
                        workspace.full_name,
                        pos_action_in_url(
                            "/workspace/obj-%s" % workspace.group_id,
                            request.getURL()), base_url_path,
                        "obj-%s" % workspace.group_id))

        _url = url.absoluteURL(container, request)

        if IReadContainer.providedBy(container):
            #XXX should be the same in all containers ?
            container = proxy.removeSecurityProxy(container)
            for name, item in container.items():
                if context is None:
                    selected = False
                else:
                    selected = url.same_path_names(context.__name__, name)
                item = proxy.removeSecurityProxy(item)
                if IDCDescriptiveProperties.providedBy(item):
                    title = item.title
                else:
                    props = IDCDescriptiveProperties(item)
                    title = props.title
                # only items with valid title
                if title is not None:
                    self.items.append(
                        url.get_menu_item_descriptor(title, selected, _url,
                                                     name))
        default_view_name = queryDefaultViewName(container, self.request)
        default_view = component.queryMultiAdapter((container, self.request),
                                                   name=default_view_name)
        if hasattr(default_view, "title") and default_view.title is not None:
            self.items.insert(
                0,
                url.get_menu_item_descriptor(
                    default_view.title,
                    sameProxiedObjects(container, self.context), _url))
Exemplo n.º 6
0
 def browserDefault(self, request):
     if hasattr(self.context, '__browser_default__'):
         return self.context.__browser_default__(request)
     # Zope 3.2 still uses IDefaultView name when it
     # registeres default views, even though it's
     # deprecated. So we handle that here:
     default_name = queryDefaultViewName(self.context, request)
     if default_name is not None:
         # Adding '@@' here forces this to be a view.
         # A neater solution might be desireable.
         return self.context, ('@@' + default_name, )
     return self.context, ()
Exemplo n.º 7
0
    def browserDefault(self, request):
        # Support for old __browser_default__
        if hasattr(self.context, '__browser_default__'):
            return self.context.__browser_default__(request)

        # If there's a default view name set and the view for this
        # default view exists, we'll use that.
        default_name = queryDefaultViewName(self.context, request)
        if (default_name is not None and queryMultiAdapter(
            (self.context, request), name=default_name) is not None):
            # Adding '@@' here forces this to be a view.
            # A neater solution might be desireable.
            return self.context, ('@@' + default_name, )

        # Otherwise it's index_html...
        if getattr(self.context, 'index_html', None) is not None:
            return self.context, ('index_html', )

        # ... before __call__.
        return self.context, ()
Exemplo n.º 8
0
 def add_zcml_menu_items(self, container):
     """Add the list of ZCML menu items (if any) for this top-level 
     container. Top-level section given by container may define a menu 
     in ZCML with naming convention: <container_name>_navigation. 
     """
     # !+ turn this into a utility
     zcml_menu_name_template = "%s_navigation"
     try:
         menu_name = zcml_menu_name_template % container.__name__
         menu = component.getUtility(IBrowserMenu, name=menu_name)
         items = menu.getMenuItems(container, self.request)
     except (Exception, ):
         debug.log_exc(sys.exc_info(), log_handler=log.debug)
         return []
     # OK, do any necessary post-processing of each menu item
     local_url = url.absoluteURL(container, self.request)
     site_url = url.absoluteURL(getSite(), self.request)
     request_url = self.request.getURL()
     default_view_name = queryDefaultViewName(container, self.request)
     selection = None
     for item in sorted(items,
                        key=lambda item: item['action'],
                        reverse=True):
         action = item['action']
         if default_view_name == action.lstrip('@@'):
             _url = local_url
             if selection is None:
                 selected = sameProxiedObjects(container, self.context)
         else:
             _url = make_absolute(action, local_url, site_url)
             if selection is None:
                 selected = pos_action_in_url(action, request_url)
         item['url'] = _url
         item['selected'] = selected and u'selected' or u''
         if selected:
             # self is marker
             selection = self
             selected = False
         self.items.append(item)
Exemplo n.º 9
0
 def add_zcml_menu_items(self, container):
     """Add the list of ZCML menu items (if any) for this top-level 
     container. Top-level section given by container may define a menu 
     in ZCML with naming convention: <container_name>_navigation. 
     """
     # !+ turn this into a utility
     zcml_menu_name_template = "%s_navigation"
     try:
         menu_name = zcml_menu_name_template % container.__name__
         menu = component.getUtility(IBrowserMenu, name=menu_name)
         items = menu.getMenuItems(container, self.request)
     except (Exception, ):
         debug.log_exc(sys.exc_info(), log_handler=log.debug)
         return []
     # OK, do any necessary post-processing of each menu item
     local_url = url.absoluteURL(container, self.request)
     site_url = url.absoluteURL(getSite(), self.request)
     request_url = self.request.getURL()
     default_view_name = queryDefaultViewName(container, self.request)
     selection = None
     for item in sorted(
             items, key=lambda item: item['action'], reverse=True):
         action = item['action']
         if default_view_name == action.lstrip('@@'):
             _url = local_url
             if selection is None:
                 selected = sameProxiedObjects(container, self.context)
         else:
             _url = make_absolute(action, local_url, site_url)
             if selection is None:
                 selected = pos_action_in_url(action, request_url)
         item['url'] = _url
         item['selected'] = selected and u'selected' or u''
         if selected:
             # self is marker
             selection = self
             selected = False
         self.items.append(item)
Exemplo n.º 10
0
def handleException(self, object, request, exc_info, retry_allowed=True):
    #orig = removeAllProxies(object)

    transaction.abort()

    if retry_allowed and isinstance(exc_info[1], Retry):
        raise

    if retry_allowed and isinstance(exc_info[1], ConflictError):
        tryToLogWarning(
            'ZopePublication',
            'Competing writes/reads at %s: %s'
            % (request.get('PATH_INFO', '???'),
               exc_info[1],
               ),
            )
        raise Retry(exc_info)

    self._logErrorWithErrorReportingUtility(object, request, exc_info)

    response = request.response
    response.reset()
    exception = None
    legacy_exception = not isinstance(exc_info[1], Exception)
    if legacy_exception:
        response.handleException(exc_info)
        if isinstance(exc_info[1], str):
            tryToLogWarning(
                'Publisher received a legacy string exception: %s.'
                ' This will be handled by the request.' %
                exc_info[1])
        else:
            tryToLogWarning(
                'Publisher received a legacy classic class exception: %s.'
                ' This will be handled by the request.' %
                exc_info[1].__class__)
    else:
        self.beginErrorHandlingTransaction(
            request, object, 'application error-handling')
        view = None
        try:
            loc = object
            if not hasattr(object, '__parent__'):
                loc = removeSecurityProxy(object)
                loc = getattr(loc, 'im_self', loc)
                loc = getattr(loc, '__self__', loc)
                loc = ProxyFactory(loc)

            exception = LocationProxy(exc_info[1], loc, '')
            name = queryDefaultViewName(exception, request)
            if name is not None:
                view = queryMultiAdapter(
                    (exception, request), name=name)
        except:
            tryToLogException('Exception while getting view on exception')

        if view is not None:
            try:
                body = mapply(view, (), request)
                response.setResult(body)
                transaction.commit()
                if (ISystemErrorView.providedBy(view)
                    and view.isSystemError()):
                    try:
                        raise exc_info[0], exc_info[1], exc_info[2]
                    except:
                        logging.getLogger('SiteError').exception(
                            str(request.URL),
                            )
            except ReadOnlyError:
                transaction.abort()
            except:
                tryToLogException('Exception while rendering view on exception')
                self._logErrorWithErrorReportingUtility(
                    object, request, sys.exc_info())
                view = None

        if view is None:
            response.handleException(exc_info)
            transaction.abort()
        try:
            adapter = IExceptionSideEffects(exception, None)
        except:
            tryToLogException(
                'Exception while getting IExceptionSideEffects adapter')
            adapter = None

        if adapter is not None:
            self.beginErrorHandlingTransaction(
                request, object, 'application error-handling side-effect')
            try:
                adapter(object, request, exc_info)
                transaction.commit()
            except ReadOnlyError:
                transaction.abort()
            except:
                tryToLogException('Exception while calling'
                    ' IExceptionSideEffects adapter')
                transaction.abort()
Exemplo n.º 11
0
def queryDefaultView(context, request):
    name = queryDefaultViewName(context, request, None)
    if name:
        view = queryMultiAdapter((context, request), name=name)
        if IPagelet.providedBy(view):
            return view
Exemplo n.º 12
0
    def handleException(self, object, request, exc_info, retry_allowed=True):
        # This transaction had an exception that reached the publisher.
        # It must definitely be aborted.
        transaction.abort()

        # Reraise Retry exceptions for the publisher to deal with.
        if retry_allowed and isinstance(exc_info[1], Retry):
            raise

        # Convert ConflictErrors to Retry exceptions.
        if retry_allowed and isinstance(exc_info[1], ConflictError):
            tryToLogWarning(
                'ZopePublication',
                'Competing writes/reads at %s: %s' % (
                    request.get('PATH_INFO', '???'),
                    exc_info[1],
                ),
            )
            raise Retry(exc_info)
        # Are there any reasons why we'd want to let application-level error
        # handling determine whether a retry is allowed or not?
        # Assume not for now.

        # Record the error with the ErrorReportingUtility
        self._logErrorWithErrorReportingUtility(object, request, exc_info)

        response = request.response
        response.reset()
        exception = None
        legacy_exception = not isinstance(exc_info[1], Exception)
        if legacy_exception:
            response.handleException(exc_info)
            if isinstance(exc_info[1], str):
                tryToLogWarning(
                    'Publisher received a legacy string exception: %s.'
                    ' This will be handled by the request.' % exc_info[1])
            else:
                tryToLogWarning(
                    'Publisher received a legacy classic class exception: %s.'
                    ' This will be handled by the request.' %
                    exc_info[1].__class__)
        else:
            # We definitely have an Exception
            # Set the request body, and abort the current transaction.
            self.beginErrorHandlingTransaction(request, object,
                                               'application error-handling')
            view = None
            try:
                # We need to get a location, because some template content of
                # the exception view might require one.
                #
                # The object might not have a parent, because it might be a
                # method. If we don't have a `__parent__` attribute but have
                # an im_self or a __self__, use it.
                loc = object
                if not hasattr(object, '__parent__'):
                    loc = removeSecurityProxy(object)
                    # Try to get an object, since we apparently have a method
                    # Note: We are guaranteed that an object has a location,
                    # so just getting the instance the method belongs to is
                    # sufficient.
                    loc = getattr(loc, 'im_self', loc)
                    loc = getattr(loc, '__self__', loc)
                    # Protect the location with a security proxy
                    loc = ProxyFactory(loc)

                # Give the exception instance its location and look up the
                # view.
                exception = LocationProxy(exc_info[1], loc, '')
                name = queryDefaultViewName(exception, request)
                if name is not None:
                    view = zope.component.queryMultiAdapter(
                        (exception, request), name=name)
            except:
                # Problem getting a view for this exception. Log an error.
                tryToLogException('Exception while getting view on exception')

            if view is not None:
                try:
                    # We use mapply instead of self.callObject here
                    # because we don't want to pass positional
                    # arguments.  The positional arguments were meant
                    # for the published object, not an exception view.
                    body = mapply(view, (), request)
                    response.setResult(body)
                    transaction.commit()
                    if (ISystemErrorView.providedBy(view)
                            and view.isSystemError()):
                        # Got a system error, want to log the error

                        # Lame hack to get around logging missfeature
                        # that is fixed in Python 2.4
                        try:
                            raise exc_info[0], exc_info[1], exc_info[2]
                        except:
                            logging.getLogger('SiteError').exception(
                                str(request.URL), )

                except:
                    # Problem rendering the view for this exception.
                    # Log an error.
                    tryToLogException(
                        'Exception while rendering view on exception')

                    # Record the error with the ErrorReportingUtility
                    self._logErrorWithErrorReportingUtility(
                        object, request, sys.exc_info())

                    view = None

            if view is None:
                # Either the view was not found, or view was set to None
                # because the view couldn't be rendered. In either case,
                # we let the request handle it.
                response.handleException(exc_info)
                transaction.abort()

            # See if there's an IExceptionSideEffects adapter for the
            # exception
            try:
                adapter = IExceptionSideEffects(exception, None)
            except:
                tryToLogException(
                    'Exception while getting IExceptionSideEffects adapter')
                adapter = None

            if adapter is not None:
                self.beginErrorHandlingTransaction(
                    request, object, 'application error-handling side-effect')
                try:
                    # Although request is passed in here, it should be
                    # considered read-only.
                    adapter(object, request, exc_info)
                    transaction.commit()
                except:
                    tryToLogException('Exception while calling'
                                      ' IExceptionSideEffects adapter')
                    transaction.abort()
Exemplo n.º 13
0
 def isAvailable(self):
     name = queryDefaultViewName(self.context, self.request, None)
     if name == self.wizard.__name__:
         return False
     else:
         return super(ContentViewStep, self).isAvailable()