Пример #1
0
def _pagination_links(resource, req, documents_count):
    """Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    _links = {'parent': home_link(), 'self': collection_link(resource)}

    if documents_count and config.DOMAIN[resource]['pagination']:
        if req.page * req.max_results < documents_count:
            q = querydef(req.max_results, req.where, req.sort, req.page + 1)
            _links['next'] = {'title': 'next page', 'href': '%s%s' %
                              (resource_uri(resource), q)}

        if req.page > 1:
            q = querydef(req.max_results, req.where, req.sort, req.page - 1)
            _links['prev'] = {'title': 'previous page', 'href': '%s%s' %
                              (resource_uri(resource), q)}

    return _links
Пример #2
0
def get_cfg(blueprints):
    cfg = {}
    protocol = capp.config['PREFERRED_URL_SCHEME']
    home = home_link()
    cfg['base'] = '{}://{}'.format(protocol, home['href'])
    cfg['domains'] = {}
    cfg['server_name'] = capp.config['SERVER_NAME']
    cfg['api_name'] = capp.config.get('API_NAME', 'API')
    for domain in capp.config['DOMAIN'].keys():
        # empowering doc
        # added show_on_doc property where there aren't any item_methods nor resource_methods
        if capp.config['DOMAIN'][domain]['item_methods'] or capp.config[
                'DOMAIN'][domain][
                    'resource_methods'] or 'show_on_doc' in capp.config[
                        'DOMAIN'][domain]:
            cfg['domains'][domain] = {}
            cfg['domains'][domain] = paths(domain)
            if 'doc' in capp.config['DOMAIN'][domain]:
                cfg['domains'][domain]['doc'] = capp.config['DOMAIN'][domain][
                    'doc']
    for b in blueprints:
        resources = get_custom_functions(b)
        for domain in resources:
            cfg['domains'][domain] = resources[domain]
    return cfg
Пример #3
0
Файл: get.py Проект: klyr/eve
def _pagination_links(resource, req, documents_count):
    """Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    _links = {"parent": home_link(), "self": collection_link(resource)}

    if documents_count and config.DOMAIN[resource]["pagination"]:
        if req.page * req.max_results < documents_count:
            q = querydef(req.max_results, req.where, req.sort, req.page + 1)
            _links["next"] = {"title": "next page", "href": "%s%s" % (resource_uri(resource), q)}

        if req.page > 1:
            q = querydef(req.max_results, req.where, req.sort, req.page - 1)
            _links["prev"] = {"title": "previous page", "href": "%s%s" % (resource_uri(resource), q)}

    return _links
Пример #4
0
Файл: get.py Проект: Tefnet/eve
def _pagination_links(resource, req, documents_count):
    """Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    _links = {'parent': home_link(), 'self': collection_link(resource)}

    if documents_count and config.DOMAIN[resource]['pagination']:
        if req.page * req.max_results < documents_count:
            q = querydef(req.max_results, req.where, req.sort, req.page + 1)
            _links['next'] = {
                'title': 'next page',
                'href': '%s%s' % (resource_uri(resource), q)
            }

        if req.page > 1:
            q = querydef(req.max_results, req.where, req.sort, req.page - 1)
            _links['prev'] = {
                'title': 'previous page',
                'href': '%s%s' % (resource_uri(resource), q)
            }

    return _links
Пример #5
0
Файл: get.py Проект: klyr/eve
def getitem(resource, **lookup):
    """ Retrieves and returns a single document.

    :param resource: the name of the resource to which the document belongs.
    :param **lookup: the lookup query.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.6
        ETag added to payload.

    .. versionchanged:: 0.0.5
       Support for user-restricted access to resources.
       Support for LAST_UPDATED field missing from documents, because they were
       created outside the API context.

    .. versionchanged:: 0.0.4
       Added the ``requires_auth`` decorator.

    .. versionchanged:: 0.0.3
       Superflous ``response`` container removed. Links wrapped with
       ``_links``. Links are now properly JSON formatted.
    """
    response = {}

    req = parse_request(resource)
    document = app.data.find_one(resource, **lookup)
    if document:
        # need to update the document field as well since the etag must
        # be computed on the same document representation that might have
        # been used in the collection 'get' method
        last_modified = document[config.LAST_UPDATED] = _last_updated(document)
        document["etag"] = document_etag(document)

        if req.if_none_match and document["etag"] == req.if_none_match:
            # request etag matches the current server representation of the
            # document, return a 304 Not-Modified.
            return response, last_modified, document["etag"], 304

        if req.if_modified_since and last_modified <= req.if_modified_since:
            # request If-Modified-Since conditional request match. We test
            # this after the etag since Last-Modified dates have lower
            # resolution (1 second).
            return response, last_modified, document["etag"], 304

        response["_links"] = {
            "self": document_link(resource, document[config.ID_FIELD]),
            "collection": collection_link(resource),
            "parent": home_link(),
        }
        response.update(document)
        return response, last_modified, document["etag"], 200

    abort(404)
Пример #6
0
def _pagination_links(resource, req, documents_count):
    """ Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.

    .. versionchanged:: 0.0.8
       Link to last page is provided if pagination is enabled (and the current
       page is not the last one).

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    _links = {
        'parent': home_link(),
        'self': {
            'title': config.DOMAIN[resource]['resource_title'],
            'href': _collection_link(resource)
        }
    }

    if documents_count and config.DOMAIN[resource]['pagination']:
        if req.page * req.max_results < documents_count:
            q = querydef(req.max_results, req.where, req.sort, req.page + 1)
            _links['next'] = {
                'title': 'next page',
                'href': '%s%s' % (_collection_link(resource), q)
            }

            # in python 2.x dividing 2 ints produces an int and that's rounded
            # before the ceil call. Have to cast one value to float to get
            # a correct result. Wonder if 2 casts + ceil() call are actually
            # faster than documents_count // req.max_results and then adding
            # 1 if the modulo is non-zero...
            last_page = int(math.ceil(documents_count /
                                      float(req.max_results)))
            q = querydef(req.max_results, req.where, req.sort, last_page)
            _links['last'] = {
                'title': 'last page',
                'href': '%s%s' % (_collection_link(resource), q)
            }

        if req.page > 1:
            q = querydef(req.max_results, req.where, req.sort, req.page - 1)
            _links['prev'] = {
                'title': 'previous page',
                'href': '%s%s' % (_collection_link(resource), q)
            }

    return _links
