コード例 #1
0
ファイル: codebrowser.py プロジェクト: Open-Source-GIS/RESTx
    def __process_get(self, is_code, prefix):
        """
        Respond to GET requests.
        
        When someone sends GET requests to the code then
        they want to browse the available code options.

        Same with spezialiced code.

        @param is_code:     Indicates whether this is a request for un-specialized code.
        @type is_code:      boolean

        @param prefix:      The prefix for this type of request.
        @type prefix:       string
        
        @return:  HTTP return structure.
        @rtype:   Result

        """
        # It's the responsibility of the browser class to provide breadcrumbs
        if is_code:
            dirname = "Code"
        else:
            dirname = "Specialized"
        self.breadcrumbs = [ ("Home", "/"), (dirname, prefix) ]

        if self.request.getRequestPath() == prefix:
            #
            # Just show the home page of the code browser (list of all installed (specialized) code)
            #
            if is_code:
                # Data to be taken from the code
                data = dict()
                for name in get_component_names():
                    if name[0] not in EXCLUDE_PREFIXES:
                        # component_info is a tuple, which contains the component class and its manifest info
                        component = make_component(name)
                        data[name] = { "uri" : Url(component.getCodeUri()), "desc" : component.getDesc() }
                """
                data = dict([ (name, { "uri" : Url(component_class().getCodeUri()), "desc" : component_class().getDesc() } ) \
                                    for (name, (component_class, component_config)) in get_code_map().items() \
                                        if name[0] not in EXCLUDE_PREFIXES ])
                """
            else:
                # We are looking for partial resources
                data = listResources(partials=True)
        else:
            # Path elements (the known code prefix is stripped off)
            path_elems = self.request.getRequestPath()[len(prefix):].split("/")[1:]
            if is_code:
                # We are referencing actual components here
                component_name  = path_elems[0]   # This should be the name of the code element
                component_path  = self.request.getRequestPath()
            else:
                # We are looking at a partial resource. Therefore, we need to load
                # that resource and then get the code URI from it.
                specialized_code_name = path_elems[0]
                specialized_code      = retrieveResourceFromStorage(getResourceUri(specialized_code_name, is_partial=True), only_public=False, is_partial=True)
                if not specialized_code:
                    return Result.notFound("Cannot find specialized component resource '%s'" % specialized_code_name)
                component_path        = specialized_code["private"]["code_uri"]
            
            # Instantiate the component
            component = getComponentObjectFromPath(component_path)
            if not component:
                return Result.notFound("Unknown component")
            component_home_uri = component.getCodeUri()

            if is_code:
                self.breadcrumbs.append((component_name, component_home_uri))
            else:
                self.breadcrumbs.append((specialized_code_name, specialized_code["public"]["uri"]))

            if len(path_elems) == 1:
                #
                # No sub-detail specified: We want meta info about a code segment (component)
                #
                data = component.getMetaData()

                #
                # If this is based on a specialized component then we need to overwrite some
                # of the component's meta data with the info from the specialized component
                # definition.
                #
                if not is_code:
                    data = specializedOverwrite(data, specialized_code)

                data = languageStructToPython(component, data)
                if is_code:
                    qs = ""
                    cname = component_name
                else:
                    qs = "?specialized=y"
                    cname = specialized_code_name
                self.context_header.append(("[ Create resource ]", settings.PREFIX_RESOURCE+"/_createResourceForm/form/"+cname+qs, ""))  #, "target=_blank"))
            else:
                #
                # Some sub-detail of the requested component was requested
                #
                sub_name = path_elems[1]
                if sub_name == "doc":
                    data       = component.getDocs()
                    self.breadcrumbs.append(("Doc", component_home_uri + "/doc"))
                else:
                    return Result.notFound("Unknown code detail")
                
        return Result.ok(data)
