| @@ -44,6 +44,11 @@ type Attachment struct { | |||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||
| } | |||
| type AttachmentUsername struct { | |||
| Attachment `xorm:"extends"` | |||
| Name string | |||
| } | |||
| func (a *Attachment) AfterUpdate() { | |||
| if a.DatasetID > 0 { | |||
| datasetIsPublicCount, err := x.Where("dataset_id = ? AND is_private = ?", a.DatasetID, false).Count(new(Attachment)) | |||
| @@ -348,16 +353,20 @@ func getUnDecompressAttachments(e Engine) ([]*Attachment, error) { | |||
| return attachments, e.Where("decompress_state = ? and dataset_id != 0 and name like '%.zip'", DecompressStateInit).Find(&attachments) | |||
| } | |||
| func GetAllPublicAttachments() ([]*Attachment, error) { | |||
| func GetAllPublicAttachments() ([]*AttachmentUsername, error) { | |||
| return getAllPublicAttachments(x) | |||
| } | |||
| func getAllPublicAttachments(e Engine) ([]*Attachment, error) { | |||
| attachments := make([]*Attachment, 0, 10) | |||
| return attachments, e.Where("is_private = false and decompress_state = ?", DecompressStateDone).Find(&attachments) | |||
| func getAllPublicAttachments(e Engine) ([]*AttachmentUsername, error) { | |||
| attachments := make([]*AttachmentUsername, 0, 10) | |||
| if err := e.Table("attachment").Join("LEFT", "`user`", "attachment.uploader_id " + | |||
| "= `user`.id").Where("decompress_state= ? and is_private= ?", DecompressStateDone, false).Find(&attachments); err != nil { | |||
| return nil, err | |||
| } | |||
| return attachments, nil | |||
| } | |||
| func GetPrivateAttachments(username string) ([]*Attachment, error) { | |||
| func GetPrivateAttachments(username string) ([]*AttachmentUsername, error) { | |||
| user, err := getUserByName(x, username) | |||
| if err != nil { | |||
| log.Error("getUserByName(%s) failed:%v", username, err) | |||
| @@ -366,12 +375,16 @@ func GetPrivateAttachments(username string) ([]*Attachment, error) { | |||
| return getPrivateAttachments(x, user.ID) | |||
| } | |||
| func getPrivateAttachments(e Engine, userID int64) ([]*Attachment, error) { | |||
| attachments := make([]*Attachment, 0, 10) | |||
| return attachments, e.Where("uploader_id = ? and decompress_state = ?", userID, DecompressStateDone).Find(&attachments) | |||
| func getPrivateAttachments(e Engine, userID int64) ([]*AttachmentUsername, error) { | |||
| attachments := make([]*AttachmentUsername, 0, 10) | |||
| if err := e.Table("attachment").Join("LEFT", "`user`", "attachment.uploader_id " + | |||
| "= `user`.id").Where("decompress_state= ? and uploader_id= ?", DecompressStateDone, userID).Find(&attachments); err != nil { | |||
| return nil, err | |||
| } | |||
| return attachments, nil | |||
| } | |||
| func GetAllUserAttachments(userID int64) ([]*Attachment, error) { | |||
| func GetAllUserAttachments(userID int64) ([]*AttachmentUsername, error) { | |||
| attachsPub, err := getAllPublicAttachments(x) | |||
| if err != nil { | |||
| log.Error("getAllPublicAttachments failed:%v", err) | |||
| @@ -65,6 +65,8 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||
| } | |||
| if result.JobStatus.State != string(models.JobWaiting) { | |||
| //todo | |||
| go models.SetCloudbrainStatusByJobID(result.Config.JobID, models.CloudbrainStatus(result.JobStatus.State)) | |||
| } | |||
| @@ -635,7 +635,7 @@ func QueryAllPublicDataset(ctx *context.Context){ | |||
| return | |||
| } | |||
| queryDatasets(ctx, "admin", attachs) | |||
| queryDatasets(ctx, attachs) | |||
| } | |||
| func QueryPrivateDataset(ctx *context.Context){ | |||
| @@ -650,10 +650,14 @@ func QueryPrivateDataset(ctx *context.Context){ | |||
| return | |||
| } | |||
| queryDatasets(ctx, username, attachs) | |||
| for _, attach := range attachs { | |||
| attach.Name = username | |||
| } | |||
| queryDatasets(ctx, attachs) | |||
| } | |||
| func queryDatasets(ctx *context.Context, username string, attachs []*models.Attachment) { | |||
| func queryDatasets(ctx *context.Context, attachs []*models.AttachmentUsername) { | |||
| var datasets []CloudBrainDataset | |||
| for _, attch := range attachs { | |||
| has,err := storage.Attachments.HasObject(models.AttachmentRelativePath(attch.UUID)) | |||
| @@ -661,15 +665,15 @@ func queryDatasets(ctx *context.Context, username string, attachs []*models.Atta | |||
| continue | |||
| } | |||
| datasets = append(datasets, CloudBrainDataset{string(attch.ID), | |||
| attch.Name, | |||
| datasets = append(datasets, CloudBrainDataset{strconv.FormatInt(attch.ID, 10), | |||
| attch.Attachment.Name, | |||
| setting.Attachment.Minio.RealPath + | |||
| setting.Attachment.Minio.Bucket + "/" + | |||
| setting.Attachment.Minio.BasePath + | |||
| models.AttachmentRelativePath(attch.UUID) + | |||
| attch.UUID, | |||
| username, | |||
| attch.CreatedUnix.Format("2006-01-02 03:04:05")}) | |||
| attch.Name, | |||
| attch.CreatedUnix.Format("2006-01-02 03:04:05 PM")}) | |||
| } | |||
| data,err := json.Marshal(datasets) | |||
| @@ -203,7 +203,7 @@ func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrain | |||
| ImageTag: form.Tag, | |||
| }) | |||
| if err != nil { | |||
| log.Error("CommitImage failed:", err.Error()) | |||
| log.Error("CommitImage(%s) failed:", task.JobName, err.Error()) | |||
| ctx.ServerError("CommitImage failed", err) | |||
| return | |||
| } | |||
| @@ -61,51 +61,50 @@ | |||
| </a> | |||
| </span> | |||
| </div> | |||
| <div class="two wide column"> | |||
| <span class="ui text center clipboard"> | |||
| <form id="commitImageForm" action="{{if not .CanDebug}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/commit_image{{end}}" method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a class="fitted" onclick="document.getElementById('commitImageForm').submit();" style="{{if not .CanDebug}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">镜像提交</a> | |||
| </form> | |||
| </span> | |||
| </div> | |||
| <div class="one wide column"> | |||
| <span class="ui text center clipboard"> | |||
| <form id="stopForm" action="{{if ne .Status "RUNNING"}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/stop{{end}}" method="post"> | |||
| <form id="stopForm-{{.JobID}}" action="{{if ne .Status "RUNNING"}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/stop{{end}}" method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a class="fitted" onclick="document.getElementById('stopForm').submit();" style="{{if ne .Status "RUNNING"}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">停止</a> | |||
| <a class="fitted" onclick="document.getElementById('stopForm-{{.JobID}}').submit();" style="{{if ne .Status "RUNNING"}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">停止</a> | |||
| </form> | |||
| </span> | |||
| </div> | |||
| <!-- 打开弹窗按钮 --> | |||
| <button id="imageBtn">提交镜像</button> | |||
| <!-- 弹窗 --> | |||
| <div id="imageModal" class="modal"> | |||
| <!-- 弹窗内容 --> | |||
| <div class="modal-content"> | |||
| <span class="close">×</span> | |||
| <form id="commitImageForm" action="{{$.Link}}/{{.JobID}}/commit_image" method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <div class="inline required field"> | |||
| <label>镜像标签:</label> | |||
| <input name="tag" id="image_tag" tabindex="3" autofocus required maxlength="255"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>镜像描述:</label> | |||
| <textarea name="description" rows="10"></textarea> | |||
| </div> | |||
| <div class="inline field"> | |||
| <label></label> | |||
| <button class="ui green button"> | |||
| {{$.i18n.Tr "repo.cloudbrain.commit_image"}} | |||
| </button> | |||
| <a class="ui button" href="/">{{$.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| <!-- 打开弹窗按钮 --> | |||
| <a class="imageBtn" style="{{if not .CanDebug}}color:#CCCCCC;cursor:pointer;pointer-events:none;{{end}}; font-size:16px; font-weight:bold" value="{{.CanDebug}}">提交镜像</a> | |||
| <!-- 弹窗 --> | |||
| <div id="imageModal" class="modal"> | |||
| <!-- 弹窗内容 --> | |||
| <div class="modal-content"> | |||
| <span class="close">×</span> | |||
| <form id="commitImageForm" action="{{$.Link}}/{{.JobID}}/commit_image" method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <p>提交任务镜像</p> | |||
| <div class="ui divider"></div> | |||
| <div class="inline required field dis"> | |||
| <label>镜像标签:</label> | |||
| <input name="tag" id="image_tag" tabindex="3" autofocus required maxlength="255" style="width:300px"> | |||
| </div> | |||
| <div class="inline required field" style="position:relative;height:200px;"> | |||
| <div style="height:20px;width:75px;"> | |||
| <label>镜像描述:</label> | |||
| </div> | |||
| <div style="position:absolute;left:75px;top:0"> | |||
| <textarea name="description" rows="10" style="width:300px"></textarea> | |||
| </div> | |||
| </div> | |||
| <div class="ui divider"></div> | |||
| <div class="inline field"> | |||
| <label></label> | |||
| <button class="ui green button"> | |||
| {{$.i18n.Tr "repo.cloudbrain.commit_image"}} | |||
| </button> | |||
| <!--<a class="ui button" href="/">{{$.i18n.Tr "repo.cloudbrain.cancel"}}</a>--> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -142,21 +141,26 @@ $( document ).ready(function() { | |||
| var modal = document.getElementById('imageModal'); | |||
| // 打开弹窗的按钮对象 | |||
| var btn = document.getElementById("imageBtn"); | |||
| var btns = document.getElementsByClassName("imageBtn"); | |||
| // 获取 <span> 元素,用于关闭弹窗 | |||
| var span = document.querySelector('.close'); | |||
| var spans = document.getElementsByClassName('close'); | |||
| // 点击按钮打开弹窗 | |||
| btn.onclick = function() { | |||
| modal.style.display = "block"; | |||
| for(i=0;i<btns.length;i++){ | |||
| btns[i].onclick = function() { | |||
| modal.style.display = "block"; | |||
| } | |||
| } | |||
| // 点击 <span> (x), 关闭弹窗 | |||
| span.onclick = function() { | |||
| modal.style.display = "none"; | |||
| } | |||
| for(i=0;i<spans.length;i++){ | |||
| spans[i].onclick = function() { | |||
| modal.style.display = "none"; | |||
| } | |||
| } | |||
| // 在用户点击其他地方时,关闭弹窗 | |||
| window.onclick = function(event) { | |||
| if (event.target == modal) { | |||
| @@ -188,7 +192,7 @@ window.onclick = function(event) { | |||
| margin: 15% auto; | |||
| padding: 20px; | |||
| border: 1px solid #888; | |||
| width: 30%; | |||
| width: 25%; | |||
| } | |||
| /* 关闭按钮 */ | |||
| @@ -205,4 +209,10 @@ window.onclick = function(event) { | |||
| text-decoration: none; | |||
| cursor: pointer; | |||
| } | |||
| .dis{ | |||
| margin-bottom:20px; | |||
| } | |||
| </style> | |||
| @@ -28,7 +28,7 @@ | |||
| <label>数据集</label> | |||
| <select id="cloudbrain_dataset" placeholder="选择数据集" style='width:385px' name="attachment"> | |||
| {{range .attachments}} | |||
| <option name="attachment" value="{{.UUID}}">{{.Name}}</option> | |||
| <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||