Esempio n. 1
0
    def _default(self, *path, **kw):
        request = tg.request
        response = tg.response
        path = list(path)
        resource = None
        if not hasattr(request, 'bisque'):
            bisque = Bunch()
            request.bisque = bisque
        bisque = request.bisque
        user_id = identity.get_user_id()
        usecache = asbool(kw.pop('cache', True))
        http_method = request.method.lower()
        log.debug('Request "%s" with %s?%s', http_method, request.path,
                  str(kw))
        #log.debug ('Request "%s" ', path)

        #check the http method is supported.
        try:
            method_name = dict(get='get',
                               head='check',
                               post='append',
                               put='modify',
                               delete='delete')[http_method]
        except KeyError:
            abort(501)

        if not path:  #If the request path is to a collection.
            #self.check_cache_header(http_method, resource)
            if http_method == 'post':
                #If the method is a post, we call self.create which returns
                #a class which is passed into the self.new method.
                resource = self.create(**kw)
                assert resource is not None
                method_name = 'new'
            elif http_method == 'get':

                resource = getattr(request.bisque, 'parent', None)
                method_name = 'dir'
                # if parent:
                #     self.check_cache_header (http_method, parent)

                # #If the method is a get, call the self.index method, which
                # #should list the contents of the collection.
                # accept_header = headers = value = None
                # if usecache:
                #     headers, value = self.server_cache.fetch(request.url, user=user_id)
                #     if headers:
                #         _, accept_header = find_formatter (accept_header=request.headers.get ('accept'))
                #         content_type  = headers.get ('Content-Type')

                # if value and accept_header == content_type:
                #     response.headers.update(headers) # cherrypy.response.headers.update (headers)
                # else:
                #     #self.add_cache_header(None)
                #     value =  self.dir(**kw)
                #     self.server_cache.save (request.url,
                #                             response.headers,
                #                             value, user=user_id)
                # #self.add_cache_header(resource)
                # return value
            elif http_method == 'put':
                resource = getattr(bisque, 'parent', None)
                method_name = 'replace_all'
            elif http_method == 'delete':
                resource = getattr(bisque, 'parent', None)
                method_name = 'delete_all'
            elif http_method == 'head':
                # Determine whether the collection has changed
                resource = getattr(bisque, 'parent', None)
                method_name = "check"
            else:
                #Any other methods get rejected.
                abort(501)

        if resource is None and method_name != 'dir':
            #if we don't have a resource by now, (it wasn't created)
            #then try and load one.
            if path:
                token = path.pop(0)
                resource = self.load(token)
            if resource is None:
                #No resource found?
                if user_id is None:
                    abort(401)
                abort(404)

        #if we have a path, check if the first token matches this
        #classes children.
        if path:
            token = path.pop(0)
            log.debug('Token: ' + str(token))
            child = self.get_child_resource(token)
            if child is not None:
                bisque.parent = resource
                log.debug("parent = %s", str(resource))
                #call down into the child resource.
                return child._default(*path, **kw)

#        if http_method == 'get':
#            #if this resource has children, make sure it has a '/'
#            #on the end of the URL
#            if getattr(self, 'children', None) is not None:
#                if request.path[-1:] != '/':
#                    redirect(request.path + "/")

#resource = self.server_cache.force_load(resource)
        self.check_cache_header(http_method, resource)
        method = getattr(self, method_name)
        #pylons.response.headers['Content-Type'] = 'text/xml'
        log.debug("Dispatch for %s", method_name)
        try:
            if http_method in ('post', 'put'):
                clen = int(request.headers.get('Content-Length', 0))
                content_type = request.headers.get('Content-Type')

                inputer = find_inputer(content_type)
                if not inputer:
                    log.debug("Bad media type in post/put:%s", content_type)
                    abort(415, "Bad media type in post/put:%s" % content_type)

                # xml arg is for backward compat
                value = method(resource,
                               xml=inputer(request.body_file, clen),
                               **kw)

                # if content.startswith('text/xml') or \
                #        content.startswith('application/xml'):
                #     data = request.body_file.read(clen)
                #     #log.debug('POST '+ data)
                #     #kw['xml_text'] = data
                #     value = method(resource, xml=data, **kw)
                # elif content.startswith("application/json"):
                #     try:
                #         #data = request.body_file.read(clen)
                #         data = d2xml (json.load (request.body_file))
                #         value = method(resource, xml=data, **kw)
                #     except Exception as e:
                #         log.exception ("while reading json content")
                #         abort(415, "Bad media type in post/put:%s" % content )
                # else:
                #     #response = method(resource, doc = None, **kw)
                #     # Raise illegal operation (you should provide XML)
                #     log.debug ("Bad media type in post/put:%s" ,  content)
                #     abort(415, "Bad media type in post/put:%s" % content )
                # #self.server_cache.invalidate(request.url, user=user_id)
                self.server_cache.invalidate_resource(resource, user=user_id)
            elif http_method == 'delete':
                self.server_cache.invalidate_resource(resource, user=user_id)
                value = method(resource, **kw)
                #self.server_cache.invalidate(request.url, user=user_id)
            elif http_method == 'get':
                accept_header = headers = value = None
                if usecache:
                    headers, value = self.server_cache.fetch(request.url,
                                                             user=user_id)
                    if headers:
                        content_type = headers.get('Content-Type')
                        _, accept_header = find_formatter(
                            accept_header=request.headers.get('accept'))
                if value and accept_header == content_type:
                    response.headers.update(headers)
                    return value
                else:
                    #run the requested method, passing it the resource
                    value = method(resource, **kw)
                    # SET content length?
                    self.server_cache.save(request.url,
                                           response.headers,
                                           value,
                                           user=user_id)
                    self.add_cache_header(resource)
            else:  # http_method == HEAD
                value = method(resource, **kw)

            #set the last modified date header for the response
            return value

        except identity.BQIdentityException:
            response.status_int = 401
            return "<response>FAIL</response>"