diff --git a/frontend/src/components/dialog/wiki-delete-dialog.js b/frontend/src/components/dialog/wiki-delete-dialog.js index 7f0980da8d..cc00ac1ef0 100644 --- a/frontend/src/components/dialog/wiki-delete-dialog.js +++ b/frontend/src/components/dialog/wiki-delete-dialog.js @@ -17,13 +17,13 @@ class WikiDeleteDialog extends React.Component { render() { return ( - {gettext('Delete Wiki')} + {gettext('Unpublish Library')} -

{gettext('Are you sure you want to delete this wiki?')}

+

{gettext('Are you sure you want to unpublish this library?')}

- +
); diff --git a/frontend/src/components/dialog/wiki-select-dialog.js b/frontend/src/components/dialog/wiki-select-dialog.js index eec6b05335..bdeee40cc5 100644 --- a/frontend/src/components/dialog/wiki-select-dialog.js +++ b/frontend/src/components/dialog/wiki-select-dialog.js @@ -18,8 +18,6 @@ class WikiSelectDialog extends React.Component { super(props); this.state = { repos: [], - isExist: true, - name: '', repoID: '', }; } @@ -43,8 +41,8 @@ class WikiSelectDialog extends React.Component { } handleSubmit = () => { - let { isExist, name, repoID } = this.state; - this.props.addWiki(isExist, name, repoID); + let { repoID } = this.state; + this.props.addWiki(repoID); this.props.toggleCancel(); } @@ -55,7 +53,7 @@ class WikiSelectDialog extends React.Component { render() { return ( - {gettext('Choose a library as Wiki')} + {gettext('Publish a library')} diff --git a/frontend/src/components/main-side-nav.js b/frontend/src/components/main-side-nav.js index 7bd949c4a7..02807bf9d5 100644 --- a/frontend/src/components/main-side-nav.js +++ b/frontend/src/components/main-side-nav.js @@ -202,7 +202,7 @@ class MainSideNav extends React.Component {
  • this.tabItemClick('wikis')}> - {gettext('Wikis')} + {gettext('Published Libraries')}
  • } diff --git a/frontend/src/components/wiki-list-view/wiki-list-item.js b/frontend/src/components/wiki-list-view/wiki-list-item.js index 1306964a00..51aa0b496a 100644 --- a/frontend/src/components/wiki-list-view/wiki-list-item.js +++ b/frontend/src/components/wiki-list-view/wiki-list-item.js @@ -153,15 +153,6 @@ class WikiListItem extends Component { -
    {wiki.owner_nickname} {moment(wiki.updated_at).fromNow()} - - {this.state.isShowMenuControl && ( @@ -174,8 +165,7 @@ class WikiListItem extends Component { onClick={this.clickMenuToggle} /> - {gettext('Rename')} - {gettext('Delete')} + {gettext('Unpublish')} )} @@ -196,4 +186,4 @@ class WikiListItem extends Component { WikiListItem.propTypes = propTypes; -export default WikiListItem; \ No newline at end of file +export default WikiListItem; diff --git a/frontend/src/components/wiki-list-view/wiki-list-view.js b/frontend/src/components/wiki-list-view/wiki-list-view.js index b4b76fe579..52abc80005 100644 --- a/frontend/src/components/wiki-list-view/wiki-list-view.js +++ b/frontend/src/components/wiki-list-view/wiki-list-view.js @@ -38,10 +38,9 @@ class WikiListView extends Component { - - - - + + + @@ -68,4 +67,4 @@ class WikiListView extends Component { WikiListView.propTypes = propTypes; -export default WikiListView; \ No newline at end of file +export default WikiListView; diff --git a/frontend/src/pages/wiki/main-panel.js b/frontend/src/pages/wiki/main-panel.js index b8f9509303..adc9ab928b 100644 --- a/frontend/src/pages/wiki/main-panel.js +++ b/frontend/src/pages/wiki/main-panel.js @@ -79,7 +79,7 @@ class MainPanel extends Component {
    {this.props.permission === 'rw' && ( - + )}
    - {username && - - {gettext('Wikis')} - / - - } {slug} {this.renderNavPath()}
    diff --git a/frontend/src/pages/wiki/side-panel.js b/frontend/src/pages/wiki/side-panel.js index 2055ba9514..49bb425803 100644 --- a/frontend/src/pages/wiki/side-panel.js +++ b/frontend/src/pages/wiki/side-panel.js @@ -46,7 +46,7 @@ class SidePanel extends Component { renderTreeView = () => { return ( -

    {gettext('Pages')}

    +

    {gettext('Contents')}

    {this.props.treeData && ( { - seafileAPI.addWiki(isExist, name, repoID).then((res) => { + addWiki = (repoID) => { + seafileAPI.addWiki(repoID).then((res) => { this.state.wikis.push(res.data); this.setState({wikis: this.state.wikis}); }).catch((error) => { @@ -123,15 +123,9 @@ class Wikis extends Component {
    - - - {gettext('Add Wiki')} - - - {gettext('New Wiki')} - {gettext('Choose a library as Wiki')} - - +
    @@ -140,7 +134,7 @@ class Wikis extends Component {
    -

    {gettext('Wikis')}

    +

    {gettext('Published Libraries')}

    diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index be16c6f97f..6416d63d73 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -56,6 +56,8 @@ export const permission = window.wiki ? window.wiki.config.permission === 'True' export const isDir = window.wiki ? window.wiki.config.isDir : ''; export const serviceUrl = window.wiki ? window.wiki.config.serviceUrl : ''; export const isPublicWiki = window.wiki ? window.wiki.config.isPublicWiki === 'True': ''; +export const sharedToken = window.wiki ? window.wiki.config.sharedToken : ''; +export const sharedType = window.wiki ? window.wiki.config.sharedType : ''; // file history export const PER_PAGE = 25; diff --git a/frontend/src/wiki.js b/frontend/src/wiki.js index e8afe7a147..bac051ea0b 100644 --- a/frontend/src/wiki.js +++ b/frontend/src/wiki.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import moment from 'moment'; -import { slug, repoID, siteRoot, initialPath, isDir } from './utils/constants'; +import { slug, repoID, siteRoot, initialPath, isDir, sharedToken } from './utils/constants'; import { Utils } from './utils/utils'; import { seafileAPI } from './utils/seafile-api'; import Dirent from './models/dirent'; @@ -270,7 +270,7 @@ class Wiki extends Component { if (Utils.isMarkdownFile(path)) { this.showFile(path); } else { - let url = siteRoot + 'lib/' + item.repo_id + '/file' + Utils.encodePath(path); + let url = siteRoot + 'd/' + sharedToken + '/files/?p=' + Utils.encodePath(path); let newWindow = window.open('about:blank'); newWindow.location.href = url; } @@ -285,7 +285,6 @@ class Wiki extends Component { let tree = this.state.treeData.clone(); let node = tree.getNodeByPath(nodePath); tree.expandNode(node); - this.setState({treeData: tree, currentNode: node}); this.showDir(node.path); } @@ -300,7 +299,7 @@ class Wiki extends Component { this.showFile(direntPath); } else { const w=window.open('about:blank'); - const url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(direntPath); + const url = siteRoot + 'd/' + sharedToken + '/files/?p=' + Utils.encodePath(direntPath); w.location.href = url; } } @@ -351,7 +350,7 @@ class Wiki extends Component { } } else { const w = window.open('about:blank'); - const url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(node.path); + const url = siteRoot + 'd/' + sharedToken + '/files/?p=' + Utils.encodePath(node.path); w.location.href = url; } } diff --git a/seahub/api2/endpoints/share_links.py b/seahub/api2/endpoints/share_links.py index 209d69deb4..21c664a107 100644 --- a/seahub/api2/endpoints/share_links.py +++ b/seahub/api2/endpoints/share_links.py @@ -38,6 +38,7 @@ from seahub.settings import SHARE_LINK_EXPIRE_DAYS_MAX, \ SHARE_LINK_EXPIRE_DAYS_MIN, SHARE_LINK_LOGIN_REQUIRED, \ ENABLE_SHARE_LINK_AUDIT, ENABLE_VIDEO_THUMBNAIL, \ THUMBNAIL_ROOT +from seahub.wiki.models import Wiki logger = logging.getLogger(__name__) @@ -366,11 +367,23 @@ class ShareLink(APIView): except FileShare.DoesNotExist: return Response({'success': True}) + has_published_library = False + if fs.path == '/': + try: + Wiki.objects.get(repo_id=fs.repo_id) + has_published_library = True + except Wiki.DoesNotExist: + pass + username = request.user.username if not fs.is_owner(username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) + if has_published_library: + error_msg = 'This is an associated published library.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + try: fs.delete() except Exception as e: diff --git a/seahub/api2/endpoints/wikis.py b/seahub/api2/endpoints/wikis.py index 20f481a3af..60d3fd67c0 100644 --- a/seahub/api2/endpoints/wikis.py +++ b/seahub/api2/endpoints/wikis.py @@ -9,7 +9,6 @@ from rest_framework.response import Response from rest_framework.views import APIView from seaserv import seafile_api, edit_repo from pysearpc import SearpcError -from django.core.urlresolvers import reverse from django.db import IntegrityError from django.db.models import Count from django.http import HttpResponse @@ -24,6 +23,7 @@ from seahub.utils import is_org_context, get_user_repos from seahub.utils.repo import is_group_repo_staff, is_repo_owner from seahub.views import check_folder_permission from seahub.share.utils import is_repo_admin +from seahub.share.models import FileShare logger = logging.getLogger(__name__) @@ -79,94 +79,61 @@ class WikisView(APIView): def post(self, request, format=None): """Add a new wiki. """ - use_exist_repo = request.POST.get('use_exist_repo', '') - if not use_exist_repo: - msg = 'Use exist repo is invalid' - return api_error(status.HTTP_400_BAD_REQUEST, msg) - - name = request.POST.get('name', '') - if not name: - msg = 'Name is invalid' - return api_error(status.HTTP_400_BAD_REQUEST, msg) - - if not is_valid_wiki_name(name): - msg = _('Name can only contain letters, numbers, blank, hyphen or underscore.') - return api_error(status.HTTP_400_BAD_REQUEST, msg) - username = request.user.username org_id = -1 if is_org_context(request): org_id = request.user.org.org_id - if use_exist_repo == 'false': - try: - wiki = Wiki.objects.add(name, username, org_id=org_id) - except DuplicateWikiNameError: - msg = _('%s is taken by others, please try another name.') % name - return api_error(status.HTTP_400_BAD_REQUEST, msg) - except IntegrityError: - msg = 'Internal Server Error' - return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg) + repo_id = request.POST.get('repo_id', '') + if not repo_id: + msg = 'Repo id is invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, msg) - # create home page - page_name = "home.md" + 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) + + # check perm + is_owner = is_repo_owner(request, repo_id, username) + + if not is_owner: + repo_admin = is_repo_admin(username, repo_id) + + if not repo_admin: + is_group_repo_admin = is_group_repo_staff(request, repo_id, username) + + if not is_group_repo_admin: + error_msg = _('Permission denied.') + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + try: + wiki = Wiki.objects.add(wiki_name=repo.repo_name, username=username, + repo_id=repo.repo_id, org_id=org_id, permission='public') + except DuplicateWikiNameError: + msg = _('%s is taken by others, please try another name.') % repo.repo_name + return api_error(status.HTTP_400_BAD_REQUEST, msg) + except IntegrityError: + msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg) + + # create home page if not exist + page_name = "home.md" + if not seafile_api.get_file_id_by_path(repo_id, "/" + page_name): try: - seafile_api.post_empty_file(wiki.repo_id, '/', - page_name, request.user.username) + seafile_api.post_empty_file(repo_id, '/', page_name, username) except SearpcError as e: logger.error(e) msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg) - return Response(wiki.to_dict()) + fs = FileShare.objects.get_dir_link_by_path(username, repo_id, '/') + if not fs: + fs = FileShare.objects.create_dir_link(username, repo_id, '/', + permission='view_download', org_id=org_id) - if use_exist_repo == 'true': - repo_id = request.POST.get('repo_id', '') - if not repo_id: - msg = 'Repo id is invalid.' - return api_error(status.HTTP_400_BAD_REQUEST, msg) - - 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) - - # check perm - is_owner = is_repo_owner(request, repo_id, username) - - if not is_owner: - repo_admin = is_repo_admin(username, repo_id) - - if not repo_admin: - is_group_repo_admin = is_group_repo_staff(request, repo_id, username) - - if not is_group_repo_admin: - error_msg = _('Permission denied.') - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - - try: - wiki = Wiki.objects.add(wiki_name=repo.repo_name, username=username, - repo_id=repo.repo_id, org_id=org_id) - except DuplicateWikiNameError: - msg = _('%s is taken by others, please try another name.') % repo.repo_name - return api_error(status.HTTP_400_BAD_REQUEST, msg) - except IntegrityError: - msg = 'Internal Server Error' - return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg) - - # create home page if not exist - page_name = "home.md" - if not seafile_api.get_file_id_by_path(repo_id, "/" + page_name): - try: - seafile_api.post_empty_file(repo_id, '/', page_name, username) - except SearpcError as e: - logger.error(e) - msg = 'Internal Server Error' - return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg) - - - return Response(wiki.to_dict()) + return Response(wiki.to_dict()) class WikiView(APIView): diff --git a/seahub/templates/wiki/wiki.html b/seahub/templates/wiki/wiki.html index 4bad2b8d02..d1b7bc79b6 100644 --- a/seahub/templates/wiki/wiki.html +++ b/seahub/templates/wiki/wiki.html @@ -10,6 +10,8 @@ config: { slug: "{{ wiki.slug }}", repoId: "{{ wiki.repo_id }}", + sharedToken: "{{ shared_token }}", + sharedType: "{{ shared_type }}", initial_path: "{{ file_path|escapejs }}", permission: "{{ user_can_write }}", isPublicWiki: "{{ is_public_wiki }}", diff --git a/seahub/wiki/models.py b/seahub/wiki/models.py index 41d846ed97..31e29f9ca6 100644 --- a/seahub/wiki/models.py +++ b/seahub/wiki/models.py @@ -160,3 +160,9 @@ def remove_personal_wiki(sender, **kwargs): repo_id = kwargs['repo_id'] PersonalWiki.objects.filter(username=repo_owner, repo_id=repo_id).delete() + +@receiver(repo_deleted) +def remove_wiki(sender, **kwargs): + repo_id = kwargs['repo_id'] + + Wiki.objects.filter(repo_id=repo_id).delete() diff --git a/seahub/wiki/views.py b/seahub/wiki/views.py index 4914a951c6..62e01f189b 100644 --- a/seahub/wiki/views.py +++ b/seahub/wiki/views.py @@ -12,6 +12,7 @@ from django.utils.translation import ugettext as _ from seahub.auth.decorators import login_required from seahub.base.decorators import user_mods_check +from seahub.share.models import FileShare from seahub.wiki.models import Wiki from seahub.views import check_folder_permission from seahub.utils import get_service_url, get_file_type_and_ext, render_permission_error @@ -88,9 +89,13 @@ def slug(request, slug, file_path="home.md"): if wiki.permission == 'public': is_public_wiki = True + fs = FileShare.objects.get(repo_id=wiki.repo_id, path='/') + return render(request, "wiki/wiki.html", { "wiki": wiki, "page_name": file_path, + "shared_token": fs.token, + "shared_type": fs.s_type, "user_can_write": user_can_write, "file_path": file_path, "repo_id": wiki.repo_id,
    {gettext('Name')}{gettext('Owner')}{gettext('Last Update')}{gettext('Permission')}{gettext('Name')}{gettext('Owner')}{gettext('Last Update')} {/* operation */}