From 3970035c207323c76a25191bf4e43241baa93c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E9=A1=BA=E5=BC=BA?= Date: Fri, 13 Dec 2019 16:16:02 +0800 Subject: [PATCH] add size control (#4339) * check file size before upload file * update file naming --- .../components/file-uploader/file-uploader.js | 30 +++++++++++++------ .../file-uploader/forbid-upload-list-item.js | 28 +++++++++++++++++ .../file-uploader/upload-progress-dialog.js | 9 +++++- frontend/src/utils/constants.js | 1 + seahub/templates/base_for_react.html | 3 ++ seahub/views/__init__.py | 7 +++++ 6 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 frontend/src/components/file-uploader/forbid-upload-list-item.js diff --git a/frontend/src/components/file-uploader/file-uploader.js b/frontend/src/components/file-uploader/file-uploader.js index 247ae84626..357d09cc9b 100644 --- a/frontend/src/components/file-uploader/file-uploader.js +++ b/frontend/src/components/file-uploader/file-uploader.js @@ -2,7 +2,7 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import Resumablejs from '@seafile/resumablejs'; import MD5 from 'MD5'; -import { enableResumableFileUpload, resumableUploadFileBlockSize } from '../../utils/constants'; +import { enableResumableFileUpload, resumableUploadFileBlockSize, maxUploadFileSize } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; import { gettext } from '../../utils/constants'; @@ -18,13 +18,11 @@ const propTypes = { chunkSize: PropTypes.number, withCredentials: PropTypes.bool, maxFiles: PropTypes.number, - maxFileSize: PropTypes.number, testMethod: PropTypes.string, testChunks: PropTypes.number, simultaneousUploads: PropTypes.number, fileParameterName: PropTypes.string, maxFilesErrorCallback: PropTypes.func, - maxFileSizeErrorCallback: PropTypes.func, minFileSizeErrorCallback: PropTypes.func, fileTypeErrorCallback: PropTypes.func, dragAndDrop: PropTypes.bool.isRequired, @@ -39,6 +37,7 @@ class FileUploader extends React.Component { this.state = { retryFileList: [], uploadFileList: [], + forbidUploadFileList: [], totalProgress: 0, isUploadProgressDialogShow: false, isUploadRemindDialogShow: false, @@ -64,7 +63,7 @@ class FileUploader extends React.Component { query: this.setQuery || {}, fileType: this.props.filetypes, maxFiles: this.props.maxFiles, - maxFileSize: this.props.maxFileSize, + maxFileSize: maxUploadFileSize * 1000 * 1000 || undefined, testMethod: this.props.testMethod || 'post', testChunks: this.props.testChunks || false, headers: this.setHeaders || {}, @@ -105,7 +104,7 @@ class FileUploader extends React.Component { } bindCallbackHandler = () => { - let {maxFilesErrorCallback, minFileSizeErrorCallback, maxFileSizeErrorCallback, fileTypeErrorCallback } = this.props; + let {maxFilesErrorCallback, minFileSizeErrorCallback, fileTypeErrorCallback } = this.props; if (maxFilesErrorCallback) { this.resumable.opts.maxFilesErrorCallback = this.props.maxFilesErrorCallback; @@ -115,8 +114,8 @@ class FileUploader extends React.Component { this.resumable.opts.minFileSizeErrorCallback = this.props.minFileSizeErrorCallback; } - if (maxFileSizeErrorCallback) { - this.resumable.opts.maxFileSizeErrorCallback = this.props.maxFileSizeErrorCallback; + if (this.maxFileSizeErrorCallback) { + this.resumable.opts.maxFileSizeErrorCallback = this.maxFileSizeErrorCallback; } if (fileTypeErrorCallback) { @@ -142,6 +141,12 @@ class FileUploader extends React.Component { this.resumable.on('dragstart', this.onDragStart.bind(this)); } + maxFileSizeErrorCallback = (file) => { + let { forbidUploadFileList } = this.state; + forbidUploadFileList.push(file); + this.setState({forbidUploadFileList: forbidUploadFileList}); + } + onChunkingComplete = (resumableFile) => { let allFilesUploaded = this.state.allFilesUploaded; @@ -229,7 +234,13 @@ class FileUploader extends React.Component { } 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 = () => { @@ -481,7 +492,7 @@ class FileUploader extends React.Component { this.resumable.files = []; // reset upload link loaded this.isUploadLinkLoaded = false; - this.setState({isUploadProgressDialogShow: false, uploadFileList: []}); + this.setState({isUploadProgressDialogShow: false, uploadFileList: [], forbidUploadFileList: []}); Utils.registerGlobalVariable('uploader', 'isUploadProgressDialogShow', false); } @@ -667,6 +678,7 @@ class FileUploader extends React.Component { + +
{file.name}
+ + + {msg} + + ); + } +} + +ForbidUploadListItem.propTypes = propTypes; + +export default ForbidUploadListItem; diff --git a/frontend/src/components/file-uploader/upload-progress-dialog.js b/frontend/src/components/file-uploader/upload-progress-dialog.js index 2cbfecbf68..7a94726e62 100644 --- a/frontend/src/components/file-uploader/upload-progress-dialog.js +++ b/frontend/src/components/file-uploader/upload-progress-dialog.js @@ -1,14 +1,16 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { gettext } from '../../utils/constants'; -import UploadListItem from './upload-list-item'; import { Utils } from '../../utils/utils'; +import UploadListItem from './upload-list-item'; +import ForbidUploadListItem from './forbid-upload-list-item'; const propTypes = { uploadBitrate: PropTypes.number.isRequired, totalProgress: PropTypes.number.isRequired, retryFileList: PropTypes.array.isRequired, uploadFileList: PropTypes.array.isRequired, + forbidUploadFileList: PropTypes.array.isRequired, onCloseUploadDialog: PropTypes.func.isRequired, onCancelAllUploading: PropTypes.func.isRequired, onUploadCancel: PropTypes.func.isRequired, @@ -94,6 +96,11 @@ class UploadProgressDialog extends React.Component { } + { + this.props.forbidUploadFileList.map((file, index) => { + return (); + }) + } { this.props.uploadFileList.map((resumableFile, index) => { return ( diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 254d8f48d9..3db994dfc2 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -54,6 +54,7 @@ export const canAddPublicRepo = window.app.pageOptions.canAddPublicRepo; export const canInvitePeople = window.app.pageOptions.canInvitePeople; export const canLockUnlockFile = window.app.pageOptions.canLockUnlockFile; export const customNavItems = window.app.pageOptions.customNavItems; +export const maxUploadFileSize = window.app.pageOptions.maxUploadFileSize; export const curNoteMsg = window.app.pageOptions.curNoteMsg; export const curNoteID = window.app.pageOptions.curNoteID; diff --git a/seahub/templates/base_for_react.html b/seahub/templates/base_for_react.html index 189810a25e..d3dc4496e7 100644 --- a/seahub/templates/base_for_react.html +++ b/seahub/templates/base_for_react.html @@ -91,6 +91,9 @@ 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 %}, 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 %} curNoteMsg: '{{ request.cur_note.message|urlize|escapejs }}', diff --git a/seahub/views/__init__.py b/seahub/views/__init__.py index 3a836023d1..69e9821575 100644 --- a/seahub/views/__init__.py +++ b/seahub/views/__init__.py @@ -1252,7 +1252,14 @@ def choose_register(request): def react_fake_view(request, **kwargs): 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", { + 'max_upload_file_size': max_upload_file_size, 'seafile_collab_server': SEAFILE_COLLAB_SERVER, 'storages': get_library_storages(request), 'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL,