1
0
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:
Michael An
2024-05-29 11:51:52 +08:00
committed by GitHub
parent b76bad303a
commit 96aa207802
9 changed files with 177 additions and 58 deletions

View File

@@ -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}

View File

@@ -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}

View File

@@ -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;

View 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;

View File

@@ -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();

View File

@@ -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)

View File

@@ -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 }}",

View File

@@ -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')),

View File

@@ -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
})