1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-12 21:30:39 +00:00

public repo search (#3817)

* public repo search

* remove print code

* add permission check
This commit is contained in:
王健辉
2019-07-08 16:47:04 +08:00
committed by Daniel Pan
parent 97016a2e2b
commit 53a79ed706
4 changed files with 166 additions and 16 deletions

View File

@@ -1,12 +1,14 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import MediaQuery from 'react-responsive';
import { seafileAPI } from '../../utils/seafile-api';
import { gettext, siteRoot } from '../../utils/constants';
import SearchResultItem from './search-result-item';
import editorUtilities from '../../utils/editor-utilties';
import More from '../more';
const propTypes = {
isPublic: PropTypes.bool,
repoID: PropTypes.string,
placeholder: PropTypes.string,
onSearchedClick: PropTypes.func.isRequired,
@@ -93,27 +95,53 @@ class Search extends Component {
sendRequest(queryData, cancelToken) {
var _this = this;
editorUtilities.searchFiles(queryData,cancelToken).then(res => {
if (!res.data.total) {
let isPublic = this.props.isPublic;
if (isPublic) {
seafileAPI.searchPublicFiles(queryData.q, queryData.search_repo).then(res => {
if (!res.data.total) {
_this.setState({
resultItems: [],
isResultGetted: true
});
_this.source = null;
return;
}
let items = _this.formatResultItems(res.data.results);
_this.setState({
resultItems: [],
resultItems: items,
isResultGetted: true
});
_this.source = null;
return;
}
let items = _this.formatResultItems(res.data.results);
_this.setState({
resultItems: items,
isResultGetted: true
}).catch(res => {
/* eslint-disable */
console.log(res);
/* eslint-enable */
});
_this.source = null;
}).catch(res => {
/* eslint-disable */
console.log(res);
/* eslint-enable */
});
} else {
editorUtilities.searchFiles(queryData,cancelToken).then(res => {
if (!res.data.total) {
_this.setState({
resultItems: [],
isResultGetted: true
});
_this.source = null;
return;
}
let items = _this.formatResultItems(res.data.results);
_this.setState({
resultItems: items,
isResultGetted: true
});
_this.source = null;
}).catch(res => {
/* eslint-disable */
console.log(res);
/* eslint-enable */
});
}
}
cancelRequest() {

View File

@@ -7,6 +7,7 @@ import WikiMarkdownViewer from '../../components/wiki-markdown-viewer';
import WikiDirListView from '../../components/wiki-dir-list-view/wiki-dir-list-view';
import Loading from '../../components/loading';
import { Utils } from '../../utils/utils';
import Search from '../../components/search/search';
const propTypes = {
path: PropTypes.string.isRequired,
@@ -77,6 +78,21 @@ class MainPanel extends Component {
return (
<div className="main-panel wiki-main-panel o-hidden">
<div className="main-panel-north panel-top border-left-show">
{!username &&
<Fragment>
<div className="cur-view-toolbar">
<span className="sf2-icon-menu hidden-md-up d-md-none side-nav-toggle" title="Side Nav Menu" onClick={this.onMenuClick}></span>
</div>
<div className="common-toolbar">
<Search
isPublic={true}
repoID={repoID}
onSearchedClick={this.props.onSearchedClick}
placeholder={gettext('Search files in this library')}
/>
</div>
</Fragment>
}
{username && (
<Fragment>
<div className="cur-view-toolbar">

View File

@@ -0,0 +1,102 @@
# -*- coding: utf-8 -*-
import logging
from rest_framework.views import APIView
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from rest_framework import status
from seaserv import seafile_api
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error
from seahub.utils.repo import is_valid_repo_id_format
from seahub.utils import HAS_FILE_SEARCH
from seahub.wiki.models import Wiki
if HAS_FILE_SEARCH:
from seahub_extra.search.utils import search_files
logger = logging.getLogger('seafes')
class PublicReposSearchView(APIView):
""" Search public repos
"""
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticatedOrReadOnly,)
throttle_classes = (UserRateThrottle, )
def get(self, request):
# is search supported
if not HAS_FILE_SEARCH:
error_msg = 'Search not supported.'
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# argument check
keyword = request.GET.get('q', None)
if not keyword:
error_msg = 'q invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
search_repo = request.GET.get('search_repo', None)
if not is_valid_repo_id_format(search_repo):
error_msg = 'search_repo invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# recourse check
repo = seafile_api.get_repo(search_repo)
if not repo:
error_msg = 'Library %s not found.' % search_repo
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# permission check
wiki = Wiki.objects.filter(repo_id=search_repo)[0]
if not wiki.has_read_perm(request):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
try:
current_page = int(request.GET.get('page', '1'))
per_page = int(request.GET.get('per_page', '10'))
if per_page > 100:
per_page = 100
except ValueError:
current_page = 1
per_page = 10
start = (current_page - 1) * per_page
size = per_page
if start < 0 or size < 0:
error_msg = 'page or per_page invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
repo_id_map = {}
map_id = repo.origin_repo_id if repo.origin_repo_id else search_repo
repo_id_map[map_id] = repo
# search file
try:
results, total = search_files(
repo_id_map, None, keyword, None, start, size, org_id=None
)
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
for result in results:
result.pop('repo', None)
result.pop('exists', None)
result.pop('last_modified_by', None)
result.pop('name_highlight', None)
result.pop('score', None)
result['repo_type'] = 'public'
has_more = True if total > current_page * per_page else False
return Response({
"total": total,
"results": results,
"has_more": has_more
})

View File

@@ -89,6 +89,7 @@ from seahub.api2.endpoints.related_files import RelatedFilesView, RelatedFileVie
from seahub.api2.endpoints.webdav_secret import WebdavSecretView
from seahub.api2.endpoints.starred_items import StarredItems
from seahub.api2.endpoints.markdown_lint import MarkdownLintView
from seahub.api2.endpoints.public_repos_search import PublicReposSearchView
# Admin
from seahub.api2.endpoints.admin.revision_tag import AdminTaggedItemsView
@@ -359,6 +360,9 @@ urlpatterns = [
# user: markdown-lint
url(r'^api/v2.1/markdown-lint/$', MarkdownLintView.as_view(), name='api-v2.1-markdown-lint'),
# public repos search
url(r'^api/v2.1/public-repos-search/$', PublicReposSearchView.as_view(), name='api-v2.1-public-repos-search'),
# Deprecated
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/tags/$', FileTagsView.as_view(), name="api-v2.1-filetags-view"),
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/tags/(?P<name>.*?)/$', FileTagView.as_view(), name="api-v2.1-filetag-view"),