| @@ -2433,6 +2433,7 @@ md5_computing = MD5 computing | |||||
| loading_file = Loading | loading_file = Loading | ||||
| uploading = Uploading | uploading = Uploading | ||||
| upload_complete = Uploading complete | upload_complete = Uploading complete | ||||
| enable_minio_support = Enable minio support to use the dataset service | |||||
| [notification] | [notification] | ||||
| notifications = Notifications | notifications = Notifications | ||||
| @@ -2434,6 +2434,7 @@ md5_computing=计算MD5 | |||||
| loading_file=加载文件 | loading_file=加载文件 | ||||
| uploading=正在上传 | uploading=正在上传 | ||||
| upload_complete=上传完成 | upload_complete=上传完成 | ||||
| enable_minio_support=启用minio支持以使用数据集服务 | |||||
| [notification] | [notification] | ||||
| notifications=通知 | notifications=通知 | ||||
| @@ -1,18 +1,15 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "net/url" | |||||
| "sort" | "sort" | ||||
| "code.gitea.io/gitea/modules/storage" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| gouuid "github.com/satori/go.uuid" | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| @@ -82,18 +79,8 @@ func DatasetIndex(ctx *context.Context) { | |||||
| ctx.Data["dataset"] = dataset | ctx.Data["dataset"] = dataset | ||||
| ctx.Data["Attachments"] = attachments | ctx.Data["Attachments"] = attachments | ||||
| ctx.Data["IsOwner"] = true | ctx.Data["IsOwner"] = true | ||||
| uuid := gouuid.NewV4().String() | |||||
| tmpUrl, err := storage.Attachments.PresignedPutURL(models.AttachmentRelativePath(uuid)) | |||||
| if err != nil { | |||||
| ctx.ServerError("PresignedPutURL", err) | |||||
| } | |||||
| preUrl, err := url.QueryUnescape(tmpUrl) | |||||
| if err != nil { | |||||
| ctx.ServerError("QueryUnescape", err) | |||||
| } | |||||
| ctx.Data["StoreType"] = setting.Attachment.StoreType | |||||
| ctx.Data["uuid"] = uuid | |||||
| ctx.Data["url"] = preUrl | |||||
| renderAttachmentSettings(ctx) | renderAttachmentSettings(ctx) | ||||
| ctx.HTML(200, tplIndex) | ctx.HTML(200, tplIndex) | ||||
| @@ -2,7 +2,8 @@ | |||||
| <div class="field required dataset-files"> | <div class="field required dataset-files"> | ||||
| <label>{{.i18n.Tr "dataset.file"}}</label> | <label>{{.i18n.Tr "dataset.file"}}</label> | ||||
| <div class="files"></div> | <div class="files"></div> | ||||
| <div class="ui dropzone" id="dataset" data-upload-url="{{.url}}" data-uuid="{{.uuid}}" data-add-url="{{AppSubUrl}}/attachments/add" data-accepts="{{.AttachmentAllowedTypes}}" data-remove-url="{{AppSubUrl}}/attachments/delete" data-csrf="{{.CsrfToken}}" dataset-id={{.dataset.ID}} data-max-file="100" data-dataset-id="{{.dataset.ID}}" data-max-size="{{.AttachmentMaxSize}}" 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 class="ui dropzone" id="dataset" data-upload-url="{{AppSubUrl}}/attachments" data-accepts="{{.AttachmentAllowedTypes}}" data-remove-url="{{AppSubUrl}}/attachments/delete" data-csrf="{{.CsrfToken}}" dataset-id={{.dataset.ID}} data-max-file="100" data-dataset-id="{{.dataset.ID}}" data-max-size="{{.AttachmentMaxSize}}" 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> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -66,6 +66,7 @@ | |||||
| </div> | </div> | ||||
| <div class="dataset ui middle very relaxed page"> | <div class="dataset ui middle very relaxed page"> | ||||
| <div class="column"> | <div class="column"> | ||||
| {{if .Permission.CanWrite $.UnitTypeDatasets}} | |||||
| <div style='display:none;' | <div style='display:none;' | ||||
| id="minioUploader-params" | id="minioUploader-params" | ||||
| data-uuid="{{.uuid}}" | data-uuid="{{.uuid}}" | ||||
| @@ -91,7 +92,12 @@ | |||||
| data-uploading='{{.i18n.Tr "dropzone.uploading"}}' | data-uploading='{{.i18n.Tr "dropzone.uploading"}}' | ||||
| > | > | ||||
| </div> | </div> | ||||
| {{if eq .StoreType "minio"}} | |||||
| <div id="minioUploader"></div> | <div id="minioUploader"></div> | ||||
| {{else}} | |||||
| <div style="margin: 2em 0;"> {{.i18n.Tr "dropzone.enable_minio_support"}} </div> | |||||
| {{end}} | |||||
| {{end}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -345,4 +345,12 @@ export default { | |||||
| min-height: 5rem; | min-height: 5rem; | ||||
| border-radius: 4px; | border-radius: 4px; | ||||
| } | } | ||||
| .dataset .dataset-files #dataset .dz-preview.dz-file-preview, .dataset .dataset-files #dataset .dz-preview.dz-processing { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| } | |||||
| .dataset .dataset-files #dataset .dz-preview { | |||||
| border-bottom: 1px solid #dadce0; | |||||
| min-height: 0; | |||||
| } | |||||
| </style> | </style> | ||||
| @@ -2397,38 +2397,22 @@ $(document).ready(async () => { | |||||
| await createDropzone('#dataset', { | await createDropzone('#dataset', { | ||||
| url: $dataset.data('upload-url'), | url: $dataset.data('upload-url'), | ||||
| method: 'put', | |||||
| headers: {'X-Csrf-Token': csrf}, | headers: {'X-Csrf-Token': csrf}, | ||||
| maxFiles: $dataset.data('max-file'), | maxFiles: $dataset.data('max-file'), | ||||
| maxFilesize: $dataset.data('max-size'), | maxFilesize: $dataset.data('max-size'), | ||||
| acceptedFiles: ($dataset.data('accepts') === '*/*') ? null : $dataset.data('accepts'), | acceptedFiles: ($dataset.data('accepts') === '*/*') ? null : $dataset.data('accepts'), | ||||
| addRemoveLinks: true, | addRemoveLinks: true, | ||||
| timeout: 0, | |||||
| dictDefaultMessage: $dataset.data('default-message'), | dictDefaultMessage: $dataset.data('default-message'), | ||||
| dictInvalidFileType: $dataset.data('invalid-input-type'), | dictInvalidFileType: $dataset.data('invalid-input-type'), | ||||
| dictFileTooBig: $dataset.data('file-too-big'), | dictFileTooBig: $dataset.data('file-too-big'), | ||||
| dictRemoveFile: $dataset.data('remove-file'), | dictRemoveFile: $dataset.data('remove-file'), | ||||
| timeout: 18000000, | |||||
| previewTemplate, | previewTemplate, | ||||
| init() { | init() { | ||||
| this.on('sending', (file, xhr, _formData) => { | |||||
| const send = xhr.send; | |||||
| xhr.send = function () { | |||||
| send.call(xhr, file); | |||||
| }; | |||||
| }); | |||||
| this.on('success', (file, _data) => { | |||||
| const uuid = $dataset.data('uuid'); | |||||
| if ($dataset.data('add-url') && $dataset.data('csrf')) { | |||||
| $.post($dataset.data('add-url'), { | |||||
| uuid, | |||||
| file_name: file.name, | |||||
| size: file.size, | |||||
| dataset_id: $dataset.data('dataset-id'), | |||||
| _csrf: $dataset.data('csrf') | |||||
| }).done(() => { | |||||
| window.location.reload(); | |||||
| }); | |||||
| } | |||||
| this.on('success', (file, data) => { | |||||
| filenameDict[file.name] = data.uuid; | |||||
| const input = $(`<input id="${data.uuid}" name="files" type="hidden">`).val(data.uuid); | |||||
| $('.files').append(input); | |||||
| }); | }); | ||||
| this.on('removedfile', (file) => { | this.on('removedfile', (file) => { | ||||
| if (file.name in filenameDict) { | if (file.name in filenameDict) { | ||||