Esempio n. 1
0
def search(
    *,
    db_session: Session = Depends(get_db),
    skip: int = 0,
    limit: int = 10,
    q: str = None,
    type: List[str] = [
        v.value for v in SearchTypes
    ],  # hack for pydantic enum json generation see: https://github.com/samuelcolvin/pydantic/pull/1749
    current_user: DispatchUser = Depends(get_current_user),
):
    """
    Perform a search.
    """
    if q:
        models = [get_class_by_tablename(t) for t in type]
        results = composite_search(db_session=db_session,
                                   query_str=q,
                                   models=models)
    else:
        results = []

    # add a filter for restricted incidents
    if current_user.role != UserRoles.admin:
        results["Incident"] = [
            i for i in results["Incident"] if i.visibility == Visibility.open
        ]

    return SearchResponse(**{
        "query": q,
        "results": results
    }).dict(by_alias=False)
Esempio n. 2
0
def match(*, db_session, filter_spec: List[dict], class_instance: Base):
    """Matches an class instance with a given search filter."""
    table_name = get_table_name_by_class_instance(class_instance)
    model_cls = get_class_by_tablename(table_name)
    query = db_session.query(model_cls)
    query = apply_filters(query, filter_spec)
    return query.filter(model_cls.id == class_instance.id).one_or_none()
Esempio n. 3
0
def search(
    *,
    db_session: Session = Depends(get_db),
    skip: int = 0,
    limit: int = 10,
    q: str = None,
    type: List[str] = [
        v.value for v in SearchTypes
    ],  # hack for pydantic enum json generation see: https://github.com/samuelcolvin/pydantic/pull/1749
    current_user: DispatchUser = Depends(get_current_user),
):
    """
    Perform a search.
    """
    if q:
        models = [get_class_by_tablename(t) for t in type]
        results = composite_search(db_session=db_session,
                                   query_str=q,
                                   models=models)
    else:
        results = []

    # add a filter for restricted incidents
    if current_user.role != UserRoles.admin:
        filtered_results = []
        for r in results:
            if r["type"].lower() == "incident":
                if r["content"].visibility != Visibility.open:
                    continue
            filtered_results.append(r)
        results = filtered_results
    return {"query": q, "results": results}
Esempio n. 4
0
def search(*, query_str: str, query: Query, model: str, sort=False):
    """Perform a search based on the query."""
    search_model = get_class_by_tablename(model)

    if not query_str.strip():
        return query

    vector = search_model.search_vector

    query = query.filter(vector.op("@@")(func.tsq_parse(query_str)))
    if sort:
        query = query.order_by(
            desc(func.ts_rank_cd(vector, func.tsq_parse(query_str))))

    return query.params(term=query_str)
Esempio n. 5
0
def get_tag_recommendations(*,
                            db_session: Session = Depends(get_db),
                            model_name: str,
                            id: int):
    """
    Retrieves a tag recommendation based on the model and model id.
    """
    model_object = get_class_by_tablename(model_name)
    model = db_session.query(model_object).filter(
        model_object.id == id).one_or_none()

    if not model:
        raise HTTPException(
            status_code=404,
            detail=f"No model found. ModelName: {model_name} Id: {id}")

    tags = get_recommendations(db_session, [t.id for t in model.tags],
                               model_name)
    return {"items": tags, "total": len(tags)}
Esempio n. 6
0
def search(
    *,
    db_session: Session = Depends(get_db),
    skip: int = 0,
    limit: int = 10,
    q: str = None,
    type: List[SearchTypes] = SearchTypes,
):
    """
    Perform a search.
    """
    if q:
        models = [get_class_by_tablename(t.name) for t in type]
        results = composite_search(db_session=db_session,
                                   query_str=q,
                                   models=models)
    else:
        results = []

    return {"query": q, "results": results}
Esempio n. 7
0
def search(
    *,
    db_session: Session = Depends(get_db),
    skip: int = 0,
    limit: int = 10,
    q: str = None,
    type: List[str] = [
        v.value for v in SearchTypes
    ],  # hack for pydantic enum json generation see: https://github.com/samuelcolvin/pydantic/pull/1749
):
    """
    Perform a search.
    """
    if q:
        models = [get_class_by_tablename(t.name) for t in type]
        results = composite_search(db_session=db_session,
                                   query_str=q,
                                   models=models)
    else:
        results = []

    return {"query": q, "results": results}
Esempio n. 8
0
def search_filter_sort_paginate(
    db_session,
    model,
    query_str: str = None,
    page: int = 1,
    items_per_page: int = 5,
    sort_by: List[str] = None,
    descending: List[bool] = None,
    fields: List[str] = None,
    ops: List[str] = None,
    values: List[str] = None,
    current_user: DispatchUser = None,
    role: UserRoles = UserRoles.CUSTOMER,
):
    """Common functionality for searching, filtering, sorting, and pagination."""
    model_cls = get_class_by_tablename(model)
    try:
        query = db_session.query(model_cls)

        if query_str:
            sort = False if sort_by else True
            query = search(query_str=query_str,
                           query=query,
                           model=model,
                           sort=sort)

        query = apply_model_specific_filters(model_cls, query, current_user,
                                             role)

        filter_spec = create_filter_spec(model, fields, ops, values)
        query = apply_filters(query, filter_spec)

        if sort_by:
            sort_spec = create_sort_spec(model, sort_by, descending)
            query = apply_sort(query, sort_spec)

    except FieldNotFound as e:
        raise ValidationError(
            [
                ErrorWrapper(FieldNotFoundError(msg=str(e)), loc="filter"),
            ],
            model=BaseModel,
        )
    except BadFilterFormat as e:
        raise ValidationError(
            [ErrorWrapper(InvalidFilterError(msg=str(e)), loc="filter")],
            model=BaseModel)

    if items_per_page == -1:
        items_per_page = None

    # sometimes we get bad input for the search function
    # TODO investigate moving to a different way to parsing queries that won't through errors
    # e.g. websearch_to_tsquery
    # https://www.postgresql.org/docs/current/textsearch-controls.html
    try:
        query, pagination = apply_pagination(query,
                                             page_number=page,
                                             page_size=items_per_page)
    except sqlalchemy.exc.ProgrammingError as e:
        log.debug(e)
        return {
            "items": [],
            "itemsPerPage": items_per_page,
            "page": page,
            "total": 0,
        }

    return {
        "items": query.all(),
        "itemsPerPage": pagination.page_size,
        "page": pagination.page_number,
        "total": pagination.total_results,
    }
Esempio n. 9
0
def get_all(*, db_session, model):
    """Fetches a query object based on the model class name."""
    return db_session.query(get_class_by_tablename(model))
Esempio n. 10
0
def match(*, db_session, filter_spec, model, model_id: int):
    """Matches an incident with a given search filter."""
    model_cls = get_class_by_tablename(model)
    query = db_session.query(model_cls)
    query = apply_filters(query, filter_spec)
    return query.filter(model.id == model_id).one_or_none()