Пример #7
0
def getitem(resource, **lookup):
    """ Retrieves and returns a single document.

    :param resource: the name of the resource to which the document belongs.
    :param **lookup: the lookup query.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.6
        ETag added to payload.

    .. versionchanged:: 0.0.5
       Support for user-restricted access to resources.
       Support for LAST_UPDATED field missing from documents, because they were
       created outside the API context.

    .. versionchanged:: 0.0.4
       Added the ``requires_auth`` decorator.

    .. versionchanged:: 0.0.3
       Superflous ``response`` container removed. Links wrapped with
       ``_links``. Links are now properly JSON formatted.
    """
    response = {}

    req = parse_request(resource)
    document = app.data.find_one(resource, **lookup)
    if document:
        # need to update the document field as well since the etag must
        # be computed on the same document representation that might have
        # been used in the collection 'get' method
        last_modified = document[config.LAST_UPDATED] = _last_updated(document)
        document['etag'] = document_etag(document)

        if req.if_none_match and document['etag'] == req.if_none_match:
            # request etag matches the current server representation of the
            # document, return a 304 Not-Modified.
            return response, last_modified, document['etag'], 304

        if req.if_modified_since and last_modified <= req.if_modified_since:
            # request If-Modified-Since conditional request match. We test
            # this after the etag since Last-Modified dates have lower
            # resolution (1 second).
            return response, last_modified, document['etag'], 304

        response['_links'] = {
            'self': document_link(resource, document[config.ID_FIELD]),
            'collection': collection_link(resource),
            'parent': home_link()
        }
        response.update(document)
        return response, last_modified, document['etag'], 200

    abort(404)
