Esempio n. 1
0
def api():
    """Search API for search UI demo.

    .. note::

        WARNING! This search API is just for demo proposes only.

    """
    page = request.values.get('page', 1, type=int)
    size = request.values.get('size', 1, type=int)
    query = Query(request.values.get('q', ''))[(page-1)*size:page*size]
    # dummy facets
    query.body["aggs"] = {
        "by_body": {
            "terms": {
                "field": "summary.summary"
            }
        },
        "by_title": {
            "terms": {
                "field": "title_statement.title"
            }
        }
    }
    response = current_search_client.search(
        index=request.values.get('index', 'records'),
        doc_type=request.values.get('type'),
        body=query.body,
    )
    return jsonify(**response)
Esempio n. 2
0
def es_query_factory(index, page, size):
    """Send query directly as query string query to Elasticsearch.

    .. warning:

       All fields in a record that a user can access are searchable! This means
       that if a user can access a record, you cannot include confidential
       information into the record (or you must remove it when indexing).
       Otherwise a user is able to search for the information.

       The reason is that the query string is passed directly to Elasticsearch,
       which takes care of parsing the string.

    :param index: Index to search in.
    :param page: Requested page.
    :param size: Request results size.
    :returns: Tuple of (query, URL arguments).
    """
    query_string = request.values.get('q', '')

    query = Query()
    if query_string.strip():
        query.body['query'] = dict(query_string=dict(
            query=query_string,
            allow_leading_wildcard=False,
        ))
    query = query[(page - 1) * size:page * size]
    return (query, {'q': query_string})
Esempio n. 3
0
def es_query_factory(index, page, size):
    """Send query directly as query string query to Elasticsearch.

    .. warning:

       All fields in a record that a user can access are searchable! This means
       that if a user can access a record, you cannot include confidential
       information into the record (or you must remove it when indexing).
       Otherwise a user is able to search for the information.

       The reason is that the query string is passed directly to Elasticsearch,
       which takes care of parsing the string.

    :param index: Index to search in.
    :param page: Requested page.
    :param size: Request results size.
    :returns: Tuple of (query, URL arguments).
    """
    query_string = request.values.get('q', '')

    query = Query()
    if query_string.strip():
        query.body['query'] = dict(
            query_string=dict(
                query=query_string,
                allow_leading_wildcard=False,
            )
        )
    query = query[(page-1)*size:page*size]
    return (query, {'q': query_string})
Esempio n. 4
0
def index():
    """Frontpage blueprint."""
    query = Query("")
    query.body["size"] = 10
    query.body["sort"] = [{"creation_date": "desc"}]

    response = current_search_client.search(
        index='records',
        body=query.body,
    )

    return render_template('zenodo_frontpage/index.html',
                           records=(h['_source']
                                    for h in response['hits']['hits']))
Esempio n. 5
0
def index():
    """Frontpage blueprint."""
    query = Query("communities:zenodo AND access_right:open")
    query.body["size"] = 10
    query.body["sort"] = [{"creation_date": "desc"}]

    response = current_search_client.search(
        index='records',
        body=query.body,
    )

    return render_template(
        'zenodo_frontpage/index.html',
        records=(h['_source'] for h in response['hits']['hits'])
    )
Esempio n. 6
0
def default_query_factory(index, page, size, query_string=None):
    """Create default ES query based on query-string pattern."""
    if not query_string:
        query_string = request.values.get('q', '')

    query = Query()
    if query_string.strip():
        query.body['query'] = dict(
            query_string=dict(
                query=query_string,
                allow_leading_wildcard=False,
            )
        )
    query = query[(page-1)*size:page*size]
    return (query, {'q': query_string})
Esempio n. 7
0
def submit_set():
    """Insert a new set."""
    form = get_NewSetForm(request.form)
    if request.method == 'POST' and form.validate():
        new_set = OAISet(spec=form.spec.data,
                         name=form.name.data,
                         description=form.description.data,
                         search_pattern=form.search_pattern.data,
                         parent=form.parent.data)
        db.session.add(new_set)

        # this shoul be moved to UPDATER (celery task) and it sould always
        # take care of adding records to sets.
        ##########
        query = Query(form.query.data)
        response = current_search_client.search(
            index='records',  # make configurable PER SET
            doc_type='record',  # make configurable PER SET
            body=query.body,
            fields='_id, oaiid'  # path to oaiid as a configurable
        )
        ids = [(a['_id'], a['oaiid']) for a in response['hits']['hits']]
        add_records_to_set(ids)
        #########

        db.session.commit()
        flash(_('New set %(spec)s was added.', spec=new_set.spec))
        return redirect(url_for('.manage_sets'))
    return render_template('make_set.html', new_set_form=form)
