1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-04-28 03:10:45 +00:00

add size control (#4339)

* check file size before upload file

* update file naming
This commit is contained in:
杨顺强 2019-12-13 16:16:02 +08:00 committed by Daniel Pan
parent d5f4f036b3
commit 3970035c20
6 changed files with 68 additions and 10 deletions

View File

@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Resumablejs from '@seafile/resumablejs'; import Resumablejs from '@seafile/resumablejs';
import MD5 from 'MD5'; import MD5 from 'MD5';
import { enableResumableFileUpload, resumableUploadFileBlockSize } from '../../utils/constants'; import { enableResumableFileUpload, resumableUploadFileBlockSize, maxUploadFileSize } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api'; import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils'; import { Utils } from '../../utils/utils';
import { gettext } from '../../utils/constants'; import { gettext } from '../../utils/constants';
@ -18,13 +18,11 @@ const propTypes = {
chunkSize: PropTypes.number, chunkSize: PropTypes.number,
withCredentials: PropTypes.bool, withCredentials: PropTypes.bool,
maxFiles: PropTypes.number, maxFiles: PropTypes.number,
maxFileSize: PropTypes.number,
testMethod: PropTypes.string, testMethod: PropTypes.string,
testChunks: PropTypes.number, testChunks: PropTypes.number,
simultaneousUploads: PropTypes.number, simultaneousUploads: PropTypes.number,
fileParameterName: PropTypes.string, fileParameterName: PropTypes.string,
maxFilesErrorCallback: PropTypes.func, maxFilesErrorCallback: PropTypes.func,
maxFileSizeErrorCallback: PropTypes.func,
minFileSizeErrorCallback: PropTypes.func, minFileSizeErrorCallback: PropTypes.func,
fileTypeErrorCallback: PropTypes.func, fileTypeErrorCallback: PropTypes.func,
dragAndDrop: PropTypes.bool.isRequired, dragAndDrop: PropTypes.bool.isRequired,
@ -39,6 +37,7 @@ class FileUploader extends React.Component {
this.state = { this.state = {
retryFileList: [], retryFileList: [],
uploadFileList: [], uploadFileList: [],
forbidUploadFileList: [],
totalProgress: 0, totalProgress: 0,
isUploadProgressDialogShow: false, isUploadProgressDialogShow: false,
isUploadRemindDialogShow: false, isUploadRemindDialogShow: false,
@ -64,7 +63,7 @@ class FileUploader extends React.Component {
query: this.setQuery || {}, query: this.setQuery || {},
fileType: this.props.filetypes, fileType: this.props.filetypes,
maxFiles: this.props.maxFiles, maxFiles: this.props.maxFiles,
maxFileSize: this.props.maxFileSize, maxFileSize: maxUploadFileSize * 1000 * 1000 || undefined,
testMethod: this.props.testMethod || 'post', testMethod: this.props.testMethod || 'post',
testChunks: this.props.testChunks || false, testChunks: this.props.testChunks || false,
headers: this.setHeaders || {}, headers: this.setHeaders || {},
@ -105,7 +104,7 @@ class FileUploader extends React.Component {
} }
bindCallbackHandler = () => { bindCallbackHandler = () => {
let {maxFilesErrorCallback, minFileSizeErrorCallback, maxFileSizeErrorCallback, fileTypeErrorCallback } = this.props; let {maxFilesErrorCallback, minFileSizeErrorCallback, fileTypeErrorCallback } = this.props;
if (maxFilesErrorCallback) { if (maxFilesErrorCallback) {
this.resumable.opts.maxFilesErrorCallback = this.props.maxFilesErrorCallback; this.resumable.opts.maxFilesErrorCallback = this.props.maxFilesErrorCallback;
@ -115,8 +114,8 @@ class FileUploader extends React.Component {
this.resumable.opts.minFileSizeErrorCallback = this.props.minFileSizeErrorCallback; this.resumable.opts.minFileSizeErrorCallback = this.props.minFileSizeErrorCallback;
} }
if (maxFileSizeErrorCallback) { if (this.maxFileSizeErrorCallback) {
this.resumable.opts.maxFileSizeErrorCallback = this.props.maxFileSizeErrorCallback; this.resumable.opts.maxFileSizeErrorCallback = this.maxFileSizeErrorCallback;
} }
if (fileTypeErrorCallback) { if (fileTypeErrorCallback) {
@ -142,6 +141,12 @@ class FileUploader extends React.Component {
this.resumable.on('dragstart', this.onDragStart.bind(this)); this.resumable.on('dragstart', this.onDragStart.bind(this));
} }
maxFileSizeErrorCallback = (file) => {
let { forbidUploadFileList } = this.state;
forbidUploadFileList.push(file);
this.setState({forbidUploadFileList: forbidUploadFileList});
}
onChunkingComplete = (resumableFile) => { onChunkingComplete = (resumableFile) => {
let allFilesUploaded = this.state.allFilesUploaded; let allFilesUploaded = this.state.allFilesUploaded;
@ -229,7 +234,13 @@ class FileUploader extends React.Component {
} }
filesAddedComplete = (resumable, files) => { filesAddedComplete = (resumable, files) => {
// single file uploading can check repetition, because custom dialog conn't prevent program execution; let { forbidUploadFileList } = this.state;
if (forbidUploadFileList.length > 0 && files.length === 0) {
this.setState({
isUploadProgressDialogShow: true,
totalProgress: 100
});
}
} }
setUploadFileList = () => { setUploadFileList = () => {
@ -481,7 +492,7 @@ class FileUploader extends React.Component {
this.resumable.files = []; this.resumable.files = [];
// reset upload link loaded // reset upload link loaded
this.isUploadLinkLoaded = false; this.isUploadLinkLoaded = false;
this.setState({isUploadProgressDialogShow: false, uploadFileList: []}); this.setState({isUploadProgressDialogShow: false, uploadFileList: [], forbidUploadFileList: []});
Utils.registerGlobalVariable('uploader', 'isUploadProgressDialogShow', false); Utils.registerGlobalVariable('uploader', 'isUploadProgressDialogShow', false);
} }
@ -667,6 +678,7 @@ class FileUploader extends React.Component {
<UploadProgressDialog <UploadProgressDialog
retryFileList={this.state.retryFileList} retryFileList={this.state.retryFileList}
uploadFileList={this.state.uploadFileList} uploadFileList={this.state.uploadFileList}
forbidUploadFileList={this.state.forbidUploadFileList}
totalProgress={this.state.totalProgress} totalProgress={this.state.totalProgress}
uploadBitrate={this.state.uploadBitrate} uploadBitrate={this.state.uploadBitrate}
allFilesUploaded={this.state.allFilesUploaded} allFilesUploaded={this.state.allFilesUploaded}

View File

@ -0,0 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext, maxUploadFileSize } from '../../utils/constants';
const propTypes = {
file: PropTypes.object,
};
class ForbidUploadListItem extends React.Component {
render() {
let { file } = this.props;
let msg = gettext('Please upload files less than {placeholder}M').replace('{placeholder}', maxUploadFileSize);
return (
<tr className="file-upload-item">
<td className="upload-name">
<div className="ellipsis">{file.name}</div>
</td>
<td colSpan={3} className="error">{msg}</td>
</tr>
);
}
}
ForbidUploadListItem.propTypes = propTypes;
export default ForbidUploadListItem;

View File

@ -1,14 +1,16 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants'; import { gettext } from '../../utils/constants';
import UploadListItem from './upload-list-item';
import { Utils } from '../../utils/utils'; import { Utils } from '../../utils/utils';
import UploadListItem from './upload-list-item';
import ForbidUploadListItem from './forbid-upload-list-item';
const propTypes = { const propTypes = {
uploadBitrate: PropTypes.number.isRequired, uploadBitrate: PropTypes.number.isRequired,
totalProgress: PropTypes.number.isRequired, totalProgress: PropTypes.number.isRequired,
retryFileList: PropTypes.array.isRequired, retryFileList: PropTypes.array.isRequired,
uploadFileList: PropTypes.array.isRequired, uploadFileList: PropTypes.array.isRequired,
forbidUploadFileList: PropTypes.array.isRequired,
onCloseUploadDialog: PropTypes.func.isRequired, onCloseUploadDialog: PropTypes.func.isRequired,
onCancelAllUploading: PropTypes.func.isRequired, onCancelAllUploading: PropTypes.func.isRequired,
onUploadCancel: PropTypes.func.isRequired, onUploadCancel: PropTypes.func.isRequired,
@ -94,6 +96,11 @@ class UploadProgressDialog extends React.Component {
} }
</td> </td>
</tr> </tr>
{
this.props.forbidUploadFileList.map((file, index) => {
return (<ForbidUploadListItem key={index} file={file} />);
})
}
{ {
this.props.uploadFileList.map((resumableFile, index) => { this.props.uploadFileList.map((resumableFile, index) => {
return ( return (

View File

@ -54,6 +54,7 @@ export const canAddPublicRepo = window.app.pageOptions.canAddPublicRepo;
export const canInvitePeople = window.app.pageOptions.canInvitePeople; export const canInvitePeople = window.app.pageOptions.canInvitePeople;
export const canLockUnlockFile = window.app.pageOptions.canLockUnlockFile; export const canLockUnlockFile = window.app.pageOptions.canLockUnlockFile;
export const customNavItems = window.app.pageOptions.customNavItems; export const customNavItems = window.app.pageOptions.customNavItems;
export const maxUploadFileSize = window.app.pageOptions.maxUploadFileSize;
export const curNoteMsg = window.app.pageOptions.curNoteMsg; export const curNoteMsg = window.app.pageOptions.curNoteMsg;
export const curNoteID = window.app.pageOptions.curNoteID; export const curNoteID = window.app.pageOptions.curNoteID;

View File

@ -91,6 +91,9 @@
canAddPublicRepo: {% if can_add_public_repo %} true {% else %} false {% endif %}, canAddPublicRepo: {% if can_add_public_repo %} true {% else %} false {% endif %},
canInvitePeople: {% if enable_guest_invitation and user.permissions.can_invite_guest %} true {% else %} false {% endif %}, canInvitePeople: {% if enable_guest_invitation and user.permissions.can_invite_guest %} true {% else %} false {% endif %},
customNavItems: {% if custom_nav_items %} JSON.parse('{{ custom_nav_items | escapejs }}') {% else %} {{'[]'}} {% endif %}, customNavItems: {% if custom_nav_items %} JSON.parse('{{ custom_nav_items | escapejs }}') {% else %} {{'[]'}} {% endif %},
{% if max_upload_file_size > 0 %}
maxUploadFileSize: {{ max_upload_file_size }},
{% endif %}
{% if request.user.is_authenticated and request.cur_note %} {% if request.user.is_authenticated and request.cur_note %}
curNoteMsg: '{{ request.cur_note.message|urlize|escapejs }}', curNoteMsg: '{{ request.cur_note.message|urlize|escapejs }}',

View File

@ -1252,7 +1252,14 @@ def choose_register(request):
def react_fake_view(request, **kwargs): def react_fake_view(request, **kwargs):
folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False
try:
max_upload_file_size = seafile_api.get_server_config_int('fileserver', 'max_upload_size')
except Exception as e:
logger.error(e)
max_upload_file_size = -1
return render(request, "react_app.html", { return render(request, "react_app.html", {
'max_upload_file_size': max_upload_file_size,
'seafile_collab_server': SEAFILE_COLLAB_SERVER, 'seafile_collab_server': SEAFILE_COLLAB_SERVER,
'storages': get_library_storages(request), 'storages': get_library_storages(request),
'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL, 'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL,