mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-09 02:42:47 +00:00
Org export log (#6652)
* org admin export log * optimize code * optimize code * optimize code * update * update code * update --------- Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com> Co-authored-by: r350178982 <32759763+r350178982@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, FormGroup, Label, Input, Alert } from 'reactstrap';
|
||||
import { gettext, siteRoot, orgID } from '../../utils/constants';
|
||||
import { orgAdminAPI } from '../../utils/org-admin-api';
|
||||
import { userAPI } from '../../utils/user-api';
|
||||
import toaster from '../../components/toast';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import moment from 'moment';
|
||||
|
||||
class OrgLogsExportExcelDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: true,
|
||||
startDateStr: '',
|
||||
endDateStr: '',
|
||||
errMsg: '',
|
||||
taskId: '',
|
||||
};
|
||||
}
|
||||
|
||||
downloadExcel = () => {
|
||||
if (!this.isValidDateStr()) {
|
||||
return;
|
||||
}
|
||||
switch (this.props.logType) {
|
||||
case 'fileaudit':
|
||||
this.orgAdminExportLogs('fileaudit');
|
||||
break;
|
||||
case 'file-update':
|
||||
this.orgAdminExportLogs('fileupdate');
|
||||
break;
|
||||
case 'perm-audit':
|
||||
this.orgAdminExportLogs('permaudit');
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
orgAdminExportLogs = (logType) => {
|
||||
let { startDateStr, endDateStr } = this.state;
|
||||
let task_id = '';
|
||||
orgAdminAPI.orgAdminExportLogsExcel(orgID, startDateStr, endDateStr, logType).then(res => {
|
||||
task_id = res.data.task_id;
|
||||
this.setState({
|
||||
taskId: task_id
|
||||
});
|
||||
this.props.toggle();
|
||||
return userAPI.queryIOStatus(task_id);
|
||||
}).then(res => {
|
||||
if (res.data.is_finished === true) {
|
||||
location.href = siteRoot + 'api/v2.1/org/admin/log/export-excel/?task_id=' + task_id + '&log_type=' + logType;
|
||||
} else {
|
||||
this.timer = setInterval(() => {
|
||||
userAPI.queryIOStatus(task_id).then(res => {
|
||||
if (res.data.is_finished === true) {
|
||||
clearInterval(this.timer);
|
||||
location.href = siteRoot + 'api/v2.1/org/admin/log/export-excel/?task_id=' + task_id + '&log_type=' + logType;
|
||||
}
|
||||
}).catch(err => {
|
||||
clearInterval(this.timer);
|
||||
toaster.danger(gettext('Failed to export. Please check whether the size of table attachments exceeds the limit.'));
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
}).catch(error => {
|
||||
this.props.toggle();
|
||||
if (error.response && error.response.status === 500) {
|
||||
const error_msg = error.response.data ? error.response.data['error_msg'] : null;
|
||||
if (error_msg && error_msg !== 'Internal Server Error') {
|
||||
toaster.danger(error_msg);
|
||||
} else {
|
||||
toaster.danger(gettext('Internal Server Error'));
|
||||
}
|
||||
} else {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
isValidDateStr = () => {
|
||||
let { startDateStr, endDateStr } = this.state;
|
||||
if (moment(startDateStr, 'YYYY-MM-DD', true).isValid() &&
|
||||
moment(endDateStr, 'YYYY-MM-DD', true).isValid() &&
|
||||
moment(startDateStr).isBefore(endDateStr)
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
this.setState({
|
||||
errMsg: gettext('Date Invalid.')
|
||||
});
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
handleStartChange = (e) => {
|
||||
const startDateStr = e.target.value.trim();
|
||||
this.setState({
|
||||
startDateStr: startDateStr,
|
||||
errMsg: ''
|
||||
});
|
||||
};
|
||||
|
||||
handleEndChange = (e) => {
|
||||
const endDateStr = e.target.value.trim();
|
||||
this.setState({
|
||||
endDateStr: endDateStr,
|
||||
errMsg: '',
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal isOpen={true} toggle={this.props.toggle} autoFocus={false}>
|
||||
<ModalHeader toggle={this.props.toggle}>{gettext('Choose date')}</ModalHeader>
|
||||
<ModalBody>
|
||||
<FormGroup>
|
||||
<Label>{gettext('Start date')}</Label>
|
||||
<Input
|
||||
value={this.state.startDateStr}
|
||||
onChange={this.handleStartChange}
|
||||
placeholder='yyyy-mm-dd'
|
||||
autoFocus={true}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label>{gettext('End date')}</Label>
|
||||
<Input
|
||||
value={this.state.endDateStr}
|
||||
onChange={this.handleEndChange}
|
||||
placeholder='yyyy-mm-dd'
|
||||
/>
|
||||
</FormGroup>
|
||||
{this.state.errMsg &&
|
||||
<Alert className="mt-2" color="danger">
|
||||
{gettext(this.state.errMsg)}
|
||||
</Alert>
|
||||
}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="secondary" onClick={this.props.toggle}>{gettext('Cancel')}</Button>
|
||||
<Button color="primary" onClick={this.downloadExcel}>{gettext('Submit')}</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const propTypes = {
|
||||
toggle: PropTypes.func.isRequired,
|
||||
logType: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
OrgLogsExportExcelDialog.propTypes = propTypes;
|
||||
|
||||
export default OrgLogsExportExcelDialog;
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, FormGroup, Label, Input, Alert } from 'reactstrap';
|
||||
import { gettext, siteRoot } from '../../../utils/constants';
|
||||
import { systemAdminAPI } from '../../../utils/system-admin-api';
|
||||
import { userAPI } from '../../../utils/user-api';
|
||||
import toaster from '../../../components/toast';
|
||||
import { Utils } from '../../../utils/utils';
|
||||
import moment from 'moment';
|
||||
@@ -49,23 +50,20 @@ class LogsExportExcelDialog extends React.Component {
|
||||
taskId: task_id
|
||||
});
|
||||
this.props.toggle();
|
||||
return systemAdminAPI.queryAsyncOperationExportExcel(task_id);
|
||||
return userAPI.queryIOStatus(task_id);
|
||||
}).then(res => {
|
||||
if (res.data.is_finished === true) {
|
||||
location.href = siteRoot + 'sys/log/export-excel/?task_id=' + task_id + '&log_type=' + logType;
|
||||
} else {
|
||||
this.timer = setInterval(() => {
|
||||
systemAdminAPI.queryAsyncOperationExportExcel(task_id).then(res => {
|
||||
userAPI.queryIOStatus(task_id).then(res => {
|
||||
if (res.data.is_finished === true) {
|
||||
this.setState({ isFinished: true });
|
||||
clearInterval(this.timer);
|
||||
location.href = siteRoot + 'sys/log/export-excel/?task_id=' + task_id + '&log_type=' + logType;
|
||||
}
|
||||
}).catch(err => {
|
||||
if (this.state.isFinished === false) {
|
||||
clearInterval(this.timer);
|
||||
toaster.danger(gettext('Failed to export. Please check whether the size of table attachments exceeds the limit.'));
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
@@ -73,7 +73,14 @@ class Org extends React.Component {
|
||||
if (location.href.indexOf(`${siteRoot}org/departmentadmin`) != -1) {
|
||||
currentTab = 'departmentadmin';
|
||||
}
|
||||
this.setState({ currentTab: currentTab });
|
||||
if (location.href.indexOf(`${siteRoot}org/logadmin/`) != -1) {
|
||||
if (currentTab === 'logadmin') {
|
||||
currentTab = 'fileaudit';
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
currentTab: currentTab
|
||||
});
|
||||
}
|
||||
|
||||
onCloseSidePanel = () => {
|
||||
|
@@ -3,28 +3,53 @@ import PropTypes from 'prop-types';
|
||||
import { Link } from '@gatsbyjs/reach-router';
|
||||
import { siteRoot, gettext } from '../../utils/constants';
|
||||
import MainPanelTopbar from './main-panel-topbar';
|
||||
import { Button } from 'reactstrap';
|
||||
import ModalPortal from '../../components/modal-portal';
|
||||
import OrgLogsExportExcelDialog from '../../components/dialog/org-admin-logs-export-excel-dialog';
|
||||
|
||||
class OrgLogs extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isExportExcelDialogOpen: false,
|
||||
logType: '',
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let href = window.location.href.split('/');
|
||||
let logtype = href[href.length - 2];
|
||||
if (logtype === 'logadmin') {
|
||||
logtype = 'fileaudit';
|
||||
}
|
||||
this.setState({ logType: logtype });
|
||||
}
|
||||
|
||||
toggleExportExcelDialog = () => {
|
||||
this.setState({ isExportExcelDialogOpen: !this.state.isExportExcelDialogOpen });
|
||||
};
|
||||
tabItemClick = (param) => {
|
||||
this.setState({
|
||||
logType: param
|
||||
});
|
||||
this.props.tabItemClick(param);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { isExportExcelDialogOpen, logType } = this.state;
|
||||
return (
|
||||
<Fragment>
|
||||
<MainPanelTopbar/>
|
||||
<MainPanelTopbar>
|
||||
<Button className="btn btn-secondary operation-item" onClick={this.toggleExportExcelDialog}>{gettext('Export Excel')}</Button>
|
||||
</MainPanelTopbar>
|
||||
<div className="main-panel-center flex-row">
|
||||
<div className="cur-view-container">
|
||||
<div className="cur-view-container h-100">
|
||||
<div className="cur-view-path org-user-nav">
|
||||
<ul className="nav">
|
||||
<li className="nav-item" onClick={() => this.tabItemClick('logadmin')}>
|
||||
<li className="nav-item" onClick={() => this.tabItemClick('fileaudit')}>
|
||||
<Link
|
||||
className={`nav-link ${this.props.currentTab === 'logadmin' ? 'active' : ''}`}
|
||||
className={`nav-link ${this.props.currentTab === 'fileaudit' ? 'active' : ''}`}
|
||||
to={siteRoot + 'org/logadmin/'} title={gettext('File Access')}>{gettext('File Access')}
|
||||
</Link>
|
||||
</li>
|
||||
@@ -42,9 +67,19 @@ class OrgLogs extends Component {
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="h-100 o-auto">
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{isExportExcelDialogOpen &&
|
||||
<ModalPortal>
|
||||
<OrgLogsExportExcelDialog
|
||||
logType={logType}
|
||||
toggle={this.toggleExportExcelDialog}
|
||||
/>
|
||||
</ModalPortal>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
@@ -95,8 +95,8 @@ class SidePanel extends React.Component {
|
||||
<span className="nav-text">{gettext('Links')}</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className={`nav-item ${this.getActiveClass('logadmin') || this.getActiveClass('file-update') || this.getActiveClass('perm-audit')}`}>
|
||||
<Link className={`nav-link ellipsis ${this.getActiveClass('logadmin') || this.getActiveClass('file-update') || this.getActiveClass('perm-audit')}`} to={siteRoot + 'org/logadmin/'} onClick={() => this.tabItemClick('logadmin')} >
|
||||
<li className={`nav-item ${this.getActiveClass('fileaudit') || this.getActiveClass('file-update') || this.getActiveClass('perm-audit')}`}>
|
||||
<Link className={`nav-link ellipsis ${this.getActiveClass('fileaudit') || this.getActiveClass('file-update') || this.getActiveClass('perm-audit')}`} to={siteRoot + 'org/logadmin/'} onClick={() => this.tabItemClick('fileaudit')} >
|
||||
<span className="sf2-icon-clock"></span>
|
||||
<span className="nav-text">{gettext('Logs')}</span>
|
||||
</Link>
|
||||
|
@@ -49,6 +49,16 @@ class OrgAdminAPI {
|
||||
return this.req.post(url);
|
||||
}
|
||||
|
||||
orgAdminExportLogsExcel(orgID, start, end, logType) {
|
||||
const url = this.server + '/api/v2.1/org/' + orgID + '/admin/logs/export-excel/';
|
||||
const params = {
|
||||
start: start,
|
||||
end: end,
|
||||
logType: logType
|
||||
};
|
||||
return this.req.get(url, { params: params });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let orgAdminAPI = new OrgAdminAPI();
|
||||
|
@@ -76,11 +76,6 @@ class SystemAdminAPI {
|
||||
return this.req.get(url, { params: params });
|
||||
}
|
||||
|
||||
queryAsyncOperationExportExcel(task_id) {
|
||||
const url = this.server + '/api/v2.1/query-export-status/?task_id=' + task_id;
|
||||
return this.req.get(url);
|
||||
}
|
||||
|
||||
adminGroup2Department(groupID) {
|
||||
const url = this.server + '/api/v2.1/admin/groups/' + groupID + '/group-to-department/';
|
||||
return this.req.post(url);
|
||||
|
@@ -42,6 +42,11 @@ class UserAPI {
|
||||
};
|
||||
return this.req.post(url, data);
|
||||
}
|
||||
|
||||
queryIOStatus(task_id) {
|
||||
const url = this.server + '/api/v2.1/query-io-status/?task_id=' + task_id;
|
||||
return this.req.get(url);
|
||||
}
|
||||
}
|
||||
|
||||
let userAPI = new UserAPI();
|
||||
|
@@ -1,7 +1,4 @@
|
||||
import os
|
||||
import logging
|
||||
import time
|
||||
import json
|
||||
from shutil import rmtree
|
||||
from django.http import FileResponse
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
@@ -9,6 +6,7 @@ from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import api_view
|
||||
from urllib.parse import quote
|
||||
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
@@ -39,34 +37,11 @@ class SysLogsExport(APIView):
|
||||
return Response(res_data)
|
||||
|
||||
|
||||
class FileLogsExportStatus(APIView):
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsAdminUser, IsProVersion)
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
Get task status by task id
|
||||
"""
|
||||
task_id = request.GET.get('task_id', '')
|
||||
if not task_id:
|
||||
error_msg = 'task_id invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
resp = event_export_status(task_id)
|
||||
if resp.status_code == 500:
|
||||
logger.error('query export status error: %s, %s' % (task_id, resp.content))
|
||||
return api_error(500, 'Internal Server Error')
|
||||
if not resp.status_code == 200:
|
||||
return api_error(resp.status_code, resp.content)
|
||||
|
||||
is_finished = json.loads(resp.content)['is_finished']
|
||||
|
||||
return Response({'is_finished': is_finished})
|
||||
|
||||
|
||||
@login_required
|
||||
@sys_staff_required
|
||||
@api_view(('GET',))
|
||||
def sys_log_export_excel(request):
|
||||
task_id = request.GET.get('task_id', None)
|
||||
log_type = request.GET.get('log_type', None)
|
||||
|
41
seahub/api2/endpoints/seahub_io.py
Normal file
41
seahub/api2/endpoints/seahub_io.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import logging
|
||||
import json
|
||||
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.endpoints.utils import event_export_status
|
||||
from seahub.api2.permissions import IsProVersion
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.api2.utils import api_error
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SeahubIOStatus(APIView):
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsProVersion,)
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
Get task status by task id
|
||||
"""
|
||||
task_id = request.GET.get('task_id', '')
|
||||
if not task_id:
|
||||
error_msg = 'task_id invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
resp = event_export_status(task_id)
|
||||
if resp.status_code == 500:
|
||||
logger.error('query export status error: %s, %s' % (task_id, resp.content))
|
||||
return api_error(500, 'Internal Server Error')
|
||||
if not resp.status_code == 200:
|
||||
return api_error(resp.status_code, resp.content)
|
||||
|
||||
is_finished = json.loads(resp.content)['is_finished']
|
||||
|
||||
return Response({'is_finished': is_finished})
|
@@ -296,13 +296,16 @@ def format_date(start, end):
|
||||
return start_timestamp, end_timestamp
|
||||
|
||||
|
||||
def export_logs_to_excel(start, end, log_type):
|
||||
def export_logs_to_excel(start, end, log_type, org_id=None):
|
||||
start_time, end_time = format_date(start, end)
|
||||
payload = {'exp': int(time.time()) + 300, }
|
||||
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
|
||||
headers = {"Authorization": "Token %s" % token}
|
||||
url = urljoin(SEAFEVENTS_SERVER_URL, '/add-init-export-log-task')
|
||||
params = {'start_time': start_time, 'end_time': end_time, 'log_type': log_type}
|
||||
if not org_id:
|
||||
url = urljoin(SEAFEVENTS_SERVER_URL, '/add-export-log-task')
|
||||
else:
|
||||
url = urljoin(SEAFEVENTS_SERVER_URL, '/add-org-export-log-task')
|
||||
params = {'start_time': start_time, 'end_time': end_time, 'log_type': log_type, 'org_id': org_id}
|
||||
resp = requests.get(url, params=params, headers=headers)
|
||||
return json.loads(resp.content)['task_id']
|
||||
|
||||
|
@@ -31,6 +31,8 @@ from .api.admin.statistics import OrgFileOperationsView, OrgTotalStorageView, \
|
||||
OrgUserTrafficExcelView, OrgUserStorageExcelView
|
||||
from .api.admin.saml_config import OrgSAMLConfigView, OrgVerifyDomain
|
||||
|
||||
from .org_logs_export import OrgLogsExport, org_log_export_excel
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('<int:org_id>/admin/statistics/file-operations/',
|
||||
@@ -101,5 +103,8 @@ urlpatterns = [
|
||||
path('admin/logs/file-update/', OrgAdminLogsFileUpdate.as_view(), name='api-v2.1-org-admin-logs-file-update'),
|
||||
path('admin/logs/repo-permission/', OrgAdminLogsPermAudit.as_view(), name='api-v2.1-org-admin-logs-repo-permission'),
|
||||
path('<int:org_id>/admin/departments/', OrgAdminDepartments.as_view(), name='api-v2.1-org-admin-departments'),
|
||||
path('<int:org_id>/admin/logs/export-excel/', OrgLogsExport.as_view(), name='api-v2.1-org-logs-export-excel'),
|
||||
path('admin/log/export-excel/', org_log_export_excel, name='org_log_export_excel'),
|
||||
|
||||
]
|
||||
|
||||
|
72
seahub/organizations/org_logs_export.py
Normal file
72
seahub/organizations/org_logs_export.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import os
|
||||
import logging
|
||||
from shutil import rmtree
|
||||
from django.http import FileResponse
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import api_view
|
||||
from urllib.parse import quote
|
||||
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.endpoints.utils import check_time_period_valid, export_logs_to_excel
|
||||
from seahub.api2.permissions import IsProVersion
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.api2.utils import api_error
|
||||
from seahub.auth.decorators import login_required
|
||||
from seahub.organizations.api.permissions import IsOrgAdmin
|
||||
from seahub.organizations.decorators import org_staff_required
|
||||
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OrgLogsExport(APIView):
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsOrgAdmin, IsProVersion)
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
|
||||
def get(self, request, org_id):
|
||||
start = request.GET.get('start', None)
|
||||
end = request.GET.get('end', None)
|
||||
log_type = request.GET.get('logType', None)
|
||||
if not check_time_period_valid(start, end):
|
||||
error_msg = 'Failed to export excel, invalid start or end date.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
task_id = export_logs_to_excel(start, end, log_type, org_id)
|
||||
res_data = {'task_id': task_id}
|
||||
return Response(res_data)
|
||||
|
||||
|
||||
@login_required
|
||||
@org_staff_required
|
||||
@api_view(('GET',))
|
||||
def org_log_export_excel(request):
|
||||
task_id = request.GET.get('task_id', None)
|
||||
log_type = request.GET.get('log_type', None)
|
||||
if not task_id:
|
||||
error_msg = 'task_id invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
if log_type == 'fileaudit':
|
||||
excel_name = 'file-access-logs.xlsx'
|
||||
elif log_type == 'fileupdate':
|
||||
excel_name = 'file-update-logs.xlsx'
|
||||
elif log_type == 'permaudit':
|
||||
excel_name = 'perm-audit-logs.xlsx'
|
||||
else:
|
||||
error_msg = 'log_type invalid'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
target_dir = os.path.join('/tmp/seafile_events/', task_id)
|
||||
tmp_excel_path = os.path.join(target_dir, excel_name)
|
||||
if not os.path.isfile(tmp_excel_path):
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, excel_name + ' not found.')
|
||||
response = FileResponse(open(tmp_excel_path, 'rb'), content_type='application/ms-excel', as_attachment=True)
|
||||
try:
|
||||
rmtree(target_dir)
|
||||
except OSError:
|
||||
pass
|
||||
response['Content-Disposition'] = 'attachment;filename*=UTF-8\'\'' + quote(excel_name)
|
||||
return response
|
@@ -125,7 +125,7 @@ from seahub.api2.endpoints.repo_share_links import RepoShareLinks, RepoShareLink
|
||||
from seahub.api2.endpoints.repo_upload_links import RepoUploadLinks, RepoUploadLink
|
||||
|
||||
# Admin
|
||||
from seahub.api2.endpoints.admin.logs_export import SysLogsExport, FileLogsExportStatus, sys_log_export_excel
|
||||
from seahub.api2.endpoints.admin.logs_export import SysLogsExport, sys_log_export_excel
|
||||
from seahub.api2.endpoints.admin.abuse_reports import AdminAbuseReportsView, AdminAbuseReportView
|
||||
from seahub.api2.endpoints.admin.revision_tag import AdminTaggedItemsView
|
||||
from seahub.api2.endpoints.admin.login_logs import LoginLogs, AdminLoginLogs
|
||||
@@ -212,6 +212,7 @@ from seahub.api2.endpoints.subscription import SubscriptionView, SubscriptionPla
|
||||
from seahub.api2.endpoints.metadata_manage import MetadataRecords, MetadataManage, MetadataColumns, MetadataRecordInfo, \
|
||||
MetadataViews, MetadataViewsMoveView, MetadataViewsDetailView, MetadataViewsDuplicateView
|
||||
from seahub.api2.endpoints.user_list import UserListView
|
||||
from seahub.api2.endpoints.seahub_io import SeahubIOStatus
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
@@ -911,7 +912,7 @@ if is_pro_version():
|
||||
re_path(r'^api/v2.1/admin/logs/perm-audit/$', PermAudit.as_view(), name='api-v2.1-admin-logs-perm-audit'),
|
||||
|
||||
re_path(r'^api/v2.1/admin/logs/export-excel/$', SysLogsExport.as_view(), name='api-v2.1-admin-logs-export-excel'),
|
||||
re_path(r'^api/v2.1/query-export-status/$', FileLogsExportStatus.as_view(), name='api-v2.1-query-export-status'),
|
||||
re_path(r'^api/v2.1/query-io-status/$', SeahubIOStatus.as_view(), name='api-v2.1-query-export-status'),
|
||||
path('sys/log/export-excel/', sys_log_export_excel, name='sys_log_export_excel'),
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user