Пример #8
0
Файл: get.py Проект: Acapla/eve
def _pagination_links(resource, req, documents_count):
    """ Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.

    .. versionchanged:: 0.4
       HATOEAS link for contains the business unit value even when
       regexes have been configured for the resource endpoint.

    .. versionchanged:: 0.0.8
       Link to last page is provided if pagination is enabled (and the current
       page is not the last one).

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    _links = {'parent': home_link(),
              'self': {'title': config.DOMAIN[resource]['resource_title'],
                       'href': resource_link()}}

    if documents_count and config.DOMAIN[resource]['pagination']:
        if req.page * req.max_results < documents_count:
            q = querydef(req.max_results, req.where, req.sort, req.page + 1)
            _links['next'] = {'title': 'next page', 'href': '%s%s' %
                              (resource_link(), q)}

            # in python 2.x dividing 2 ints produces an int and that's rounded
            # before the ceil call. Have to cast one value to float to get
            # a correct result. Wonder if 2 casts + ceil() call are actually
            # faster than documents_count // req.max_results and then adding
            # 1 if the modulo is non-zero...
            last_page = int(math.ceil(documents_count
                                      / float(req.max_results)))
            q = querydef(req.max_results, req.where, req.sort, last_page)
            _links['last'] = {'title': 'last page', 'href': '%s%s'
                              % (resource_link(), q)}

        if req.page > 1:
            q = querydef(req.max_results, req.where, req.sort, req.page - 1)
            _links['prev'] = {'title': 'previous page', 'href': '%s%s' %
                              (resource_link(), q)}

    return _links
Пример #9
0
def get_cfg():
    cfg = {}
    protocol = capp.config['PREFERRED_URL_SCHEME']
    home = home_link()
    cfg['base'] = '{}://{}'.format(protocol, home['href'])
    cfg['domains'] = {}
    cfg['server_name'] = capp.config['SERVER_NAME']
    cfg['api_name'] = capp.config.get('API_NAME', 'API')
    for domain in capp.config['DOMAIN'].keys():
        if capp.config['DOMAIN'][domain]['item_methods'] or capp.config['DOMAIN'][domain]['resource_methods']:
            cfg['domains'][domain] = {}
            cfg['domains'][domain] = paths(domain)
    return cfg
Пример #10
0
def get_cfg():
    cfg = {}
    protocol = capp.config['PREFERRED_URL_SCHEME']
    home = home_link()
    cfg['base'] = '{}://{}'.format(protocol, home['href'])
    cfg['domains'] = {}
    cfg['server_name'] = capp.config['SERVER_NAME']
    cfg['api_name'] = capp.config.get('API_NAME', 'API')
    for domain in capp.config['DOMAIN'].keys():
        if capp.config['DOMAIN'][domain]['item_methods'] or \
                capp.config['DOMAIN'][domain]['resource_methods']:
            # hide the shadow collection for document versioning
            if 'VERSIONS' not in capp.config or not \
                    domain.endswith(capp.config['VERSIONS']):
                cfg['domains'][domain] = {}
                cfg['domains'][domain] = paths(domain)
    return cfg
Пример #11
0
def getitem(resource, **lookup):
    """ Retrieves and returns a single document.

    :param resource: the name of the resource to which the document belongs.
    :param **lookup: the lookup query.

    .. versionchanged:: 0.0.4
       Added the ``requires_auth`` decorator.

    .. versionchanged:: 0.0.3
       Superflous ``response`` container removed. Links wrapped with
       ``_links``. Links are now properly JSON formatted.
    """
    response = {}

    req = parse_request()
    document = app.data.find_one(resource, **lookup)
    if document:
        # need to update the document field as well since the etag must
        # be computed on the same document representation that might have
        # been used in the collection 'get' method
        last_modified = document[config.LAST_UPDATED] = \
            document[config.LAST_UPDATED].replace(tzinfo=None)
        etag = document_etag(document)

        if req.if_none_match and etag == req.if_none_match:
            # request etag matches the current server representation of the
            # document, return a 304 Not-Modified.
            return response, last_modified, etag, 304

        if req.if_modified_since and last_modified <= req.if_modified_since:
            # request If-Modified-Since conditional request match. We test
            # this after the etag since Last-Modified dates have lower
            # resolution (1 second).
            return response, last_modified, etag, 304

        response['_links'] = {
            'self': document_link(resource, document[config.ID_FIELD]),
            'collection': collection_link(resource),
            'parent': home_link()
        }
        response.update(document)
        return response, last_modified, etag, 200

    abort(404)
Пример #12
0
def get_cfg():
    cfg = {}
    base = home_link()['href']
    if '://' not in base:
        protocol = capp.config['PREFERRED_URL_SCHEME']
        print(base)
        base = '{0}://{1}'.format(protocol, base)

    cfg['base'] = base
    cfg['domains'] = {}
    cfg['server_name'] = capp.config['SERVER_NAME']
    cfg['api_name'] = capp.config.get('API_NAME', 'API')
    for domain, resource in list(capp.config['DOMAIN'].items()):
        if resource['item_methods'] or resource['resource_methods']:
            # hide the shadow collection for document versioning
            if 'VERSIONS' not in capp.config or not \
                    domain.endswith(capp.config['VERSIONS']):
                cfg['domains'][domain] = paths(domain, resource)
    return cfg
Пример #13
0
def get_cfg():
    cfg = {}
    base = home_link()['href']
    if '://' not in base:
        protocol = capp.config['PREFERRED_URL_SCHEME']
        print base
        base = '{0}://{1}'.format(protocol, base)

    cfg['base'] = base
    cfg['domains'] = {}
    cfg['server_name'] = capp.config['SERVER_NAME']
    cfg['api_name'] = capp.config.get('API_NAME', 'API')
    for domain, resource in capp.config['DOMAIN'].items():
        if resource['item_methods'] or resource['resource_methods']:
            # hide the shadow collection for document versioning
            if 'VERSIONS' not in capp.config or not \
                    domain.endswith(capp.config['VERSIONS']):
                cfg['domains'][domain] = paths(domain, resource)
    return cfg
Пример #14
0
def _pagination_links(resource, req, documents_count):
    """Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.

    .. versionchanged:: 0.0.8
       Link to last page is provided if pagination is enabled (and the current
       page is not the last one).

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    _links = {"parent": home_link(), "self": collection_link(resource)}

    if documents_count and config.DOMAIN[resource]["pagination"]:
        if req.page * req.max_results < documents_count:
            q = querydef(req.max_results, req.where, req.sort, req.page + 1)
            _links["next"] = {"title": "next page", "href": "%s%s" % (resource_uri(resource), q)}

            # in python 2.x dividing 2 ints produces an int and that's rounded
            # before the ceil call. Have to cast one value to float to get
            # a correct result. Wonder if 2 casts + ceil() call are actually
            # faster than documents_count // req.max_results and then adding
            # 1 if the modulo is non-zero...
            last_page = int(math.ceil(documents_count / float(req.max_results)))
            q = querydef(req.max_results, req.where, req.sort, last_page)
            _links["last"] = {"title": "last page", "href": "%s%s" % (resource_uri(resource), q)}

        if req.page > 1:
            q = querydef(req.max_results, req.where, req.sort, req.page - 1)
            _links["prev"] = {"title": "previous page", "href": "%s%s" % (resource_uri(resource), q)}

    return _links
Пример #15
0
def standard_links(resource):
    """Returns the standard set of resource links that are included in every
    kind of GET response.
    """
    return [home_link(), collection_link(resource)]
