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:
parent
d5f4f036b3
commit
3970035c20
@ -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}
|
||||||
|
@ -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;
|
@ -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 (
|
||||||
|
@ -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;
|
||||||
|
@ -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 }}',
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user