コード例 #2
0
ファイル: resourcebrowser.py プロジェクト: vdreamakitex/RESTx
    def process(self):
        """
        Process the request.
     
        @return:  HTTP result structure.
        @rtype:   Result
        
        """
        method = self.request.getRequestMethod()

        if method == HTTP.GET_METHOD:
            # It's the responsibility of the browser class to provide breadcrumbs
            self.breadcrumbs = [("Home", "/"),
                                ("Resource", settings.PREFIX_RESOURCE)]

        if self.request.getRequestPath() == settings.PREFIX_RESOURCE:
            #
            # Request to the base URL of all resources (listing resources)
            #
            if method == HTTP.GET_METHOD:
                #
                # List all the resources
                #
                return Result.ok(listResources())
            else:
                raise RestxMethodNotAllowedException()

        else:
            # Path elements (the known resource prefix is stripped off)
            path = self.request.getRequestPath()[len(settings.PREFIX_RESOURCE
                                                     ):]
            path_elems = path.split("/")[1:]
            resource_name = path_elems[
                0]  # This should be the name of the resource base

            # If the path ends with a '/' then there might be an empty element at the end,
            # which we can remove.
            if not path_elems[-1:][0]:
                path_elems.pop()

            # Before calling delete on a resource, we have to make sure that this DELETE
            # is just for the resource itself, not a DELETE to some of the sub-services.
            # If it's just for the resource then there will be only one path element (the
            # resource name).
            if method == HTTP.DELETE_METHOD and len(path_elems) == 1:
                try:
                    deleteResourceFromStorage(self.request.getRequestPath())
                    return Result.ok("Resource deleted")
                except RestxException, e:
                    return Result(e.code, str(e))

            # Get the public representation of the resource
            rinfo = _getResourceDetails(resource_name)
            complete_resource_def = rinfo['complete_resource_def']
            resource_home_uri = rinfo['resource_home_uri']
            public_resource_def = rinfo['public_resource_def']
            code_uri = rinfo['code_uri']
            component = rinfo['component']
            services = public_resource_def['services']
            public_resource_def['uri'] = Url(public_resource_def['uri'])

            if method == HTTP.GET_METHOD:
                self.breadcrumbs.append((resource_name, resource_home_uri))

            # Was there more to access?
            if len(path_elems) > 1:
                #
                # Some sub-service of the component was requested. This means
                # we actually need to pass the parameters to the component
                # and call this service function.
                #

                # This service has some possible runtime parameters defined.
                runtime_param_dict = get_request_query_dict(self.request)

                service_name = path_elems[1]
                positional_params = path_elems[2:]
                input = self.request.getRequestBody()
                try:
                    http_method = __HTTP_METHOD_LOOKUP.get(
                        self.request.getRequestMethod().upper(),
                        HttpMethod.UNKNOWN)
                    result = _accessComponentService(
                        component, services, complete_resource_def,
                        resource_name, service_name, positional_params,
                        runtime_param_dict, input, self.request, http_method)
                except RestxException, e:
                    result = Result(e.code, e.msg)
                except Exception, e:
                    # The service code threw an exception. We need to log that and return a
                    # normal error back to the user.
                    print traceback.format_exc()
                    log("Exception in component for service '%s': %s" %
                        (service_name, str(e)),
                        facility=LOGF_COMPONENTS)
                    result = Result.internalServerError(
                        "Internal server error. Details have been logged...")
