mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-08 18:30:53 +00:00
Merge branch '7.0'
This commit is contained in:
@@ -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, maxUploadFileSize } from '../../utils/constants';
|
import { resumableUploadFileBlockSize, maxUploadFileSize, maxNumberOfFilesForFileupload } 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';
|
||||||
@@ -17,12 +17,10 @@ const propTypes = {
|
|||||||
filetypes: PropTypes.array,
|
filetypes: PropTypes.array,
|
||||||
chunkSize: PropTypes.number,
|
chunkSize: PropTypes.number,
|
||||||
withCredentials: PropTypes.bool,
|
withCredentials: PropTypes.bool,
|
||||||
maxFiles: 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,
|
|
||||||
minFileSizeErrorCallback: PropTypes.func,
|
minFileSizeErrorCallback: PropTypes.func,
|
||||||
fileTypeErrorCallback: PropTypes.func,
|
fileTypeErrorCallback: PropTypes.func,
|
||||||
dragAndDrop: PropTypes.bool.isRequired,
|
dragAndDrop: PropTypes.bool.isRequired,
|
||||||
@@ -62,7 +60,7 @@ class FileUploader extends React.Component {
|
|||||||
target: '',
|
target: '',
|
||||||
query: this.setQuery || {},
|
query: this.setQuery || {},
|
||||||
fileType: this.props.filetypes,
|
fileType: this.props.filetypes,
|
||||||
maxFiles: this.props.maxFiles,
|
maxFiles: maxNumberOfFilesForFileupload || undefined,
|
||||||
maxFileSize: maxUploadFileSize * 1000 * 1000 || undefined,
|
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,
|
||||||
@@ -104,10 +102,10 @@ class FileUploader extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bindCallbackHandler = () => {
|
bindCallbackHandler = () => {
|
||||||
let {maxFilesErrorCallback, minFileSizeErrorCallback, fileTypeErrorCallback } = this.props;
|
let { minFileSizeErrorCallback, fileTypeErrorCallback } = this.props;
|
||||||
|
|
||||||
if (maxFilesErrorCallback) {
|
if (this.maxFilesErrorCallback) {
|
||||||
this.resumable.opts.maxFilesErrorCallback = this.props.maxFilesErrorCallback;
|
this.resumable.opts.maxFilesErrorCallback = this.maxFilesErrorCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minFileSizeErrorCallback) {
|
if (minFileSizeErrorCallback) {
|
||||||
@@ -141,6 +139,16 @@ class FileUploader extends React.Component {
|
|||||||
this.resumable.on('dragstart', this.onDragStart.bind(this));
|
this.resumable.on('dragstart', this.onDragStart.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxFilesErrorCallback = (files, errorCount) => {
|
||||||
|
let maxFiles = maxNumberOfFilesForFileupload;
|
||||||
|
let message = gettext('Please upload no more than {maxFiles} files at a time.');
|
||||||
|
if (maxFiles === 1) {
|
||||||
|
message = gettext('Please upload no more than {maxFiles} file at a time.');
|
||||||
|
}
|
||||||
|
message = message.replace('{maxFiles}', maxFiles);
|
||||||
|
toaster.danger(message);
|
||||||
|
}
|
||||||
|
|
||||||
maxFileSizeErrorCallback = (file) => {
|
maxFileSizeErrorCallback = (file) => {
|
||||||
let { forbidUploadFileList } = this.state;
|
let { forbidUploadFileList } = this.state;
|
||||||
forbidUploadFileList.push(file);
|
forbidUploadFileList.push(file);
|
||||||
|
@@ -59,6 +59,7 @@ 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 maxUploadFileSize = window.app.pageOptions.maxUploadFileSize;
|
||||||
|
export const maxNumberOfFilesForFileupload = window.app.pageOptions.maxNumberOfFilesForFileupload;
|
||||||
|
|
||||||
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;
|
||||||
|
@@ -48,6 +48,8 @@ def common_check(func):
|
|||||||
return _decorated
|
return _decorated
|
||||||
|
|
||||||
def get_dirent_info(dirent):
|
def get_dirent_info(dirent):
|
||||||
|
if not dirent:
|
||||||
|
return {}
|
||||||
|
|
||||||
if stat.S_ISDIR(dirent.mode):
|
if stat.S_ISDIR(dirent.mode):
|
||||||
is_file = False
|
is_file = False
|
||||||
@@ -175,13 +177,7 @@ class AdminLibraryDirent(APIView):
|
|||||||
|
|
||||||
path = normalize_file_path(path)
|
path = normalize_file_path(path)
|
||||||
|
|
||||||
try:
|
dirent = seafile_api.get_dirent_by_path(repo_id, path)
|
||||||
dirent = seafile_api.get_dirent_by_path(repo_id, path)
|
|
||||||
except SearpcError as e:
|
|
||||||
logger.error(e)
|
|
||||||
error_msg = 'Internal Server Error'
|
|
||||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
|
||||||
|
|
||||||
if not dirent:
|
if not dirent:
|
||||||
error_msg = 'File or folder %s not found.' % path
|
error_msg = 'File or folder %s not found.' % path
|
||||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
@@ -224,13 +220,7 @@ class AdminLibraryDirent(APIView):
|
|||||||
error_msg = 'path invalid.'
|
error_msg = 'path invalid.'
|
||||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
try:
|
dirent = seafile_api.get_dirent_by_path(repo_id, path)
|
||||||
dirent = seafile_api.get_dirent_by_path(repo_id, path)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(e)
|
|
||||||
error_msg = 'Internal Server Error'
|
|
||||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
|
||||||
|
|
||||||
if not dirent:
|
if not dirent:
|
||||||
error_msg = 'File or folder %s not found.' % path
|
error_msg = 'File or folder %s not found.' % path
|
||||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
|
@@ -189,9 +189,9 @@ class DirView(APIView):
|
|||||||
'type': 'dir',
|
'type': 'dir',
|
||||||
'repo_id': repo_id,
|
'repo_id': repo_id,
|
||||||
'parent_dir': os.path.dirname(dir_path.rstrip('/')),
|
'parent_dir': os.path.dirname(dir_path.rstrip('/')),
|
||||||
'obj_name': dir_obj.obj_name,
|
'obj_name': dir_obj.obj_name if dir_obj else '',
|
||||||
'obj_id': dir_obj.obj_id,
|
'obj_id': dir_obj.obj_id if dir_obj else '',
|
||||||
'mtime': timestamp_to_isoformat_timestr(dir_obj.mtime),
|
'mtime': timestamp_to_isoformat_timestr(dir_obj.mtime) if dir_obj else '',
|
||||||
}
|
}
|
||||||
|
|
||||||
return dir_info
|
return dir_info
|
||||||
@@ -568,18 +568,12 @@ class DirDetailView(APIView):
|
|||||||
error_msg = 'Permission denied.'
|
error_msg = 'Permission denied.'
|
||||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||||
|
|
||||||
try:
|
dir_obj = seafile_api.get_dirent_by_path(repo_id, path)
|
||||||
dir_obj = seafile_api.get_dirent_by_path(repo_id, path)
|
|
||||||
except SearpcError as e:
|
|
||||||
logger.error(e)
|
|
||||||
error_msg = 'Internal Server Error'
|
|
||||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
|
||||||
|
|
||||||
dir_info = {
|
dir_info = {
|
||||||
'repo_id': repo_id,
|
'repo_id': repo_id,
|
||||||
'path': path,
|
'path': path,
|
||||||
'name': dir_obj.obj_name,
|
'name': dir_obj.obj_name if dir_obj else '',
|
||||||
'mtime': timestamp_to_isoformat_timestr(dir_obj.mtime),
|
'mtime': timestamp_to_isoformat_timestr(dir_obj.mtime) if dir_obj else '',
|
||||||
'permission': permission,
|
'permission': permission,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,11 +53,14 @@ class FileView(APIView):
|
|||||||
|
|
||||||
repo = seafile_api.get_repo(repo_id)
|
repo = seafile_api.get_repo(repo_id)
|
||||||
file_obj = seafile_api.get_dirent_by_path(repo_id, file_path)
|
file_obj = seafile_api.get_dirent_by_path(repo_id, file_path)
|
||||||
file_name = file_obj.obj_name
|
if file_obj:
|
||||||
file_size = file_obj.size
|
file_name = file_obj.obj_name
|
||||||
|
file_size = file_obj.size
|
||||||
can_preview, error_msg = can_preview_file(file_name, file_size, repo)
|
can_preview, error_msg = can_preview_file(file_name, file_size, repo)
|
||||||
can_edit, error_msg = can_edit_file(file_name, file_size, repo)
|
can_edit, error_msg = can_edit_file(file_name, file_size, repo)
|
||||||
|
else:
|
||||||
|
can_preview = False
|
||||||
|
can_edit = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
is_locked, locked_by_me = check_file_lock(repo_id, file_path, username)
|
is_locked, locked_by_me = check_file_lock(repo_id, file_path, username)
|
||||||
@@ -70,9 +73,9 @@ class FileView(APIView):
|
|||||||
'repo_id': repo_id,
|
'repo_id': repo_id,
|
||||||
'parent_dir': os.path.dirname(file_path),
|
'parent_dir': os.path.dirname(file_path),
|
||||||
'obj_name': file_name,
|
'obj_name': file_name,
|
||||||
'obj_id': file_obj.obj_id,
|
'obj_id': file_obj.obj_id if file_obj else '',
|
||||||
'size': file_size,
|
'size': file_size,
|
||||||
'mtime': timestamp_to_isoformat_timestr(file_obj.mtime),
|
'mtime': timestamp_to_isoformat_timestr(file_obj.mtime) if file_obj else '',
|
||||||
'is_locked': is_locked,
|
'is_locked': is_locked,
|
||||||
'can_preview': can_preview,
|
'can_preview': can_preview,
|
||||||
'can_edit': can_edit,
|
'can_edit': can_edit,
|
||||||
|
@@ -92,11 +92,14 @@ def get_share_link_info(fileshare):
|
|||||||
data['can_edit'] = False
|
data['can_edit'] = False
|
||||||
if repo and path != '/' and not data['is_dir']:
|
if repo and path != '/' and not data['is_dir']:
|
||||||
dirent = seafile_api.get_dirent_by_path(repo_id, path)
|
dirent = seafile_api.get_dirent_by_path(repo_id, path)
|
||||||
try:
|
if dirent:
|
||||||
can_edit, error_msg = can_edit_file(obj_name, dirent.size, repo)
|
try:
|
||||||
data['can_edit'] = can_edit
|
can_edit, error_msg = can_edit_file(obj_name, dirent.size, repo)
|
||||||
except Exception as e:
|
data['can_edit'] = can_edit
|
||||||
logger.error(e)
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
else:
|
||||||
|
data['can_edit'] = False
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@@ -159,7 +159,7 @@ class WikiPageContentView(APIView):
|
|||||||
url = gen_inner_file_get_url(token, file_name)
|
url = gen_inner_file_get_url(token, file_name)
|
||||||
file_response = urllib.request.urlopen(url)
|
file_response = urllib.request.urlopen(url)
|
||||||
content = file_response.read()
|
content = file_response.read()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dirent = seafile_api.get_dirent_by_path(repo.repo_id, path)
|
dirent = seafile_api.get_dirent_by_path(repo.repo_id, path)
|
||||||
if dirent:
|
if dirent:
|
||||||
|
@@ -99,7 +99,9 @@
|
|||||||
{% if max_upload_file_size > 0 %}
|
{% if max_upload_file_size > 0 %}
|
||||||
maxUploadFileSize: {{ max_upload_file_size }},
|
maxUploadFileSize: {{ max_upload_file_size }},
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if max_number_of_files_for_fileupload > 0 %}
|
||||||
|
maxNumberOfFilesForFileupload: {{ max_number_of_files_for_fileupload }},
|
||||||
|
{% 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 }}',
|
||||||
curNoteID: '{{ request.cur_note.id }}',
|
curNoteID: '{{ request.cur_note.id }}',
|
||||||
|
@@ -1146,6 +1146,7 @@ def react_fake_view(request, **kwargs):
|
|||||||
'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,
|
||||||
'resumable_upload_file_block_size': settings.RESUMABLE_UPLOAD_FILE_BLOCK_SIZE,
|
'resumable_upload_file_block_size': settings.RESUMABLE_UPLOAD_FILE_BLOCK_SIZE,
|
||||||
|
'max_number_of_files_for_fileupload': settings.MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD,
|
||||||
'share_link_expire_days_default': settings.SHARE_LINK_EXPIRE_DAYS_DEFAULT,
|
'share_link_expire_days_default': settings.SHARE_LINK_EXPIRE_DAYS_DEFAULT,
|
||||||
'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
|
'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
|
||||||
'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
|
'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
|
||||||
|
@@ -62,5 +62,7 @@ class ShibbolethRemoteUserBackend(RemoteUserBackend):
|
|||||||
notify_admins_on_register_complete(user.email)
|
notify_admins_on_register_complete(user.email)
|
||||||
else:
|
else:
|
||||||
user = None
|
user = None
|
||||||
|
else:
|
||||||
|
user = User.objects.get(email=username)
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
Reference in New Issue
Block a user