Esempio n. 8
0
    def get(self, **kwargs):
        """Search records.

        :returns: the search result containing hits and aggregations as
        returned by invenio-search.
        """
        page = request.values.get('page', 1, type=int)
        size = request.values.get('size', 10, type=int)
        if page*size >= self.max_result_window:
            raise MaxResultWindowRESTError()

        # Parse and slice query
        try:
            query = Query(request.values.get('q', ''))[(page-1)*size:page*size]
        except SyntaxError:
            raise InvalidQueryRESTError()

        # Arguments that must be added in prev/next links
        urlkwargs = dict()

        # Facets
        query, qs_kwargs = self.facets_factory(query, self.search_index)
        urlkwargs.update(qs_kwargs)

        # Sort
        query, qs_kwargs = self.sorter_factory(query, self.search_index)
        urlkwargs.update(qs_kwargs)

        # Execute search
        response = current_search_client.search(
            index=self.search_index,
            doc_type=self.search_type,
            body=query.body,
            version=True,
        )

        # Generate links for prev/next
        urlkwargs.update(
            size=size,
            q=request.values.get('q', ''),
            _external=True,
        )
        endpoint = 'invenio_records_rest.{0}_list'.format(self.pid_type)
        links = dict(self=url_for(endpoint, page=page, **urlkwargs))
        if page > 1:
            links['prev'] = url_for(endpoint, page=page-1, **urlkwargs)
        if size * page < int(response['hits']['total']) and \
                size * page < self.max_result_window:
            links['next'] = url_for(endpoint, page=page+1, **urlkwargs)

        return self.make_response(
            pid_fetcher=self.pid_fetcher,
            search_result=response,
            links=links,
        )
def index():
    """Query Elasticsearch using Invenio query syntax."""
    page = request.values.get('page', 1, type=int)
    size = request.values.get('size', 1, type=int)
    query = Query(request.values.get('q', ''))[(page - 1) * size:page * size]
    response = current_search_client.search(
        index=request.values.get('index', 'demo'),
        doc_type=request.values.get('type'),
        body=query.body,
    )
    return jsonify(**response)
Esempio n. 10
0
    def get(self, **kwargs):
        """Search records.

        :returns: the search result containing hits and aggregations as
        returned by invenio-search.
        """
        page = request.values.get("page", 1, type=int)
        size = request.values.get("size", 10, type=int)
        sort = request.values.get("sort", "", type=str)
        query = Query(request.values.get("q", ""))[(page - 1) * size : page * size]

        for sort_key in sort.split(","):
            if sort_key:
                query = query.sort(sort_key)

        response = current_search_client.search(
            index=self.search_index, doc_type=self.search_type, body=query.body, version=True
        )
        links = {}
        if page > 1:
            links["prev"] = url_for(
                "invenio_records_rest.{0}_list".format(self.pid_type),
                page=page - 1,
                size=size,
                sort=sort,
                q=request.values.get("q", ""),
                _external=True,
            )
        if size * page < int(response["hits"]["total"]):
            links["next"] = url_for(
                "invenio_records_rest.{0}_list".format(self.pid_type),
                page=page + 1,
                size=size,
                sort=sort,
                q=request.values.get("q", ""),
                _external=True,
            )

        return self.make_response(pid_fetcher=self.pid_fetcher, search_result=response, links=links)
Esempio n. 11
0
def submit_edit_set(spec):
    """Insert a new set."""
    form = get_NewSetForm(request.form)
    if request.method == 'POST' and form.validate():
        old_set = OAISet.query.filter(spec=spec)
        query = Query(old_set.search_pattern)
        old_recid = current_search_client.search(index='records',
                                                 doc_type='record',
                                                 body=query.body,
                                                 fields='_id, oaiid')
        query = Query(form.search_pattern)
        new_recid = current_search_client.search(index='records',
                                                 doc_type='record',
                                                 body=query.body,
                                                 fields='_id, oaiid')
        recids_to_delete = set(old_recid) - set(new_recid)
        # TODO: marks records as deleted from set
        remove_recids_from_set(recids_to_delete)
        add_records_to_set(new_recid)
        flash('Set was changed')
        return redirect(url_for('.manage_sets'))
    return render_template('edit_set.html', edit_set_form=form, spec=spec)
Esempio n. 12
0
    def get_expired_embargos(cls):
        """Get records for which the embargo period have expired."""
        query_str = 'access_right:{0} AND embargo_date:{{* TO {1}}}'.format(
            cls.EMBARGOED,
            datetime.utcnow().isoformat()
        )

        query = Query()
        query.body['from'] = 0
        query.body['size'] = 1000
        query.body['query'] = {
            'query_string': {
                'query': query_str,
                'allow_leading_wildcard': False,
            },
        }

        endpoints = current_app.config['RECORDS_REST_ENDPOINTS']
        index = endpoints['recid']['search_index']

        response = current_search_client.search(
            index=index, body=query.body
        )
        return [hit['_id'] for hit in response['hits']['hits']]
Esempio n. 13
0
def default_query_factory(index, page, size):
    """Parse and slice query using Invenio-Query-Parser.

    :param index: Index to search in.
    :param page: Requested page.
    :param size: Request results size.
    :returns: Tuple of (query, URL arguments).
    """
    query_string = request.values.get('q', '')

    try:
        query = Query(query_string)[(page - 1) * size:page * size]
    except SyntaxError:
        current_app.logger.debug("Failed parsing query: {0}".format(
            request.values.get('q', '')),
                                 exc_info=True)
        raise InvalidQueryRESTError()

    return (query, {'q': query_string})