コード例 #3
0
ファイル: resourcebrowser.py プロジェクト: vdreamakitex/RESTx
    def process(self):
        """
        Process the request.
     
        @return:  HTTP result structure.
        @rtype:   Result
        
        """
        method = self.request.getRequestMethod()

        if method == HTTP.GET_METHOD:
            # It's the responsibility of the browser class to provide breadcrumbs
            self.breadcrumbs = [ ("Home", "/"), ("Resource", settings.PREFIX_RESOURCE) ]

        if self.request.getRequestPath() == settings.PREFIX_RESOURCE:
            #
            # Request to the base URL of all resources (listing resources)
            #
            if method == HTTP.GET_METHOD:
                #
                # List all the resources
                #
                return Result.ok(listResources())
            else:
                raise RestxMethodNotAllowedException()
            
        else:
            # Path elements (the known resource prefix is stripped off)
            path          = self.request.getRequestPath()[len(settings.PREFIX_RESOURCE):]
            path_elems    = path.split("/")[1:]
            resource_name = path_elems[0]   # This should be the name of the resource base

            # If the path ends with a '/' then there might be an empty element at the end,
            # which we can remove.
            if not path_elems[-1:][0]:
                path_elems.pop()
            
            # Before calling delete on a resource, we have to make sure that this DELETE
            # is just for the resource itself, not a DELETE to some of the sub-services.
            # If it's just for the resource then there will be only one path element (the
            # resource name).
            if method == HTTP.DELETE_METHOD  and  len(path_elems) == 1:
                try:
                    deleteResourceFromStorage(self.request.getRequestPath())
                    return Result.ok("Resource deleted")
                except RestxException, e:
                    return Result(e.code, str(e))

            # Get the public representation of the resource
            rinfo = _getResourceDetails(resource_name)
            complete_resource_def = rinfo['complete_resource_def']
            resource_home_uri     = rinfo['resource_home_uri']
            public_resource_def   = rinfo['public_resource_def']
            code_uri              = rinfo['code_uri']
            component             = rinfo['component']
            services              = public_resource_def['services']
            public_resource_def['uri'] = Url(public_resource_def['uri'])

            if method == HTTP.GET_METHOD:
                self.breadcrumbs.append((resource_name, resource_home_uri))

            # Was there more to access?
            if len(path_elems) > 1:
                #
                # Some sub-service of the component was requested. This means
                # we actually need to pass the parameters to the component
                # and call this service function.
                #
                
                # This service has some possible runtime parameters defined.
                runtime_param_dict = get_request_query_dict(self.request)

                service_name      = path_elems[1]
                positional_params = path_elems[2:]
                input             = self.request.getRequestBody()
                try:
                    http_method = __HTTP_METHOD_LOOKUP.get(self.request.getRequestMethod().upper(), HttpMethod.UNKNOWN)
                    result      = _accessComponentService(component, services, complete_resource_def,
                                                          resource_name, service_name, positional_params,
                                                          runtime_param_dict, input, self.request,
                                                          http_method)
                except RestxException, e:
                    result = Result(e.code, e.msg)
                except Exception, e:
                    # The service code threw an exception. We need to log that and return a
                    # normal error back to the user.
                    print traceback.format_exc()
                    log("Exception in component for service '%s': %s" % (service_name, str(e)), facility=LOGF_COMPONENTS)
                    result = Result.internalServerError("Internal server error. Details have been logged...")
