search_api.py
152 lines
| 5.4 KiB
| text/x-python
|
PythonLexer
r5048 | ||||
r3604 | ||||
r4306 | # Copyright (C) 2011-2020 RhodeCode GmbH | |||
r3604 | # | |||
# This program is free software: you can redistribute it and/or modify | ||||
# it under the terms of the GNU Affero General Public License, version 3 | ||||
# (only), as published by the Free Software Foundation. | ||||
# | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# | ||||
# You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | ||||
# This program is dual-licensed. If you wish to learn more about the | ||||
# RhodeCode Enterprise Edition, including its added features, Support services, | ||||
# and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
import logging | ||||
from rhodecode.api import jsonrpc_method | ||||
r4353 | from rhodecode.api.exc import JSONRPCValidationError, JSONRPCForbidden | |||
from rhodecode.api.utils import Optional, has_superadmin_permission | ||||
r3604 | from rhodecode.lib.index import searcher_from_config | |||
r4353 | from rhodecode.lib.user_log_filter import user_log_filter | |||
r3604 | from rhodecode.model import validation_schema | |||
r4353 | from rhodecode.model.db import joinedload, UserLog | |||
r3604 | from rhodecode.model.validation_schema.schemas import search_schema | |||
log = logging.getLogger(__name__) | ||||
@jsonrpc_method() | ||||
r3607 | def search(request, apiuser, search_query, search_type, page_limit=Optional(10), | |||
r3965 | page=Optional(1), search_sort=Optional('desc:date'), | |||
r3607 | repo_name=Optional(None), repo_group_name=Optional(None)): | |||
r3604 | """ | |||
r3607 | Fetch Full Text Search results using API. | |||
r3604 | ||||
:param apiuser: This is filled automatically from the |authtoken|. | ||||
:type apiuser: AuthUser | ||||
:param search_query: Search query. | ||||
:type search_query: str | ||||
r3605 | :param search_type: Search type. The following are valid options: | |||
* commit | ||||
* content | ||||
* path | ||||
r3604 | :type search_type: str | |||
r3605 | :param page_limit: Page item limit, from 1 to 500. Default 10 items. | |||
r3604 | :type page_limit: Optional(int) | |||
:param page: Page number. Default first page. | ||||
:type page: Optional(int) | ||||
r3965 | :param search_sort: Search sort order.Must start with asc: or desc: Default desc:date. | |||
The following are valid options: | ||||
* asc|desc:message.raw | ||||
* asc|desc:date | ||||
* asc|desc:author.email.raw | ||||
* asc|desc:message.raw | ||||
* newfirst (old legacy equal to desc:date) | ||||
* oldfirst (old legacy equal to asc:date) | ||||
r3604 | :type search_sort: Optional(str) | |||
:param repo_name: Filter by one repo. Default is all. | ||||
:type repo_name: Optional(str) | ||||
r3605 | :param repo_group_name: Filter by one repo group. Default is all. | |||
:type repo_group_name: Optional(str) | ||||
r3604 | """ | |||
data = {'execution_time': ''} | ||||
repo_name = Optional.extract(repo_name) | ||||
r3605 | repo_group_name = Optional.extract(repo_group_name) | |||
r3604 | ||||
schema = search_schema.SearchParamsSchema() | ||||
try: | ||||
search_params = schema.deserialize( | ||||
dict(search_query=search_query, | ||||
search_type=search_type, | ||||
search_sort=Optional.extract(search_sort), | ||||
page_limit=Optional.extract(page_limit), | ||||
requested_page=Optional.extract(page)) | ||||
) | ||||
except validation_schema.Invalid as err: | ||||
raise JSONRPCValidationError(colander_exc=err) | ||||
search_query = search_params.get('search_query') | ||||
search_type = search_params.get('search_type') | ||||
search_sort = search_params.get('search_sort') | ||||
if search_params.get('search_query'): | ||||
page_limit = search_params['page_limit'] | ||||
requested_page = search_params['requested_page'] | ||||
r3607 | searcher = searcher_from_config(request.registry.settings) | |||
r3604 | try: | |||
search_result = searcher.search( | ||||
r3606 | search_query, search_type, apiuser, repo_name, repo_group_name, | |||
requested_page=requested_page, page_limit=page_limit, sort=search_sort) | ||||
r3604 | ||||
data.update(dict( | ||||
results=list(search_result['results']), page=requested_page, | ||||
item_count=search_result['count'], | ||||
items_per_page=page_limit)) | ||||
finally: | ||||
searcher.cleanup() | ||||
if not search_result['error']: | ||||
r3853 | data['execution_time'] = '%s results (%.4f seconds)' % ( | |||
r3604 | search_result['count'], | |||
search_result['runtime']) | ||||
else: | ||||
node = schema['search_query'] | ||||
r3607 | raise JSONRPCValidationError( | |||
colander_exc=validation_schema.Invalid(node, search_result['error'])) | ||||
r3604 | ||||
return data | ||||
r4353 | ||||
@jsonrpc_method() | ||||
def get_audit_logs(request, apiuser, query): | ||||
""" | ||||
return full audit logs based on the query. | ||||
Please see `example query in admin > settings > audit logs` for examples | ||||
:param apiuser: This is filled automatically from the |authtoken|. | ||||
:type apiuser: AuthUser | ||||
:param query: filter query, example: action:repo.artifact.add date:[20200401 TO 20200601]" | ||||
:type query: str | ||||
""" | ||||
if not has_superadmin_permission(apiuser): | ||||
raise JSONRPCForbidden() | ||||
filter_term = query | ||||
ret = [] | ||||
# show all user actions | ||||
user_log = UserLog.query() \ | ||||
.options(joinedload(UserLog.user)) \ | ||||
.options(joinedload(UserLog.repository)) \ | ||||
.order_by(UserLog.action_date.desc()) | ||||
audit_log = user_log_filter(user_log, filter_term) | ||||
for entry in audit_log: | ||||
ret.append(entry) | ||||
return ret | ||||