Пример #16
0
def _pagination_links(resource, req, documents_count, document_id=None):
    """ Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.
    :param document_id: the document id (used for versions). Defaults to None.

    .. versionchanged:: 0.5
       Create pagination links given a document ID to allow paginated versions
       pages (#475).
       Pagination links reflect current query. (#464)

    .. versionchanged:: 0.4
       HATOEAS link for contains the business unit value even when
       regexes have been configured for the resource endpoint.

    .. versionchanged:: 0.0.8
       Link to last page is provided if pagination is enabled (and the current
       page is not the last one).

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    version = None
    if config.DOMAIN[resource]['versioning'] is True:
        version = request.args.get(config.VERSION_PARAM)

    other_params = _other_params(req.args)
    # construct the default links
    q = querydef(req.max_results, req.where, req.sort, version, req.page,
                 other_params)
    resource_title = config.DOMAIN[resource]['resource_title']
    _links = {'parent': home_link(),
              'self': {'title': resource_title,
                       'href': resource_link()}}

    # change links if document ID is given
    if document_id:
        _links['self'] = document_link(resource, document_id)
        _links['collection'] = {'title': resource_title,
                                'href': '%s%s' % (resource_link(), q)}

        # make more specific links for versioned requests
        if version in ('all', 'diffs'):
            _links['parent'] = {'title': resource_title,
                                'href': resource_link()}
            _links['collection'] = document_link(resource, document_id)
        elif version:
            _links['parent'] = document_link(resource, document_id)
            _links['collection'] = {'title': resource_title,
                                    'href': '%s?version=all'
                                    % _links['parent']['href']}

    # modify the self link to add query params or version number
    if documents_count:
        _links['self']['href'] = '%s%s' % (_links['self']['href'], q)
    elif not documents_count and version and version not in ('all', 'diffs'):
        _links['self'] = document_link(resource, document_id, version)

    # create pagination links
    if documents_count and config.DOMAIN[resource]['pagination']:
        # strip any queries from the self link if present
        _pagination_link = _links['self']['href'].split('?')[0]
        if req.page * req.max_results < documents_count:
            q = querydef(req.max_results, req.where, req.sort, version,
                         req.page + 1, other_params)
            _links['next'] = {'title': 'next page', 'href': '%s%s' %
                              (_pagination_link, q)}

            # in python 2.x dividing 2 ints produces an int and that's rounded
            # before the ceil call. Have to cast one value to float to get
            # a correct result. Wonder if 2 casts + ceil() call are actually
            # faster than documents_count // req.max_results and then adding
            # 1 if the modulo is non-zero...
            last_page = int(math.ceil(documents_count /
                                      float(req.max_results)))
            q = querydef(req.max_results, req.where, req.sort, version,
                         last_page, other_params)
            _links['last'] = {'title': 'last page', 'href': '%s%s'
                              % (_pagination_link, q)}

        if req.page > 1:
            q = querydef(req.max_results, req.where, req.sort, version,
                         req.page - 1, other_params)
            _links['prev'] = {'title': 'previous page', 'href': '%s%s' %
                              (_pagination_link, q)}

    return _links
Пример #17
0
Файл: get.py Проект: bcattle/eve
def getitem(resource, **lookup):
    """ Retrieves and returns a single document.

    :param resource: the name of the resource to which the document belongs.
    :param **lookup: the lookup query.

    .. versionchanged: 0.0.8
       'on_getting_item' event is raised when a document has been read from the
       database and is about to be sent to the client.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.6
        ETag added to payload.

    .. versionchanged:: 0.0.5
       Support for user-restricted access to resources.
       Support for LAST_UPDATED field missing from documents, because they were
       created outside the API context.

    .. versionchanged:: 0.0.4
       Added the ``requires_auth`` decorator.

    .. versionchanged:: 0.0.3
       Superflous ``response`` container removed. Links wrapped with
       ``_links``. Links are now properly JSON formatted.
    """
    response = {}

    req = parse_request(resource)
    document = app.data.find_one(resource, **lookup)
    if document:
        # need to update the document field as well since the etag must
        # be computed on the same document representation that might have
        # been used in the collection 'get' method
        last_modified = document[config.LAST_UPDATED] = _last_updated(document)
        document['etag'] = document_etag(document)

        if req.if_none_match and document['etag'] == req.if_none_match:
            # request etag matches the current server representation of the
            # document, return a 304 Not-Modified.
            return response, last_modified, document['etag'], 304

        if req.if_modified_since and last_modified <= req.if_modified_since:
            # request If-Modified-Since conditional request match. We test
            # this after the etag since Last-Modified dates have lower
            # resolution (1 second).
            return response, last_modified, document['etag'], 304

        response['_links'] = {
            'self': document_link(resource, document[config.ID_FIELD]),
            'collection': collection_link(resource),
            'parent': home_link()
        }

        # notify registered callback functions. Please note that, should the
        # functions modify the document, last_modified and etag  won't be
        # updated to reflect the changes (they always reflect the documents
        # state on the database).
        getattr(app, "on_getting_item")(resource, document[config.ID_FIELD],
                                        document)

        response.update(document)
        return response, last_modified, document['etag'], 200

    abort(404)
Пример #18
0
Файл: get.py Проект: kidaa/eve
def _pagination_links(resource, req, documents_count, document_id=None):
    """ Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.
    :param document_id: the document id (used for versions). Defaults to None.

    .. versionchanged:: 0.5
       Create pagination links given a document ID to allow paginated versions
       pages (#475).
       Pagination links reflect current query. (#464)

    .. versionchanged:: 0.4
       HATOEAS link for contains the business unit value even when
       regexes have been configured for the resource endpoint.

    .. versionchanged:: 0.0.8
       Link to last page is provided if pagination is enabled (and the current
       page is not the last one).

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    version = None
    if config.DOMAIN[resource]['versioning'] is True:
        version = request.args.get(config.VERSION_PARAM)

    # construct the default links
    q = querydef(req.max_results, req.where, req.sort, version, req.page)
    resource_title = config.DOMAIN[resource]['resource_title']
    _links = {'parent': home_link(),
              'self': {'title': resource_title,
                       'href': resource_link()}}

    # change links if document ID is given
    if document_id:
        _links['self'] = document_link(resource, document_id)
        _links['collection'] = {'title': resource_title,
                                'href': '%s%s' % (resource_link(), q)}

        # make more specific links for versioned requests
        if version in ('all', 'diffs'):
            _links['parent'] = {'title': resource_title,
                                'href': resource_link()}
            _links['collection'] = document_link(resource, document_id)
        elif version:
            _links['parent'] = document_link(resource, document_id)
            _links['collection'] = {'title': resource_title,
                                    'href': '%s?version=all'
                                    % _links['parent']['href']}

    # modify the self link to add query params or version number
    if documents_count:
        _links['self']['href'] = '%s%s' % (_links['self']['href'], q)
    elif not documents_count and version and version not in ('all', 'diffs'):
        _links['self'] = document_link(resource, document_id, version)

    # create pagination links
    if documents_count and config.DOMAIN[resource]['pagination']:
        # strip any queries from the self link if present
        _pagination_link = _links['self']['href'].split('?')[0]
        if req.page * req.max_results < documents_count:
            q = querydef(req.max_results, req.where, req.sort, version,
                         req.page + 1)
            _links['next'] = {'title': 'next page', 'href': '%s%s' %
                              (_pagination_link, q)}

            # in python 2.x dividing 2 ints produces an int and that's rounded
            # before the ceil call. Have to cast one value to float to get
            # a correct result. Wonder if 2 casts + ceil() call are actually
            # faster than documents_count // req.max_results and then adding
            # 1 if the modulo is non-zero...
            last_page = int(math.ceil(documents_count /
                                      float(req.max_results)))
            q = querydef(req.max_results, req.where, req.sort, version,
                         last_page)
            _links['last'] = {'title': 'last page', 'href': '%s%s'
                              % (_pagination_link, q)}

        if req.page > 1:
            q = querydef(req.max_results, req.where, req.sort, version,
                         req.page - 1)
            _links['prev'] = {'title': 'previous page', 'href': '%s%s' %
                              (_pagination_link, q)}

    return _links
Пример #19
0
def getitem(resource, **lookup):
    """
    :param resource: the name of the resource to which the document belongs.
    :param **lookup: the lookup query.

    .. versionchanged:: 0.3
       Support for media fields.
       When IF_MATCH is disabled, no etag is included in the payload.

    .. versionchanged:: 0.1.1
       Support for Embeded Resource Serialization.

    .. versionchanged:: 0.1.0
       Support for optional HATEOAS.

    .. versionchanged: 0.0.8
       'on_getting_item' event is raised when a document has been read from the
       database and is about to be sent to the client.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.6
        ETag added to payload.

    .. versionchanged:: 0.0.5
       Support for user-restricted access to resources.
       Support for LAST_UPDATED field missing from documents, because they were
       created outside the API context.

    .. versionchanged:: 0.0.4
       Added the ``requires_auth`` decorator.

    .. versionchanged:: 0.0.3
       Superflous ``response`` container removed. Links wrapped with
       ``_links``. Links are now properly JSON formatted.
    """
    response = {}

    req = parse_request(resource)
    document = app.data.find_one(resource, **lookup)
    if document:
        # need to update the document field as well since the etag must
        # be computed on the same document representation that might have
        # been used in the collection 'get' method
        last_modified = document[config.LAST_UPDATED] = last_updated(document)
        document[config.DATE_CREATED] = date_created(document)

        etag = None
        if config.IF_MATCH:
            etag = document[config.ETAG] = document_etag(document)

            if req.if_none_match and document[config.ETAG] == \
                    req.if_none_match:
                # request etag matches the current server representation of the
                # document, return a 304 Not-Modified.
                return response, last_modified, etag, 304

        if req.if_modified_since and last_modified <= req.if_modified_since:
            # request If-Modified-Since conditional request match. We test
            # this after the etag since Last-Modified dates have lower
            # resolution (1 second).
            return response, last_modified, document.get(config.ETAG), 304

        _resolve_embedded_documents(resource, req, [document])
        _resolve_media_files(document, resource)

        if config.DOMAIN[resource]['hateoas']:
            response[config.LINKS] = {
                'self': document_link(resource, document[config.ID_FIELD]),
                'collection': {
                    'title': config.DOMAIN[resource]['resource_title'],
                    'href': _collection_link(resource, True)
                },
                'parent': home_link()
            }

        # notify registered callback functions. Please note that, should the
        # functions modify the document, last_modified and etag  won't be
        # updated to reflect the changes (they always reflect the documents
        # state on the database).
        item_title = config.DOMAIN[resource]['item_title'].lower()

        getattr(app, "on_fetch_item")(resource, document[config.ID_FIELD],
                                      document)
        getattr(app,
                "on_fetch_item_%s" % item_title)(document[config.ID_FIELD],
                                                 document)

        response.update(document)
        return response, last_modified, etag, 200

    abort(404)
Пример #20
0
def getitem(resource, **lookup):
    """
    :param resource: the name of the resource to which the document belongs.
    :param **lookup: the lookup query.

    .. versionchanged:: 0.4
       HATOEAS link for contains the business unit value even when
       regexes have been configured for the resource endpoint.
       'on_fetched' now returns the whole response (HATEOAS metafields
       included.)
       Support for document versioning.
       Changed ``on_fetch_*`` changed to ``on_fetched_*``.

    .. versionchanged:: 0.3
       Support for media fields.
       When IF_MATCH is disabled, no etag is included in the payload.

    .. versionchanged:: 0.1.1
       Support for Embeded Resource Serialization.

    .. versionchanged:: 0.1.0
       Support for optional HATEOAS.

    .. versionchanged: 0.0.8
       'on_getting_item' event is raised when a document has been read from the
       database and is about to be sent to the client.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.6
        ETag added to payload.

    .. versionchanged:: 0.0.5
       Support for user-restricted access to resources.
       Support for LAST_UPDATED field missing from documents, because they were
       created outside the API context.

    .. versionchanged:: 0.0.4
       Added the ``requires_auth`` decorator.

    .. versionchanged:: 0.0.3
       Superflous ``response`` container removed. Links wrapped with
       ``_links``. Links are now properly JSON formatted.
    """
    req = parse_request(resource)
    resource_def = config.DOMAIN[resource]
    embedded_fields = resolve_embedded_fields(resource, req)

    document = app.data.find_one(resource, req, **lookup)
    if not document:
        abort(404)

    response = {}
    etag = None
    version = request.args.get(config.VERSION_PARAM)
    latest_doc = None

    # synthesize old document version(s)
    if resource_def['versioning'] is True:
        latest_doc = copy.deepcopy(document)
        document = get_old_document(resource, req, lookup, document, version)

    # meld into response document
    build_response_document(document, resource, embedded_fields, latest_doc)

    # last_modified for the response
    last_modified = document[config.LAST_UPDATED]

    # facilitate client caching by returning a 304 when appropriate
    if config.IF_MATCH:
        etag = document[config.ETAG]

        if req.if_none_match and etag == req.if_none_match:
            # request etag matches the current server representation of the
            # document, return a 304 Not-Modified.
            return {}, last_modified, document[config.ETAG], 304

    if req.if_modified_since and last_modified <= req.if_modified_since:
        # request If-Modified-Since conditional request match. We test
        # this after the etag since Last-Modified dates have lower
        # resolution (1 second).
        return {}, last_modified, document.get(config.ETAG), 304

    if version == 'all' or version == 'diffs':
        # find all versions
        lookup[versioned_id_field()] = lookup[app.config['ID_FIELD']]
        del lookup[app.config['ID_FIELD']]
        if version == 'diffs' or req.sort is None:
            # default sort for 'all', required sort for 'diffs'
            req.sort = '[("%s", 1)]' % config.VERSION
        req.if_modified_since = None  # we always want the full history here
        cursor = app.data.find(resource + config.VERSIONS, req, lookup)

        # build all versions
        documents = []
        if cursor.count() == 0:
            # this is the scenario when the document existed before
            # document versioning got turned on
            documents.append(latest_doc)
        else:
            last_document = {}

            # if we aren't starting on page 1, then we need to init last_doc
            if version == 'diffs' and req.page > 1:
                # grab the last document on the previous page to diff from
                last_version = cursor[0][app.config['VERSION']] - 1
                last_document = get_old_document(resource, req, lookup,
                                                 latest_doc, last_version)

            for i, document in enumerate(cursor):
                document = synthesize_versioned_document(
                    latest_doc, document, resource_def)
                build_response_document(document, resource, embedded_fields,
                                        latest_doc)
                if version == 'diffs':
                    if i == 0:
                        documents.append(document)
                    else:
                        documents.append(
                            diff_document(resource_def, last_document,
                                          document))
                    last_document = document
                else:
                    documents.append(document)

        # add documents to response
        if config.DOMAIN[resource]['hateoas']:
            response[config.ITEMS] = documents
        else:
            response = documents
    else:
        response = document

    # extra hateoas links
    if config.DOMAIN[resource]['hateoas']:
        if config.LINKS not in response:
            response[config.LINKS] = {}
        response[config.LINKS]['collection'] = {
            'title': config.DOMAIN[resource]['resource_title'],
            'href': resource_link()
        }
        response[config.LINKS]['parent'] = home_link()

    if version != 'all' and version != 'diffs':
        # TODO: callbacks not currently supported with ?version=all

        # notify registered callback functions. Please note that, should
        # the # functions modify the document, last_modified and etag
        # won't be updated to reflect the changes (they always reflect the
        # documents state on the database).
        getattr(app, "on_fetched_item")(resource, response)
        getattr(app, "on_fetched_item_%s" % resource)(response)

    return response, last_modified, etag, 200
Пример #21
0
Файл: get.py Проект: marchon/eve
def standard_links(resource):
    """Returns the standard set of resource links that are included in every
    kind of GET response.
    """
    return [home_link(), collection_link(resource)]
Пример #22
0
Файл: get.py Проект: zaster/eve
def _pagination_links(resource, req, document_count, document_id=None):
    """ Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.
    :param document_id: the document id (used for versions). Defaults to None.

    .. versionchanged:: 0.5
       Create pagination links given a document ID to allow paginated versions
       pages (#475).
       Pagination links reflect current query. (#464)

    .. versionchanged:: 0.4
       HATEOAS link for contains the business unit value even when
       regexes have been configured for the resource endpoint.

    .. versionchanged:: 0.0.8
       Link to last page is provided if pagination is enabled (and the current
       page is not the last one).

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    version = None
    if config.DOMAIN[resource]["versioning"] is True:
        version = request.args.get(config.VERSION_PARAM)

    other_params = _other_params(req.args)
    # construct the default links
    q = querydef(req.max_results, req.where, req.sort, version, req.page, other_params)
    resource_title = config.DOMAIN[resource]["resource_title"]
    _links = {
        "parent": home_link(),
        "self": {"title": resource_title, "href": resource_link()},
    }

    # change links if document ID is given
    if document_id:
        _links["self"] = document_link(resource, document_id)
        _links["collection"] = {
            "title": resource_title,
            "href": "%s%s" % (resource_link(), q),
        }

        # make more specific links for versioned requests
        if version in ("all", "diffs"):
            _links["parent"] = {"title": resource_title, "href": resource_link()}
            _links["collection"] = document_link(resource, document_id)
        elif version:
            _links["parent"] = document_link(resource, document_id)
            _links["collection"] = {
                "title": resource_title,
                "href": "%s?version=all" % _links["parent"]["href"],
            }

    # modify the self link to add query params or version number
    if document_count:
        _links["self"]["href"] = "%s%s" % (_links["self"]["href"], q)
    elif not document_count and version and version not in ("all", "diffs"):
        _links["self"] = document_link(resource, document_id, version)

    # create pagination links
    if config.DOMAIN[resource]["pagination"]:
        # strip any queries from the self link if present
        _pagination_link = _links["self"]["href"].split("?")[0]

        if (
            req.page * req.max_results < (document_count or 0)
            or config.OPTIMIZE_PAGINATION_FOR_SPEED
        ):
            q = querydef(
                req.max_results,
                req.where,
                req.sort,
                version,
                req.page + 1,
                other_params,
            )
            _links["next"] = {
                "title": "next page",
                "href": "%s%s" % (_pagination_link, q),
            }

            if document_count:
                last_page = int(math.ceil(document_count / float(req.max_results)))
                q = querydef(
                    req.max_results,
                    req.where,
                    req.sort,
                    version,
                    last_page,
                    other_params,
                )
                _links["last"] = {
                    "title": "last page",
                    "href": "%s%s" % (_pagination_link, q),
                }

        if req.page > 1:
            q = querydef(
                req.max_results,
                req.where,
                req.sort,
                version,
                req.page - 1,
                other_params,
            )
            _links["prev"] = {
                "title": "previous page",
                "href": "%s%s" % (_pagination_link, q),
            }

    return _links
Пример #23
0
def getitem(resource, **lookup):
    """
    :param resource: the name of the resource to which the document belongs.
    :param **lookup: the lookup query.

    .. versionchanged:: 0.3
       Support for media fields.
       When IF_MATCH is disabled, no etag is included in the payload.

    .. versionchanged:: 0.1.1
       Support for Embeded Resource Serialization.

    .. versionchanged:: 0.1.0
       Support for optional HATEOAS.

    .. versionchanged: 0.0.8
       'on_getting_item' event is raised when a document has been read from the
       database and is about to be sent to the client.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.6
        ETag added to payload.

    .. versionchanged:: 0.0.5
       Support for user-restricted access to resources.
       Support for LAST_UPDATED field missing from documents, because they were
       created outside the API context.

    .. versionchanged:: 0.0.4
       Added the ``requires_auth`` decorator.

    .. versionchanged:: 0.0.3
       Superflous ``response`` container removed. Links wrapped with
       ``_links``. Links are now properly JSON formatted.
    """
    response = {}

    req = parse_request(resource)
    document = app.data.find_one(resource, **lookup)
    if document:
        # need to update the document field as well since the etag must
        # be computed on the same document representation that might have
        # been used in the collection 'get' method
        last_modified = document[config.LAST_UPDATED] = last_updated(document)
        document[config.DATE_CREATED] = date_created(document)

        etag = None
        if config.IF_MATCH:
            etag = document[config.ETAG] = document_etag(document)

            if req.if_none_match and document[config.ETAG] == \
                    req.if_none_match:
                # request etag matches the current server representation of the
                # document, return a 304 Not-Modified.
                return response, last_modified, etag, 304

        if req.if_modified_since and last_modified <= req.if_modified_since:
            # request If-Modified-Since conditional request match. We test
            # this after the etag since Last-Modified dates have lower
            # resolution (1 second).
            return response, last_modified, document.get(config.ETAG), 304

        _resolve_embedded_documents(resource, req, [document])
        _resolve_media_files(document, resource)

        if config.DOMAIN[resource]['hateoas']:
            response[config.LINKS] = {
                'self': document_link(resource, document[config.ID_FIELD]),
                'collection': {'title':
                               config.DOMAIN[resource]['resource_title'],
                               'href': _collection_link(resource, True)},
                'parent': home_link()
            }

        # notify registered callback functions. Please note that, should the
        # functions modify the document, last_modified and etag  won't be
        # updated to reflect the changes (they always reflect the documents
        # state on the database).
        item_title = config.DOMAIN[resource]['item_title'].lower()

        getattr(app, "on_fetch_item")(resource, document[config.ID_FIELD],
                                      document)
        getattr(app, "on_fetch_item_%s" %
                item_title)(document[config.ID_FIELD], document)

        response.update(document)
        return response, last_modified, etag, 200

    abort(404)
Пример #24
0
Файл: get.py Проект: sunbit/eve
def _pagination_links(resource, req, document_count, document_id=None):
    """ Returns the appropriate set of resource links depending on the
    current page and the total number of documents returned by the query.

    :param resource: the resource name.
    :param req: and instace of :class:`eve.utils.ParsedRequest`.
    :param document_count: the number of documents returned by the query.
    :param document_id: the document id (used for versions). Defaults to None.

    .. versionchanged:: 0.5
       Create pagination links given a document ID to allow paginated versions
       pages (#475).
       Pagination links reflect current query. (#464)

    .. versionchanged:: 0.4
       HATEOAS link for contains the business unit value even when
       regexes have been configured for the resource endpoint.

    .. versionchanged:: 0.0.8
       Link to last page is provided if pagination is enabled (and the current
       page is not the last one).

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.5
       Support for optional pagination.

    .. versionchanged:: 0.0.3
       JSON links
    """
    version = None
    if config.DOMAIN[resource]["versioning"] is True:
        version = request.args.get(config.VERSION_PARAM)

    other_params = _other_params(req.args)
    # construct the default links
    q = querydef(req.max_results, req.where, req.sort, version, req.page, other_params)
    resource_title = config.DOMAIN[resource]["resource_title"]
    _links = {
        "parent": home_link(),
        "self": {"title": resource_title, "href": resource_link()},
    }

    # change links if document ID is given
    if document_id:
        _links["self"] = document_link(resource, document_id)
        _links["collection"] = {
            "title": resource_title,
            "href": "%s%s" % (resource_link(), q),
        }

        # make more specific links for versioned requests
        if version in ("all", "diffs"):
            _links["parent"] = {"title": resource_title, "href": resource_link()}
            _links["collection"] = document_link(resource, document_id)
        elif version:
            _links["parent"] = document_link(resource, document_id)
            _links["collection"] = {
                "title": resource_title,
                "href": "%s?version=all" % _links["parent"]["href"],
            }

    # modify the self link to add query params or version number
    if document_count:
        _links["self"]["href"] = "%s%s" % (_links["self"]["href"], q)
    elif not document_count and version and version not in ("all", "diffs"):
        _links["self"] = document_link(resource, document_id, version)

    # create pagination links
    if config.DOMAIN[resource]["pagination"]:
        # strip any queries from the self link if present
        _pagination_link = _links["self"]["href"].split("?")[0]

        if (
            req.page * req.max_results < (document_count or 0)
            or config.OPTIMIZE_PAGINATION_FOR_SPEED
        ):
            q = querydef(
                req.max_results,
                req.where,
                req.sort,
                version,
                req.page + 1,
                other_params,
            )
            _links["next"] = {
                "title": "next page",
                "href": "%s%s" % (_pagination_link, q),
            }

            if document_count:
                last_page = int(math.ceil(document_count / float(req.max_results)))
                q = querydef(
                    req.max_results,
                    req.where,
                    req.sort,
                    version,
                    last_page,
                    other_params,
                )
                _links["last"] = {
                    "title": "last page",
                    "href": "%s%s" % (_pagination_link, q),
                }

        if req.page > 1:
            q = querydef(
                req.max_results,
                req.where,
                req.sort,
                version,
                req.page - 1,
                other_params,
            )
            _links["prev"] = {
                "title": "previous page",
                "href": "%s%s" % (_pagination_link, q),
            }

    return _links
Пример #25
0
Файл: get.py Проект: Acapla/eve
def getitem(resource, **lookup):
    """
    :param resource: the name of the resource to which the document belongs.
    :param **lookup: the lookup query.

    .. versionchanged:: 0.4
       HATOEAS link for contains the business unit value even when
       regexes have been configured for the resource endpoint.
       'on_fetched' now returns the whole response (HATEOAS metafields
       included.)
       Support for document versioning.
       Changed ``on_fetch_*`` changed to ``on_fetched_*``.

    .. versionchanged:: 0.3
       Support for media fields.
       When IF_MATCH is disabled, no etag is included in the payload.

    .. versionchanged:: 0.1.1
       Support for Embeded Resource Serialization.

    .. versionchanged:: 0.1.0
       Support for optional HATEOAS.

    .. versionchanged: 0.0.8
       'on_getting_item' event is raised when a document has been read from the
       database and is about to be sent to the client.

    .. versionchanged:: 0.0.7
       Support for Rate-Limiting.

    .. versionchanged:: 0.0.6
       Support for HEAD requests.

    .. versionchanged:: 0.0.6
        ETag added to payload.

    .. versionchanged:: 0.0.5
       Support for user-restricted access to resources.
       Support for LAST_UPDATED field missing from documents, because they were
       created outside the API context.

    .. versionchanged:: 0.0.4
       Added the ``requires_auth`` decorator.

    .. versionchanged:: 0.0.3
       Superflous ``response`` container removed. Links wrapped with
       ``_links``. Links are now properly JSON formatted.
    """
    req = parse_request(resource)
    resource_def = config.DOMAIN[resource]
    embedded_fields = resolve_embedded_fields(resource, req)

    document = app.data.find_one(resource, req, **lookup)
    if not document:
        abort(404)

    response = {}
    etag = None
    version = request.args.get(config.VERSION_PARAM)
    latest_doc = None

    # synthesize old document version(s)
    if resource_def['versioning'] is True:
        latest_doc = copy.deepcopy(document)
        document = get_old_document(
            resource, req, lookup, document, version)

    # meld into response document
    build_response_document(document, resource, embedded_fields, latest_doc)

    # last_modified for the response
    last_modified = document[config.LAST_UPDATED]

    # facilitate client caching by returning a 304 when appropriate
    if config.IF_MATCH:
        etag = document[config.ETAG]

        if req.if_none_match and etag == req.if_none_match:
            # request etag matches the current server representation of the
            # document, return a 304 Not-Modified.
            return {}, last_modified, document[config.ETAG], 304

    if req.if_modified_since and last_modified <= req.if_modified_since:
        # request If-Modified-Since conditional request match. We test
        # this after the etag since Last-Modified dates have lower
        # resolution (1 second).
        return {}, last_modified, document.get(config.ETAG), 304

    if version == 'all' or version == 'diffs':
        # find all versions
        lookup[versioned_id_field()] = lookup[app.config['ID_FIELD']]
        del lookup[app.config['ID_FIELD']]
        if version == 'diffs' or req.sort is None:
            # default sort for 'all', required sort for 'diffs'
            req.sort = '[("%s", 1)]' % config.VERSION
        req.if_modified_since = None  # we always want the full history here
        cursor = app.data.find(resource + config.VERSIONS, req, lookup)

        # build all versions
        documents = []
        if cursor.count() == 0:
            # this is the scenario when the document existed before
            # document versioning got turned on
            documents.append(latest_doc)
        else:
            last_document = {}

            # if we aren't starting on page 1, then we need to init last_doc
            if version == 'diffs' and req.page > 1:
                # grab the last document on the previous page to diff from
                last_version = cursor[0][app.config['VERSION']] - 1
                last_document = get_old_document(
                    resource, req, lookup, latest_doc, last_version)

            for i, document in enumerate(cursor):
                document = synthesize_versioned_document(
                    latest_doc, document, resource_def)
                build_response_document(
                    document, resource, embedded_fields, latest_doc)
                if version == 'diffs':
                    if i == 0:
                        documents.append(document)
                    else:
                        documents.append(diff_document(
                            resource_def, last_document, document))
                    last_document = document
                else:
                    documents.append(document)

        # add documents to response
        if config.DOMAIN[resource]['hateoas']:
            response[config.ITEMS] = documents
        else:
            response = documents
    else:
        response = document

    # extra hateoas links
    if config.DOMAIN[resource]['hateoas']:
        if config.LINKS not in response:
            response[config.LINKS] = {}
        response[config.LINKS]['collection'] = {
            'title': config.DOMAIN[resource]['resource_title'],
            'href': resource_link()}
        response[config.LINKS]['parent'] = home_link()

    if version != 'all' and version != 'diffs':
        # TODO: callbacks not currently supported with ?version=all

        # notify registered callback functions. Please note that, should
        # the # functions modify the document, last_modified and etag
        # won't be updated to reflect the changes (they always reflect the
        # documents state on the database).
        getattr(app, "on_fetched_item")(resource, response)
        getattr(app, "on_fetched_item_%s" % resource)(response)

    return response, last_modified, etag, 200