コード例 #4
0
    def process(self):
        """
        Process the request.
     
        @return:  HTTP result structure.
        @rtype:   Result
        
        """
        method = self.request.getRequestMethod()

        if method == HTTP.GET_METHOD:
            # It's the responsibility of the browser class to provide breadcrumbs
            self.breadcrumbs = [ ("Home", "/"), ("Resource", settings.PREFIX_RESOURCE) ]

        if self.request.getRequestPath() == settings.PREFIX_RESOURCE:
            #
            # Request to the base URL of all resources (listing resources)
            #
            if method == HTTP.GET_METHOD:
                #
                # List all the resources
                #
                return Result.ok(listResources())
            else:
                raise RestxMethodNotAllowedException()
            
        else:
            # Path elements (the known resource prefix is stripped off)
            path          = self.request.getRequestPath()[len(settings.PREFIX_RESOURCE):]
            path_elems    = path.split("/")[1:]
            resource_name = path_elems[0]   # This should be the name of the resource base

            # If the path ends with a '/' then there might be an empty element at the end,
            # which we can remove.
            if not path_elems[-1:][0]:
                path_elems.pop()
            
            # Before calling delete on a resource, we have to make sure that this DELETE
            # is just for the resource itself, not a DELETE to some of the sub-services.
            # If it's just for the resource then there will be only one path element (the
            # resource name).
            if method == HTTP.DELETE_METHOD  and  len(path_elems) == 1:
                try:
                    deleteResourceFromStorage(self.request.getRequestPath())
                    return Result.ok("Resource deleted")
                except RestxException, e:
                    return Result(e.code, e.msg)

            # Get the public representation of the resource
            rinfo = _getResourceDetails(resource_name)
            if not rinfo:
                return Result.notFound("Unknown component")
            complete_resource_def = rinfo['complete_resource_def']
            resource_home_uri     = rinfo['resource_home_uri']
            public_resource_def   = rinfo['public_resource_def']
            code_uri              = rinfo['code_uri']
            component             = rinfo['component']
            services              = public_resource_def['services']
            public_resource_def['uri'] = Url(public_resource_def['uri'])

            if method == HTTP.GET_METHOD:
                self.breadcrumbs.append((resource_name, resource_home_uri))

            # Was there more to access?
            if len(path_elems) > 1:
                #
                # Some sub-service of the component was requested. This means
                # we actually need to pass the parameters to the component
                # and call this service function.
                #
                
                service_name = path_elems[1]

                # If the service name contains a "." then we might deal with
                # a content type ID in the URI (used by clients who don't know how
                # to deal with the 'Accept' or 'Content-type' headers properly).
                # In that case, we remove that ID from the service name.
                content_type_from_id = None
                if "." in service_name:
                    service_name, content_id = service_name.split(".")
                    content_type_from_id = RENDERER_ID_SHORTCUTS.get(content_id)
                    self.request.setContentType(content_type_from_id)

                if not content_type_from_id:
                    # Get the supported output content types for this service method
                    requested_content_types = self.request.preferredContentTypes()
                else:
                    # We have a content type specified in the URI
                    requested_content_types = [ content_type_from_id ]

                try:
                    service_def = complete_resource_def['public']['services'][service_name]
                except KeyError, e:
                    raise RestxResourceNotFoundException("Cannot find '%s'." % service_name)

                # This service has some possible runtime parameters defined.
                # We pass this service definition's parameter list in, since that
                # means we are filtering out all those parameters that we are
                # not expecting.
                service_params = service_def.get('params')
                if service_params:
                    # Only_params is the list of defined service parameters. Passing this to
                    # get_request_query_dict() means that all other runtime parameters are
                    # filtered out.
                    only_params = service_params.keys()
                    runtime_param_dict = get_request_query_dict(self.request, only_params)
                else:
                    only_params = None
                    runtime_param_dict = dict()   # No service parameters defined? All runtime parameters are removed (ignored).

                possible_output_types   = service_def.get('output_types')
                if not possible_output_types:
                    # If the service method didn't define any type(s) then we just
                    # indicate the ability to create any of the default types
                    possible_output_types = DEFAULT_OUTPUT_TYPES

                if type(possible_output_types) in [ str, unicode, java.lang.String ]:
                    # Always store the output types in a list, even if the service method just
                    # defined a single one
                    possible_output_types = [ possible_output_types ]

                # See that we can match the accepted to possible types
                matched_type      = content_type_match(possible_output_types, requested_content_types)
                positional_params = path_elems[2:]
                input             = self.request.getRequestBody()
                try:
                    http_method = __HTTP_METHOD_LOOKUP.get(self.request.getRequestMethod().upper(), HttpMethod.UNKNOWN)
                    result      = _accessComponentService(component, complete_resource_def,
                                                          resource_name, service_name, positional_params,
                                                          runtime_param_dict, input, self.request,
                                                          http_method)
                    if result == None  or  type(result) is not Result:
                        result = Result.noContent()
                    else:
                        result.setNegotiatedContentType(matched_type)
                except RestxException, e:
                    result = Result(e.code, e.msg)