mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-09 10:50:24 +00:00
12.0 change sdoc content (#6121)
* fix warnings in 12.0 * get wiki sdoc content from sdoc server * optimize code * change page search params * Add repo_name for wiki name --------- Co-authored-by: ‘JoinTyang’ <yangtong1009@163.com>
This commit is contained in:
@@ -4,7 +4,8 @@ import MediaQuery from 'react-responsive';
|
||||
import { Modal } from 'reactstrap';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import wikiAPI from '../../utils/wiki-api';
|
||||
import { slug, wikiId, siteRoot, initialPath, isDir, sharedToken, hasIndex, lang, isWiki2, gettext } from '../../utils/constants';
|
||||
import SDocServerApi from '../../utils/sdoc-server-api';
|
||||
import { slug, wikiId, siteRoot, initialPath, isDir, sharedToken, hasIndex, lang, isWiki2, seadocServerUrl } from '../../utils/constants';
|
||||
import Dirent from '../../models/dirent';
|
||||
import WikiConfig from './models/wiki-config';
|
||||
import TreeNode from '../../components/tree-view/tree-node';
|
||||
@@ -33,7 +34,7 @@ class Wiki extends Component {
|
||||
isViewFile: true,
|
||||
isDataLoading: false,
|
||||
direntList: [],
|
||||
content: '',
|
||||
editorContent: {},
|
||||
permission: '',
|
||||
lastModified: '',
|
||||
latestContributor: '',
|
||||
@@ -47,7 +48,6 @@ class Wiki extends Component {
|
||||
config: new WikiConfig({}),
|
||||
repoId: '',
|
||||
seadoc_access_token: '',
|
||||
docUuid: '',
|
||||
assets_url: '',
|
||||
};
|
||||
|
||||
@@ -200,24 +200,41 @@ class Wiki extends Component {
|
||||
window.history.pushState({ url: fileUrl, path: dirPath }, dirPath, fileUrl);
|
||||
};
|
||||
|
||||
getSdocFileContent = (docUuid, accessToken) => {
|
||||
const config = {
|
||||
docUuid,
|
||||
sdocServer: seadocServerUrl,
|
||||
accessToken,
|
||||
};
|
||||
const sdocServerApi = new SDocServerApi(config);
|
||||
sdocServerApi.getDocContent().then(res => {
|
||||
this.setState({
|
||||
isDataLoading: false,
|
||||
editorContent: res.data,
|
||||
});
|
||||
}).catch(error => {
|
||||
let errorMsg = Utils.getErrorMsg(error);
|
||||
toaster.danger(errorMsg);
|
||||
});
|
||||
};
|
||||
|
||||
showFile = (filePath) => {
|
||||
this.setState({
|
||||
isDataLoading: true,
|
||||
});
|
||||
this.removePythonWrapper();
|
||||
wikiAPI.getWiki2FileContent(wikiId, filePath).then(res => {
|
||||
let data = res.data;
|
||||
const { permission, last_modified, latest_contributor, seadoc_access_token, assets_url } = res.data;
|
||||
this.setState({
|
||||
isDataLoading: false,
|
||||
content: data.content,
|
||||
permission: data.permission,
|
||||
lastModified: moment.unix(data.last_modified).fromNow(),
|
||||
latestContributor: data.latest_contributor,
|
||||
seadoc_access_token: data.seadoc_access_token,
|
||||
assets_url: data.assets_url,
|
||||
permission,
|
||||
lastModified: moment.unix(last_modified).fromNow(),
|
||||
latestContributor: latest_contributor,
|
||||
seadoc_access_token,
|
||||
assets_url,
|
||||
isViewFile: true,
|
||||
path: filePath,
|
||||
});
|
||||
const docUuid = assets_url.slice(assets_url.lastIndexOf('/') + 1);
|
||||
this.getSdocFileContent(docUuid, seadoc_access_token);
|
||||
}).catch(error => {
|
||||
let errorMsg = Utils.getErrorMsg(error);
|
||||
toaster.danger(errorMsg);
|
||||
@@ -541,6 +558,36 @@ class Wiki extends Component {
|
||||
node.addChildren(nodeList);
|
||||
};
|
||||
|
||||
showPage = (pageId, filePath) => {
|
||||
this.setState({
|
||||
isDataLoading: true,
|
||||
});
|
||||
|
||||
this.removePythonWrapper();
|
||||
wikiAPI.getWiki2Page(wikiId, pageId).then(res => {
|
||||
const { permission, last_modified, latest_contributor, seadoc_access_token, assets_url } = res.data;
|
||||
this.setState({
|
||||
permission,
|
||||
lastModified: moment.unix(last_modified).fromNow(),
|
||||
latestContributor: latest_contributor,
|
||||
seadoc_access_token,
|
||||
assets_url,
|
||||
isViewFile: true,
|
||||
path: filePath,
|
||||
});
|
||||
const docUuid = assets_url.slice(assets_url.lastIndexOf('/') + 1);
|
||||
this.getSdocFileContent(docUuid, seadoc_access_token);
|
||||
}).catch(error => {
|
||||
let errorMsg = Utils.getErrorMsg(error);
|
||||
toaster.danger(errorMsg);
|
||||
});
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.set('page_id', pageId);
|
||||
const fileUrl = `${siteRoot}${this.handlePath()}${wikiId}/?${params.toString()}`;
|
||||
window.history.pushState({ url: fileUrl, path: filePath }, filePath, fileUrl);
|
||||
};
|
||||
|
||||
setCurrentPage = (pageId, callback) => {
|
||||
const { currentPageId, config } = this.state;
|
||||
if (pageId === currentPageId) {
|
||||
@@ -552,7 +599,7 @@ class Wiki extends Component {
|
||||
const path = currentPage.path;
|
||||
if (Utils.isMarkdownFile(path) || Utils.isSdocFile(path)) {
|
||||
if (path !== this.state.path) {
|
||||
this.showFile(path);
|
||||
this.showPage(pageId, path);
|
||||
}
|
||||
this.onCloseSide();
|
||||
} else {
|
||||
@@ -602,7 +649,7 @@ class Wiki extends Component {
|
||||
pathExist={this.state.pathExist}
|
||||
isViewFile={this.state.isViewFile}
|
||||
isDataLoading={this.state.isDataLoading}
|
||||
content={this.state.content}
|
||||
editorContent={this.state.editorContent}
|
||||
permission={this.state.permission}
|
||||
lastModified={this.state.lastModified}
|
||||
latestContributor={this.state.latestContributor}
|
||||
|
@@ -12,7 +12,7 @@ const propTypes = {
|
||||
pathExist: PropTypes.bool.isRequired,
|
||||
isViewFile: PropTypes.bool.isRequired,
|
||||
isDataLoading: PropTypes.bool.isRequired,
|
||||
content: PropTypes.string,
|
||||
editorContent: PropTypes.object,
|
||||
permission: PropTypes.string,
|
||||
lastModified: PropTypes.string,
|
||||
latestContributor: PropTypes.string,
|
||||
@@ -103,13 +103,11 @@ class MainPanel extends Component {
|
||||
|
||||
render() {
|
||||
const errMessage = (<div className="message err-tip">{gettext('Folder does not exist.')}</div>);
|
||||
const { content, permission, pathExist, isDataLoading, isViewFile } = this.props;
|
||||
const { permission, pathExist, isDataLoading, isViewFile } = this.props;
|
||||
const isViewingFile = pathExist && !isDataLoading && isViewFile;
|
||||
const editorContent = content && JSON.parse(content);
|
||||
const isReadOnly = !(permission === 'rw');
|
||||
return (
|
||||
<div className="wiki2-main-panel">
|
||||
<div className="main-panel-hide hide">{this.props.content}</div>
|
||||
<div className='wiki2-main-panel-north'>
|
||||
<WikiTopNav
|
||||
config={this.props.config}
|
||||
@@ -125,7 +123,7 @@ class MainPanel extends Component {
|
||||
{this.props.pathExist && this.props.isDataLoading && <Loading />}
|
||||
{isViewingFile && Utils.isSdocFile(this.props.path) && (
|
||||
<SdocWikiViewer
|
||||
document={editorContent}
|
||||
document={this.props.editorContent}
|
||||
showOutline={false}
|
||||
showToolbar={false}
|
||||
docUuid={this.state.docUuid}
|
||||
|
@@ -122,6 +122,8 @@ export const sharedType = window.wiki ? window.wiki.config.sharedType : '';
|
||||
export const hasIndex = window.wiki ? window.wiki.config.hasIndex : '';
|
||||
export const assetsUrl = window.wiki ? window.wiki.config.assetsUrl : '';
|
||||
export const isWiki2 = window.wiki ? window.wiki.config.isWiki2 : false;
|
||||
export const seadocServerUrl = window.wiki ? window.wiki.config.seadocServerUrl : '';
|
||||
export const seadocAccessToken = window.wiki ? window.wiki.config.seadocAccessToken : '';
|
||||
|
||||
// file history
|
||||
export const PER_PAGE = 25;
|
||||
|
19
frontend/src/utils/sdoc-server-api.js
Normal file
19
frontend/src/utils/sdoc-server-api.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import axios from 'axios';
|
||||
|
||||
class SDocServerApi {
|
||||
|
||||
constructor(options) {
|
||||
this.server = options.sdocServer;
|
||||
this.docUuid = options.docUuid;
|
||||
this.accessToken = options.accessToken;
|
||||
}
|
||||
|
||||
getDocContent() {
|
||||
const { server, docUuid, accessToken } = this;
|
||||
const url = `${server}/api/v1/docs/${docUuid}/`;
|
||||
return axios.get(url, { headers: { Authorization: `Token ${accessToken}` } });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default SDocServerApi;
|
@@ -189,7 +189,6 @@ class WikiAPI {
|
||||
}
|
||||
|
||||
deleteWiki2Page(wikiId, pageId) {
|
||||
// const path = encodeURIComponent(pagePath);
|
||||
const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/page/' + pageId + '/';
|
||||
return this.req.delete(url);
|
||||
}
|
||||
@@ -199,6 +198,11 @@ class WikiAPI {
|
||||
return this.req.delete(url);
|
||||
}
|
||||
|
||||
getWiki2Page(wikiId, pageId) {
|
||||
const url = this.server + '/api/v2.1/wiki2/' + wikiId + '/page/' + pageId + '/';
|
||||
return this.req.get(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let wikiAPI = new WikiAPI();
|
||||
|
@@ -556,6 +556,70 @@ class Wiki2PageView(APIView):
|
||||
permission_classes = (IsAuthenticated, )
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
def get(self, request, wiki_id, page_id):
|
||||
|
||||
try:
|
||||
wiki = Wiki.objects.get(id=wiki_id)
|
||||
except Wiki.DoesNotExist:
|
||||
error_msg = "Wiki not found."
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
username = request.user.username
|
||||
if not check_wiki_permission(wiki, username):
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
repo_id = wiki.repo_id
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
error_msg = 'Library %s not found.' % repo_id
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
wiki_config = get_wiki_config(repo_id, username)
|
||||
pages = wiki_config.get('pages', [])
|
||||
page_info = next(filter(lambda t: t['id'] == page_id, pages), {})
|
||||
path = page_info.get('path')
|
||||
doc_uuid = page_info.get('docUuid')
|
||||
|
||||
permission = check_folder_permission(request, wiki.repo_id, '/')
|
||||
if not permission:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
try:
|
||||
file_id = seafile_api.get_file_id_by_path(repo.repo_id, path)
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
return api_error(HTTP_520_OPERATION_FAILED,
|
||||
"Failed to get file id by path.")
|
||||
if not file_id:
|
||||
return api_error(status.HTTP_404_NOT_FOUND, "File not found")
|
||||
|
||||
# send stats message
|
||||
send_file_access_msg(request, repo, path, 'api')
|
||||
|
||||
filename = os.path.basename(path)
|
||||
try:
|
||||
dirent = seafile_api.get_dirent_by_path(repo.repo_id, path)
|
||||
if dirent:
|
||||
latest_contributor, last_modified = dirent.modifier, dirent.mtime
|
||||
else:
|
||||
latest_contributor, last_modified = None, 0
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
latest_contributor, last_modified = None, 0
|
||||
|
||||
assets_url = '/api/v2.1/seadoc/download-image/' + doc_uuid
|
||||
seadoc_access_token = gen_seadoc_access_token(doc_uuid, filename, request.user.username, permission=permission)
|
||||
|
||||
return Response({
|
||||
"latest_contributor": email2nickname(latest_contributor),
|
||||
"last_modified": last_modified,
|
||||
"permission": permission,
|
||||
"seadoc_access_token": seadoc_access_token,
|
||||
"assets_url": assets_url,
|
||||
})
|
||||
|
||||
def delete(self, request, wiki_id, page_id):
|
||||
try:
|
||||
wiki = Wiki.objects.get(id=wiki_id)
|
||||
@@ -579,6 +643,10 @@ class Wiki2PageView(APIView):
|
||||
page_info = next(filter(lambda t: t['id'] == page_id, pages), {})
|
||||
path = page_info.get('path')
|
||||
|
||||
if not page_info:
|
||||
error_msg = 'page %s not found.' % page_id
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# check file lock
|
||||
try:
|
||||
is_locked, locked_by_me = check_file_lock(repo_id, path, username)
|
||||
|
@@ -43,12 +43,9 @@
|
||||
window.wiki = {
|
||||
config: {
|
||||
wikiId: "{{ wiki.id }}",
|
||||
repoId: "{{ wiki.repo_id }}",
|
||||
repoName: "{{ wiki.name }}",
|
||||
initial_path: "{{ file_path|escapejs }}",
|
||||
isDir: "{{ is_dir }}",
|
||||
isWiki2: true,
|
||||
assetsUrl: "{{ assets_url }}",
|
||||
seadocServerUrl: "{{ seadoc_server_url }}",
|
||||
seadocAccessToken: "{{ seadoc_access_token }}",
|
||||
permission: "{{ permission }}",
|
||||
|
@@ -712,7 +712,7 @@ urlpatterns = [
|
||||
re_path(r'^api/v2.1/admin/invitations/$', AdminInvitations.as_view(), name='api-v2.1-admin-invitations'),
|
||||
re_path(r'^api/v2.1/admin/invitations/(?P<token>[a-f0-9]{32})/$', AdminInvitation.as_view(), name='api-v2.1-admin-invitation'),
|
||||
|
||||
re_path(r'^wikis/(?P<wiki_id>[^/]+)/(?P<file_path>.*)$', wiki_view, name='wiki'),
|
||||
re_path(r'^wikis/(?P<wiki_id>[^/]+)/$', wiki_view, name='wiki'),
|
||||
|
||||
path('avatar/', include('seahub.avatar.urls')),
|
||||
path('notice/', include('seahub.notifications.urls')),
|
||||
|
@@ -18,7 +18,7 @@ from seahub.utils import get_file_type_and_ext, render_permission_error, is_pro_
|
||||
from seahub.utils.file_types import IMAGE, SEADOC
|
||||
from seahub.seadoc.utils import get_seadoc_file_uuid, gen_seadoc_access_token
|
||||
from seahub.auth.decorators import login_required
|
||||
from seahub.wiki2.utils import can_edit_wiki, check_wiki_permission
|
||||
from seahub.wiki2.utils import can_edit_wiki, check_wiki_permission, get_wiki_config
|
||||
|
||||
from seahub.utils.file_op import check_file_lock, ONLINE_OFFICE_LOCK_OWNER, if_locked_by_online_office
|
||||
from seahub.utils.repo import parse_repo_perm
|
||||
@@ -29,41 +29,35 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@login_required
|
||||
def wiki_view(request, wiki_id, file_path):
|
||||
def wiki_view(request, wiki_id):
|
||||
""" edit wiki page. for wiki2
|
||||
"""
|
||||
# get wiki object or 404
|
||||
wiki = get_object_or_404(Wiki, id=wiki_id)
|
||||
file_path = "/" + file_path
|
||||
|
||||
page_id = request.GET.get('page_id')
|
||||
file_path = ''
|
||||
|
||||
if page_id:
|
||||
wiki_config = get_wiki_config(wiki.repo_id, request.user.username)
|
||||
pages = wiki_config.get('pages', [])
|
||||
page_info = next(filter(lambda t: t['id'] == page_id, pages), {})
|
||||
file_path = page_info.get('path', '')
|
||||
|
||||
is_page = False
|
||||
if file_path:
|
||||
is_page = True
|
||||
|
||||
# perm check
|
||||
req_user = request.user.username
|
||||
if not check_wiki_permission(wiki, req_user):
|
||||
return render_permission_error(request, 'Permission denied.')
|
||||
|
||||
permission = check_folder_permission(request, wiki.repo_id, '/')
|
||||
if not permission:
|
||||
return render_permission_error(request, 'Permission denied.')
|
||||
|
||||
is_dir = None
|
||||
file_id = seafile_api.get_file_id_by_path(wiki.repo_id, file_path)
|
||||
if file_id:
|
||||
is_dir = False
|
||||
|
||||
dir_id = seafile_api.get_dir_id_by_path(wiki.repo_id, file_path)
|
||||
if dir_id:
|
||||
is_dir = True
|
||||
|
||||
outlines = []
|
||||
latest_contributor = ''
|
||||
last_modified = 0
|
||||
assets_url = ''
|
||||
seadoc_access_token = ''
|
||||
file_type, ext = get_file_type_and_ext(posixpath.basename(file_path))
|
||||
repo = seafile_api.get_repo(wiki.repo_id)
|
||||
if is_dir is False and file_type == SEADOC:
|
||||
file_uuid = get_seadoc_file_uuid(repo, file_path)
|
||||
assets_url = '/api/v2.1/seadoc/download-image/' + file_uuid
|
||||
if is_page and file_type == SEADOC:
|
||||
try:
|
||||
dirent = seafile_api.get_dirent_by_path(wiki.repo_id, file_path)
|
||||
if dirent:
|
||||
@@ -71,23 +65,13 @@ def wiki_view(request, wiki_id, file_path):
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
|
||||
filename = os.path.basename(file_path)
|
||||
seadoc_access_token = gen_seadoc_access_token(file_uuid, filename, req_user, permission=permission)
|
||||
|
||||
last_modified = datetime.fromtimestamp(last_modified)
|
||||
|
||||
return render(request, "wiki/wiki_edit.html", {
|
||||
"wiki": wiki,
|
||||
"repo_name": repo.name if repo else '',
|
||||
"file_path": file_path,
|
||||
"filename": os.path.splitext(os.path.basename(file_path))[0],
|
||||
"outlines": outlines,
|
||||
"repo_name": repo.name if repo else '',
|
||||
"modifier": latest_contributor,
|
||||
"modify_time": last_modified,
|
||||
"repo_id": wiki.repo_id,
|
||||
"is_dir": is_dir,
|
||||
"assets_url": assets_url,
|
||||
"seadoc_server_url": SEADOC_SERVER_URL,
|
||||
"seadoc_access_token": seadoc_access_token,
|
||||
"permission": permission,
|
||||
"seadoc_server_url": SEADOC_SERVER_URL
|
||||
})
|
||||
|
Reference in New Issue
Block a user