Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/1844 Reviewed-by: lewis <747342561@qq.com>pull/1853/head
@@ -40,6 +40,7 @@ var ( | |||
DisabledRepoUnits []string | |||
DefaultRepoUnits []string | |||
PrefixArchiveFiles bool | |||
RepoMaxSize int64 | |||
// Repository editor settings | |||
Editor struct { | |||
@@ -54,6 +55,7 @@ var ( | |||
AllowedTypes []string `delim:"|"` | |||
FileMaxSize int64 | |||
MaxFiles int | |||
TotalMaxSize int64 | |||
} `ini:"-"` | |||
// Repository local settings | |||
@@ -104,6 +106,7 @@ var ( | |||
DisabledRepoUnits: []string{}, | |||
DefaultRepoUnits: []string{}, | |||
PrefixArchiveFiles: true, | |||
RepoMaxSize: 1024, | |||
// Repository editor settings | |||
Editor: struct { | |||
@@ -121,12 +124,14 @@ var ( | |||
AllowedTypes []string `delim:"|"` | |||
FileMaxSize int64 | |||
MaxFiles int | |||
TotalMaxSize int64 | |||
}{ | |||
Enabled: true, | |||
TempPath: "data/tmp/uploads", | |||
AllowedTypes: []string{}, | |||
FileMaxSize: 3, | |||
MaxFiles: 5, | |||
FileMaxSize: 30, | |||
MaxFiles: 10, | |||
TotalMaxSize: 1024, | |||
}, | |||
// Repository local settings | |||
@@ -1260,6 +1260,10 @@ editor.cannot_commit_to_protected_branch = Cannot commit to protected branch '%s | |||
editor.no_commit_to_branch = Unable to commit directly to branch because: | |||
editor.user_no_push_to_branch = User cannot push to branch | |||
editor.require_signed_commit = Branch requires a signed commit | |||
editor.repo_too_large = Repository can not exceed %d MB | |||
editor.repo_file_invalid = Upload files are invalid | |||
editor.upload_file_too_much = Can not upload more than %d files at a time | |||
commits.desc = Browse source code change history. | |||
commits.commits = Commits | |||
@@ -2867,6 +2871,8 @@ uploading = Uploading | |||
upload_complete = Uploading complete | |||
failed = Upload Failed | |||
enable_minio_support = Enable minio support to use the dataset service | |||
max_file_tooltips= Upload a maximum of ? files at a time, each file does not exceed ? MB. | |||
max_size_tooltips= You can only upload a maximum of ? files at a time. The upload limit has been reached, please do not add more files. | |||
[notification] | |||
notifications = Notifications | |||
@@ -1267,6 +1267,9 @@ editor.cannot_commit_to_protected_branch=不可以提交到受保护的分支 '% | |||
editor.no_commit_to_branch=无法直接提交分支,因为: | |||
editor.user_no_push_to_branch=用户不能推送到分支 | |||
editor.require_signed_commit=分支需要签名提交 | |||
editor.repo_too_large = 代码仓总大小不能超过%dMB | |||
editor.repo_file_invalid = 提交的文件非法 | |||
editor.upload_file_too_much = 不能同时提交超过%d个文件 | |||
commits.desc=浏览代码修改历史 | |||
commits.commits=次代码提交 | |||
@@ -2873,6 +2876,8 @@ uploading=正在上传 | |||
upload_complete=上传完成 | |||
failed=上传失败 | |||
enable_minio_support=启用minio支持以使用数据集服务 | |||
max_file_tooltips=单次最多上传?个文件,每个文件不超过? MB。 | |||
max_size_tooltips=一次最多只能上传?个文件, 上传已达到上限,请勿再添加文件。 | |||
[notification] | |||
notifications=通知 | |||
@@ -5,6 +5,7 @@ | |||
package repo | |||
import ( | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
"encoding/json" | |||
"fmt" | |||
"io/ioutil" | |||
@@ -614,6 +615,19 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) { | |||
message += "\n\n" + form.CommitMessage | |||
} | |||
if err := repo_service.CheckPushSizeLimit4Web(ctx.Repo.Repository, form.Files); err != nil { | |||
if repo_service.IsRepoTooLargeErr(err) { | |||
ctx.RenderWithErr(ctx.Tr("repo.editor.repo_too_large", setting.Repository.RepoMaxSize), tplUploadFile, &form) | |||
} else if repo_service.IsUploadFileInvalidErr(err) { | |||
ctx.RenderWithErr(ctx.Tr("repo.editor.repo_file_invalid"), tplUploadFile, &form) | |||
} else if repo_service.IsUploadFileTooMuchErr(err) { | |||
ctx.RenderWithErr(ctx.Tr("repo.editor.upload_file_too_much", setting.Repository.Upload.MaxFiles), tplUploadFile, &form) | |||
} else { | |||
ctx.RenderWithErr(err.Error(), tplUploadFile, &form) | |||
} | |||
return | |||
} | |||
if err := repofiles.UploadRepoFiles(ctx.Repo.Repository, ctx.User, &repofiles.UploadRepoFileOptions{ | |||
LastCommitID: ctx.Repo.CommitID, | |||
OldBranch: oldBranchName, | |||
@@ -8,6 +8,7 @@ import ( | |||
"fmt" | |||
"io/ioutil" | |||
"net/http" | |||
"os" | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
@@ -172,3 +173,137 @@ func RecommendFromPromote(url string) ([]string, error) { | |||
} | |||
return result, nil | |||
} | |||
func CheckPushSizeLimit4Web(repo *models.Repository, fileIds []string) error { | |||
if err := CheckRepoNumOnceLimit(len(fileIds)); err != nil { | |||
return err | |||
} | |||
totalSize, err := CountUploadFileSizeByIds(fileIds) | |||
if err != nil { | |||
return UploadFileInvalidErr{} | |||
} | |||
if err := CheckRepoTotalSizeLimit(repo, totalSize); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func CheckPushSizeLimit4Http(repo *models.Repository, uploadFileSize int64) error { | |||
if err := CheckRepoOnceTotalSizeLimit(uploadFileSize); err != nil { | |||
return err | |||
} | |||
if err := CheckRepoTotalSizeLimit(repo, uploadFileSize); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func CheckRepoTotalSizeLimit(repo *models.Repository, uploadFileSize int64) error { | |||
if repo.Size+uploadFileSize > setting.Repository.RepoMaxSize*1024*1024 { | |||
return RepoTooLargeErr{} | |||
} | |||
return nil | |||
} | |||
func CheckRepoOnceTotalSizeLimit(uploadFileSize int64) error { | |||
if uploadFileSize > setting.Repository.Upload.TotalMaxSize*1024*1024 { | |||
return UploadFileTooLargeErr{} | |||
} | |||
return nil | |||
} | |||
func CheckRepoNumOnceLimit(uploadFileNum int) error { | |||
if uploadFileNum > setting.Repository.Upload.MaxFiles { | |||
return UploadFileTooMuchErr{} | |||
} | |||
return nil | |||
} | |||
func CountUploadFileSizeByIds(fileIds []string) (int64, error) { | |||
if len(fileIds) == 0 { | |||
return 0, nil | |||
} | |||
uploads, err := models.GetUploadsByUUIDs(fileIds) | |||
if err != nil { | |||
return 0, fmt.Errorf("CountUploadFileSizeByIds error [uuids: %v]: %v", fileIds, err) | |||
} | |||
var totalSize int64 | |||
for _, upload := range uploads { | |||
size, err := GetUploadFileSize(upload) | |||
if err != nil { | |||
return 0, err | |||
} | |||
totalSize += size | |||
} | |||
return totalSize, nil | |||
} | |||
func GetUploadFileSize(upload *models.Upload) (int64, error) { | |||
info, err := os.Lstat(upload.LocalPath()) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return info.Size(), nil | |||
} | |||
type RepoTooLargeErr struct { | |||
} | |||
func (RepoTooLargeErr) Error() string { | |||
return fmt.Sprintf("Repository can not exceed %d MB. Please remove some unnecessary files and try again", setting.Repository.RepoMaxSize) | |||
} | |||
func IsRepoTooLargeErr(err error) bool { | |||
_, ok := err.(RepoTooLargeErr) | |||
return ok | |||
} | |||
type UploadFileTooLargeErr struct { | |||
} | |||
func (UploadFileTooLargeErr) Error() string { | |||
return fmt.Sprintf("Upload files can not exceed %d MB at a time", setting.Repository.Upload.TotalMaxSize) | |||
} | |||
func IsUploadFileTooLargeErr(err error) bool { | |||
_, ok := err.(UploadFileTooLargeErr) | |||
return ok | |||
} | |||
type RepoFileTooLargeErr struct { | |||
} | |||
func (RepoFileTooLargeErr) Error() string { | |||
return "repository file is too large" | |||
} | |||
func IsRepoFileTooLargeErr(err error) bool { | |||
_, ok := err.(RepoFileTooLargeErr) | |||
return ok | |||
} | |||
type UploadFileTooMuchErr struct { | |||
} | |||
func (UploadFileTooMuchErr) Error() string { | |||
return "upload files are too lmuch" | |||
} | |||
func IsUploadFileTooMuchErr(err error) bool { | |||
_, ok := err.(UploadFileTooMuchErr) | |||
return ok | |||
} | |||
type UploadFileInvalidErr struct { | |||
} | |||
func (UploadFileInvalidErr) Error() string { | |||
return "upload files are invalid" | |||
} | |||
func IsUploadFileInvalidErr(err error) bool { | |||
_, ok := err.(UploadFileInvalidErr) | |||
return ok | |||
} |
@@ -27,10 +27,10 @@ | |||
</div> | |||
<div class="field"> | |||
<div class="files"></div> | |||
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-file" data-remove-url="{{.RepoLink}}/upload-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}"></div> | |||
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-file" data-remove-url="{{.RepoLink}}/upload-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}" data-max-file-tooltips="{{.i18n.Tr "dropzone.max_file_tooltips"}}" data-max-size-tooltips="{{.i18n.Tr "dropzone.max_size_tooltips"}}"><div class="maxfilesize ui red message" style="display: none;margin: 2.5rem;"></div></div> | |||
</div> | |||
{{template "repo/editor/commit_form" .}} | |||
</form> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
{{template "base/footer" .}} |
@@ -2751,9 +2751,23 @@ $(document).ready(async () => { | |||
$('td[data-href]').click(function () { | |||
window.location = $(this).data('href'); | |||
}); | |||
// 在String原型对象上添加format方法 | |||
String.prototype.format = function(){ | |||
let str = this; | |||
if(arguments.length == 0){ | |||
return str; | |||
}else{ | |||
Object.keys(arguments).forEach((item,index)=>{ | |||
str = str.replace(/\?/,arguments[item]) | |||
}) | |||
return str | |||
} | |||
} | |||
// Dropzone | |||
const $dropzone = $('#dropzone'); | |||
let maxFileTooltips=$dropzone.data('max-file-tooltips').format($dropzone.data('max-file'),$dropzone.data('max-size')) | |||
let maxSizeTooltips=$dropzone.data('max-size-tooltips').format($dropzone.data('max-file')) | |||
if ($dropzone.length > 0) { | |||
const filenameDict = {}; | |||
@@ -2788,6 +2802,22 @@ $(document).ready(async () => { | |||
}); | |||
} | |||
}); | |||
this.on('addedfile',(file)=>{ | |||
if(file.size/(1000*1000)>$dropzone.data('max-size')){ | |||
this.removeFile(file) | |||
$('.maxfilesize.ui.red.message').text(maxFileTooltips) | |||
$('.maxfilesize.ui.red.message').css('display','block') | |||
}else{ | |||
$('.maxfilesize.ui.red.message').css('display','none') | |||
} | |||
}); | |||
this.on('maxfilesexceeded',(file)=>{ | |||
this.removeFile(file) | |||
$('.maxfilesize.ui.red.message').text(maxSizeTooltips) | |||
$('.maxfilesize.ui.red.message').css('display','block') | |||
}) | |||
} | |||
}); | |||
} | |||