mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-21 03:18:23 +00:00
delete share links (#5572)
* delete share links * [share dialog] 'Share Link' panel: fixup & improvements for 'visit link details & delete link/links' --------- Co-authored-by: llj <lingjun.li1@gmail.com>
This commit is contained in:
@@ -95,15 +95,46 @@ class ShareLinkPanel extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteLink = () => {
|
deleteLink = (token) => {
|
||||||
const { sharedLinkInfo, shareLinks } = this.state;
|
const { shareLinks } = this.state;
|
||||||
seafileAPI.deleteShareLink(sharedLinkInfo.token).then(() => {
|
seafileAPI.deleteShareLink(token).then(() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
mode: '',
|
mode: '',
|
||||||
sharedLinkInfo: null,
|
sharedLinkInfo: null,
|
||||||
shareLinks: shareLinks.filter(item => item.token !== sharedLinkInfo.token)
|
shareLinks: shareLinks.filter(item => item.token !== token)
|
||||||
|
});
|
||||||
|
toaster.success(gettext('Successfully deleted 1 share link'));
|
||||||
|
}).catch((error) => {
|
||||||
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
|
toaster.danger(errMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteShareLinks = () => {
|
||||||
|
const { shareLinks } = this.state;
|
||||||
|
const tokens = shareLinks.filter(item => item.isSelected).map(link => link.token);
|
||||||
|
seafileAPI.deleteShareLinks(tokens).then(res => {
|
||||||
|
const { success, failed } = res.data;
|
||||||
|
if (success.length) {
|
||||||
|
let newShareLinkList = shareLinks.filter(shareLink => {
|
||||||
|
return !success.some(deletedShareLink => {
|
||||||
|
return deletedShareLink.token == shareLink.token;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.setState({
|
||||||
|
shareLinks: newShareLinkList
|
||||||
|
});
|
||||||
|
const length = success.length;
|
||||||
|
const msg = length == 1 ?
|
||||||
|
gettext('Successfully deleted 1 share link') :
|
||||||
|
gettext('Successfully deleted {number_placeholder} share links')
|
||||||
|
.replace('{number_placeholder}', length);
|
||||||
|
toaster.success(msg);
|
||||||
|
}
|
||||||
|
failed.forEach(item => {
|
||||||
|
const msg = `${item.token}: ${item.error_msg}`;
|
||||||
|
toaster.danger(msg);
|
||||||
});
|
});
|
||||||
toaster.success(gettext('Link deleted'));
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
toaster.danger(errMessage);
|
toaster.danger(errMessage);
|
||||||
@@ -209,6 +240,8 @@ class ShareLinkPanel extends React.Component {
|
|||||||
showLinkDetails={this.showLinkDetails}
|
showLinkDetails={this.showLinkDetails}
|
||||||
toggleSelectAllLinks={this.toggleSelectAllLinks}
|
toggleSelectAllLinks={this.toggleSelectAllLinks}
|
||||||
toggleSelectLink={this.toggleSelectLink}
|
toggleSelectLink={this.toggleSelectLink}
|
||||||
|
deleteShareLinks={this.deleteShareLinks}
|
||||||
|
deleteLink={this.deleteLink}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import copy from 'copy-to-clipboard';
|
|||||||
import { Button } from 'reactstrap';
|
import { Button } from 'reactstrap';
|
||||||
import { isPro, gettext, shareLinkExpireDaysMin, shareLinkExpireDaysMax, shareLinkExpireDaysDefault, canSendShareLinkEmail } from '../../utils/constants';
|
import { isPro, gettext, shareLinkExpireDaysMin, shareLinkExpireDaysMax, shareLinkExpireDaysDefault, canSendShareLinkEmail } from '../../utils/constants';
|
||||||
import ShareLinkPermissionEditor from '../../components/select-editor/share-link-permission-editor';
|
import ShareLinkPermissionEditor from '../../components/select-editor/share-link-permission-editor';
|
||||||
|
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import ShareLink from '../../models/share-link';
|
import ShareLink from '../../models/share-link';
|
||||||
@@ -38,7 +39,7 @@ class LinkDetails extends React.Component {
|
|||||||
expireDays: this.props.defaultExpireDays,
|
expireDays: this.props.defaultExpireDays,
|
||||||
expDate: null,
|
expDate: null,
|
||||||
isOpIconShown: false,
|
isOpIconShown: false,
|
||||||
isNoticeMessageShow: false,
|
isLinkDeleteDialogOpen: false,
|
||||||
isSendLinkShown: false
|
isSendLinkShown: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -129,14 +130,20 @@ class LinkDetails extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onNoticeMessageToggle = () => {
|
toggleLinkDeleteDialog = () => {
|
||||||
this.setState({isNoticeMessageShow: !this.state.isNoticeMessageShow});
|
this.setState({isLinkDeleteDialogOpen: !this.state.isLinkDeleteDialogOpen});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSendLink = () => {
|
toggleSendLink = () => {
|
||||||
this.setState({ isSendLinkShown: !this.state.isSendLinkShown });
|
this.setState({ isSendLinkShown: !this.state.isSendLinkShown });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteLink = () => {
|
||||||
|
const { sharedLinkInfo } = this.props;
|
||||||
|
const { token } = sharedLinkInfo;
|
||||||
|
this.props.deleteLink(token);
|
||||||
|
}
|
||||||
|
|
||||||
goBack = () => {
|
goBack = () => {
|
||||||
this.props.showLinkDetails(null);
|
this.props.showLinkDetails(null);
|
||||||
}
|
}
|
||||||
@@ -235,7 +242,7 @@ class LinkDetails extends React.Component {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</dl>
|
</dl>
|
||||||
{(canSendShareLinkEmail && !this.state.isSendLinkShown && !this.state.isNoticeMessageShow) &&
|
{(canSendShareLinkEmail && !this.state.isSendLinkShown) &&
|
||||||
<Button onClick={this.toggleSendLink} className='mr-2'>{gettext('Send')}</Button>
|
<Button onClick={this.toggleSendLink} className='mr-2'>{gettext('Send')}</Button>
|
||||||
}
|
}
|
||||||
{this.state.isSendLinkShown &&
|
{this.state.isSendLinkShown &&
|
||||||
@@ -246,16 +253,17 @@ class LinkDetails extends React.Component {
|
|||||||
closeShareDialog={this.props.closeShareDialog}
|
closeShareDialog={this.props.closeShareDialog}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{(!this.state.isSendLinkShown && !this.state.isNoticeMessageShow) &&
|
{(!this.state.isSendLinkShown) &&
|
||||||
<Button onClick={this.onNoticeMessageToggle}>{gettext('Delete')}</Button>
|
<Button onClick={this.toggleLinkDeleteDialog}>{gettext('Delete')}</Button>
|
||||||
}
|
}
|
||||||
{this.state.isNoticeMessageShow &&
|
{this.state.isLinkDeleteDialogOpen &&
|
||||||
<div className="alert alert-warning">
|
<CommonOperationConfirmationDialog
|
||||||
<h4 className="alert-heading">{gettext('Are you sure you want to delete the share link?')}</h4>
|
title={gettext('Delete share link')}
|
||||||
<p className="mb-4">{gettext('If the share link is deleted, no one will be able to access it any more.')}</p>
|
message={gettext('Are you sure you want to delete the share link?')}
|
||||||
<button className="btn btn-primary" onClick={this.props.deleteLink}>{gettext('Delete')}</button>{' '}
|
executeOperation={this.deleteLink}
|
||||||
<button className="btn btn-secondary" onClick={this.onNoticeMessageToggle}>{gettext('Cancel')}</button>
|
confirmBtnText={gettext('Delete')}
|
||||||
</div>
|
toggleDialog={this.toggleLinkDeleteDialog}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import copy from 'copy-to-clipboard';
|
import copy from 'copy-to-clipboard';
|
||||||
@@ -6,12 +6,14 @@ import toaster from '../toast';
|
|||||||
import { isPro, gettext } from '../../utils/constants';
|
import { isPro, gettext } from '../../utils/constants';
|
||||||
import ShareLinkPermissionEditor from '../../components/select-editor/share-link-permission-editor';
|
import ShareLinkPermissionEditor from '../../components/select-editor/share-link-permission-editor';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
|
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
item: PropTypes.object.isRequired,
|
item: PropTypes.object.isRequired,
|
||||||
permissionOptions: PropTypes.array,
|
permissionOptions: PropTypes.array,
|
||||||
showLinkDetails : PropTypes.func.isRequired,
|
showLinkDetails : PropTypes.func.isRequired,
|
||||||
toggleSelectLink: PropTypes.func.isRequired
|
toggleSelectLink: PropTypes.func.isRequired,
|
||||||
|
deleteLink: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
class LinkItem extends React.Component {
|
class LinkItem extends React.Component {
|
||||||
@@ -19,7 +21,8 @@ class LinkItem extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isItemOpVisible: false
|
isItemOpVisible: false,
|
||||||
|
isDeleteShareLinkDialogOpen: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +43,10 @@ class LinkItem extends React.Component {
|
|||||||
return link.slice(0, 9) + '...' + link.slice(length-5);
|
return link.slice(0, 9) + '...' + link.slice(length-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleDeleteShareLinkDialog = () => {
|
||||||
|
this.setState({isDeleteShareLinkDialogOpen: !this.state.isDeleteShareLinkDialogOpen});
|
||||||
|
}
|
||||||
|
|
||||||
copyLink = (e) => {
|
copyLink = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const { item } = this.props;
|
const { item } = this.props;
|
||||||
@@ -57,36 +64,55 @@ class LinkItem extends React.Component {
|
|||||||
this.props.toggleSelectLink(item, e.target.checked);
|
this.props.toggleSelectLink(item, e.target.checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteLink = () => {
|
||||||
|
const { item } = this.props;
|
||||||
|
this.props.deleteLink(item.token);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isItemOpVisible } = this.state;
|
const { isItemOpVisible } = this.state;
|
||||||
const { item, permissionOptions } = this.props;
|
const { item, permissionOptions } = this.props;
|
||||||
const { isSelected = false, permissions, link, expire_date } = item;
|
const { isSelected = false, permissions, link, expire_date } = item;
|
||||||
const currentPermission = Utils.getShareLinkPermissionStr(permissions);
|
const currentPermission = Utils.getShareLinkPermissionStr(permissions);
|
||||||
return (
|
return (
|
||||||
<tr onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} className={isSelected ? 'tr-highlight' : ''}>
|
<Fragment>
|
||||||
<td className="text-center">
|
<tr onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} className={isSelected ? 'tr-highlight' : ''}>
|
||||||
<input type="checkbox" checked={isSelected} onChange={this.toggleSelectLink} className="vam" />
|
<td className="text-center">
|
||||||
</td>
|
<input type="checkbox" checked={isSelected} onChange={this.toggleSelectLink} className="vam" />
|
||||||
<td>{this.cutLink(link)}</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{(isPro && permissions) && (
|
<a href="#" onClick={this.viewDetails} className="text-inherit">{this.cutLink(link)}</a>
|
||||||
<ShareLinkPermissionEditor
|
</td>
|
||||||
isTextMode={true}
|
<td>
|
||||||
isEditIconShow={false}
|
{(isPro && permissions) && (
|
||||||
currentPermission={currentPermission}
|
<ShareLinkPermissionEditor
|
||||||
permissionOptions={permissionOptions}
|
isTextMode={true}
|
||||||
onPermissionChanged={() => {}}
|
isEditIconShow={false}
|
||||||
/>
|
currentPermission={currentPermission}
|
||||||
)}
|
permissionOptions={permissionOptions}
|
||||||
</td>
|
onPermissionChanged={() => {}}
|
||||||
<td>
|
/>
|
||||||
{expire_date ? moment(expire_date).format('YYYY-MM-DD HH:mm') : '--'}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="#" role="button" onClick={this.copyLink} className={`sf2-icon-copy action-icon ${isItemOpVisible ? '' : 'invisible'}`} title={gettext('Copy')} aria-label={gettext('Copy')}></a>
|
{expire_date ? moment(expire_date).format('YYYY-MM-DD HH:mm') : '--'}
|
||||||
<a href="#" role="button" onClick={this.viewDetails} className={`fas fa-info-circle font-weight-bold action-icon ${isItemOpVisible ? '' : 'invisible'}`} title={gettext('Details')} aria-label={gettext('Details')}></a>
|
</td>
|
||||||
</td>
|
<td>
|
||||||
</tr>
|
<a href="#" role="button" onClick={this.copyLink} className={`sf2-icon-copy action-icon ${isItemOpVisible ? '' : 'invisible'}`} title={gettext('Copy')} aria-label={gettext('Copy')}></a>
|
||||||
|
<a href="#" role="button" onClick={this.viewDetails} className={`fa fa-pencil-alt attr-action-icon ${isItemOpVisible ? '' : 'invisible'}`} title={gettext('Edit')} aria-label={gettext('Edit')}></a>
|
||||||
|
<a href="#" role="button" onClick={this.toggleDeleteShareLinkDialog} className={`sf2-icon-delete action-icon ${isItemOpVisible ? '' : 'invisible'}`} title={gettext('Delete')} aria-label={gettext('Delete')}></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{this.state.isDeleteShareLinkDialogOpen && (
|
||||||
|
<CommonOperationConfirmationDialog
|
||||||
|
title={gettext('Delete share link')}
|
||||||
|
message={gettext('Are you sure you want to delete the share link?')}
|
||||||
|
executeOperation={this.deleteLink}
|
||||||
|
confirmBtnText={gettext('Delete')}
|
||||||
|
toggleDialog={this.toggleDeleteShareLinkDialog}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { gettext, siteRoot } from '../../utils/constants';
|
import { gettext, siteRoot } from '../../utils/constants';
|
||||||
import EmptyTip from '../empty-tip';
|
import EmptyTip from '../empty-tip';
|
||||||
import LinkItem from './link-item';
|
import LinkItem from './link-item';
|
||||||
|
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
shareLinks: PropTypes.array.isRequired,
|
shareLinks: PropTypes.array.isRequired,
|
||||||
@@ -10,11 +11,24 @@ const propTypes = {
|
|||||||
setMode: PropTypes.func.isRequired,
|
setMode: PropTypes.func.isRequired,
|
||||||
showLinkDetails: PropTypes.func.isRequired,
|
showLinkDetails: PropTypes.func.isRequired,
|
||||||
toggleSelectAllLinks: PropTypes.func.isRequired,
|
toggleSelectAllLinks: PropTypes.func.isRequired,
|
||||||
toggleSelectLink: PropTypes.func.isRequired
|
toggleSelectLink: PropTypes.func.isRequired,
|
||||||
|
deleteLink: PropTypes.func.isRequired,
|
||||||
|
deleteShareLinks: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
class LinkList extends React.Component {
|
class LinkList extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isDeleteShareLinksDialogOpen: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleDeleteShareLinksDialog = () => {
|
||||||
|
this.setState({isDeleteShareLinksDialogOpen: !this.state.isDeleteShareLinksDialogOpen});
|
||||||
|
}
|
||||||
|
|
||||||
toggleSelectAllLinks = (e) => {
|
toggleSelectAllLinks = (e) => {
|
||||||
this.props.toggleSelectAllLinks(e.target.checked);
|
this.props.toggleSelectAllLinks(e.target.checked);
|
||||||
}
|
}
|
||||||
@@ -40,7 +54,7 @@ class LinkList extends React.Component {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="d-flex justify-content-between align-items-center pb-2 border-bottom">
|
<div className="d-flex justify-content-between align-items-center pb-2 border-bottom">
|
||||||
<h6 className="font-weight-normal m-0">{gettext('Share Link')}</h6>
|
<h6 className="font-weight-normal m-0">{gettext('Share Link')}</h6>
|
||||||
<div>
|
<div className="d-flex">
|
||||||
{selectedLinks.length == 0 ? (
|
{selectedLinks.length == 0 ? (
|
||||||
<>
|
<>
|
||||||
<button className="btn btn-sm btn-outline-primary mr-2" onClick={this.props.setMode.bind(this, 'singleLinkCreation')}>{gettext('Generate Link')}</button>
|
<button className="btn btn-sm btn-outline-primary mr-2" onClick={this.props.setMode.bind(this, 'singleLinkCreation')}>{gettext('Generate Link')}</button>
|
||||||
@@ -49,7 +63,8 @@ class LinkList extends React.Component {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<button className="btn btn-sm btn-secondary mr-2" onClick={this.cancelSelectAllLinks}>{gettext('Cancel')}</button>
|
<button className="btn btn-sm btn-secondary mr-2" onClick={this.cancelSelectAllLinks}>{gettext('Cancel')}</button>
|
||||||
<button className="btn btn-sm btn-primary" onClick={this.exportSelectedLinks}>{gettext('Export')}</button>
|
<button className="btn btn-sm btn-secondary mr-2" onClick={this.toggleDeleteShareLinksDialog}>{gettext('Delete')}</button>
|
||||||
|
<button className="btn btn-sm btn-secondary" onClick={this.exportSelectedLinks}>{gettext('Export')}</button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -67,8 +82,8 @@ class LinkList extends React.Component {
|
|||||||
</th>
|
</th>
|
||||||
<th width="23%">{gettext('Link')}</th>
|
<th width="23%">{gettext('Link')}</th>
|
||||||
<th width="30%">{gettext('Permission')}</th>
|
<th width="30%">{gettext('Permission')}</th>
|
||||||
<th width="28%">{gettext('Expiration')}</th>
|
<th width="24%">{gettext('Expiration')}</th>
|
||||||
<th width="14%"></th>
|
<th width="18%"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -80,12 +95,22 @@ class LinkList extends React.Component {
|
|||||||
permissionOptions={permissionOptions}
|
permissionOptions={permissionOptions}
|
||||||
showLinkDetails={this.props.showLinkDetails}
|
showLinkDetails={this.props.showLinkDetails}
|
||||||
toggleSelectLink={this.props.toggleSelectLink}
|
toggleSelectLink={this.props.toggleSelectLink}
|
||||||
|
deleteLink={this.props.deleteLink}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
)}
|
)}
|
||||||
|
{this.state.isDeleteShareLinksDialogOpen && (
|
||||||
|
<CommonOperationConfirmationDialog
|
||||||
|
title={gettext('Delete share links')}
|
||||||
|
message={gettext('Are you sure you want to delete the selected share link(s) ?')}
|
||||||
|
executeOperation={this.props.deleteShareLinks}
|
||||||
|
confirmBtnText={gettext('Delete')}
|
||||||
|
toggleDialog={this.toggleDeleteShareLinksDialog}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -459,6 +459,71 @@ class ShareLinks(APIView):
|
|||||||
link_info = get_share_link_info(fs)
|
link_info = get_share_link_info(fs)
|
||||||
return Response(link_info)
|
return Response(link_info)
|
||||||
|
|
||||||
|
def delete(self, request):
|
||||||
|
""" Delete share links.
|
||||||
|
|
||||||
|
Permission checking:
|
||||||
|
1. default(NOT guest) user;
|
||||||
|
2. link owner;
|
||||||
|
"""
|
||||||
|
|
||||||
|
token_list = request.data.get('tokens')
|
||||||
|
if not token_list:
|
||||||
|
error_msg = 'token invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
result['failed'] = []
|
||||||
|
result['success'] = []
|
||||||
|
|
||||||
|
username = request.user.username
|
||||||
|
for token in token_list:
|
||||||
|
|
||||||
|
try:
|
||||||
|
fs = FileShare.objects.get(token=token)
|
||||||
|
except FileShare.DoesNotExist:
|
||||||
|
result['success'].append({
|
||||||
|
'token': token,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
|
||||||
|
has_published_library = False
|
||||||
|
if fs.path == '/':
|
||||||
|
try:
|
||||||
|
Wiki.objects.get(repo_id=fs.repo_id)
|
||||||
|
has_published_library = True
|
||||||
|
except Wiki.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not fs.is_owner(username):
|
||||||
|
result['failed'].append({
|
||||||
|
'token': token,
|
||||||
|
'error_msg': 'Permission denied.'
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
|
||||||
|
if has_published_library:
|
||||||
|
result['failed'].append({
|
||||||
|
'token': token,
|
||||||
|
'error_msg': _('There is an associated published library.')
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
fs.delete()
|
||||||
|
result['success'].append({
|
||||||
|
'token': token,
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
result['failed'].append({
|
||||||
|
'token': token,
|
||||||
|
'error_msg': 'Internal Server Error'
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
|
||||||
|
return Response(result)
|
||||||
|
|
||||||
|
|
||||||
class ShareLink(APIView):
|
class ShareLink(APIView):
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user