| @@ -1279,7 +1279,7 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, opts ...Cr | |||||
| } | } | ||||
| if setting.Service.AutoWatchNewRepos { | if setting.Service.AutoWatchNewRepos { | ||||
| if err = watchRepo(ctx.e, doer.ID, repo.ID, true); err != nil { | |||||
| if err = watchRepo(ctx.e, doer.ID, repo.ID, true, ReceiveAllNotification); err != nil { | |||||
| return fmt.Errorf("watchRepo: %v", err) | return fmt.Errorf("watchRepo: %v", err) | ||||
| } | } | ||||
| } | } | ||||
| @@ -24,6 +24,14 @@ const ( | |||||
| RepoWatchModeAuto // 3 | RepoWatchModeAuto // 3 | ||||
| ) | ) | ||||
| // NotifyType specifies what kind of watch the user has on a repository | |||||
| type NotifyType int8 | |||||
| const ( | |||||
| RejectAllNotification NotifyType = 0 | |||||
| ReceiveAllNotification NotifyType = 9 | |||||
| ) | |||||
| var ActionChan = make(chan *Action, 200) | var ActionChan = make(chan *Action, 200) | ||||
| var ActionChan4Task = make(chan Action, 200) | var ActionChan4Task = make(chan Action, 200) | ||||
| @@ -34,6 +42,7 @@ type Watch struct { | |||||
| RepoID int64 `xorm:"UNIQUE(watch)"` | RepoID int64 `xorm:"UNIQUE(watch)"` | ||||
| Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` | Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` | ||||
| CreatedUnix int64 `xorm:"created"` | CreatedUnix int64 `xorm:"created"` | ||||
| NotifyType NotifyType `xorm:"SMALLINT NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| // getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found | // getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found | ||||
| @@ -60,8 +69,20 @@ func IsWatching(userID, repoID int64) bool { | |||||
| return err == nil && isWatchMode(watch.Mode) | return err == nil && isWatchMode(watch.Mode) | ||||
| } | } | ||||
| // GetWatchNotifyType | |||||
| func GetWatchNotifyType(userID, repoID int64) NotifyType { | |||||
| watch, err := getWatch(x, userID, repoID) | |||||
| if err != nil { | |||||
| return RejectAllNotification | |||||
| } | |||||
| return watch.NotifyType | |||||
| } | |||||
| func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { | func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { | ||||
| if watch.Mode == mode { | if watch.Mode == mode { | ||||
| if _, err := e.ID(watch.ID).Cols("notify_type").Update(watch); err != nil { | |||||
| return err | |||||
| } | |||||
| return nil | return nil | ||||
| } | } | ||||
| if mode == RepoWatchModeAuto && (watch.Mode == RepoWatchModeDont || isWatchMode(watch.Mode)) { | if mode == RepoWatchModeAuto && (watch.Mode == RepoWatchModeDont || isWatchMode(watch.Mode)) { | ||||
| @@ -109,7 +130,7 @@ func WatchRepoMode(userID, repoID int64, mode RepoWatchMode) (err error) { | |||||
| return watchRepoMode(x, watch, mode) | return watchRepoMode(x, watch, mode) | ||||
| } | } | ||||
| func watchRepo(e Engine, userID, repoID int64, doWatch bool) (err error) { | |||||
| func watchRepo(e Engine, userID, repoID int64, doWatch bool, notifyTypes ...NotifyType) (err error) { | |||||
| var watch Watch | var watch Watch | ||||
| if watch, err = getWatch(e, userID, repoID); err != nil { | if watch, err = getWatch(e, userID, repoID); err != nil { | ||||
| return err | return err | ||||
| @@ -119,14 +140,19 @@ func watchRepo(e Engine, userID, repoID int64, doWatch bool) (err error) { | |||||
| } else if !doWatch { | } else if !doWatch { | ||||
| err = watchRepoMode(e, watch, RepoWatchModeNone) | err = watchRepoMode(e, watch, RepoWatchModeNone) | ||||
| } else { | } else { | ||||
| notifyType := RejectAllNotification | |||||
| if len(notifyTypes) > 0 { | |||||
| notifyType = notifyTypes[0] | |||||
| } | |||||
| watch.NotifyType = notifyType | |||||
| err = watchRepoMode(e, watch, RepoWatchModeNormal) | err = watchRepoMode(e, watch, RepoWatchModeNormal) | ||||
| } | } | ||||
| return err | return err | ||||
| } | } | ||||
| // WatchRepo watch or unwatch repository. | // WatchRepo watch or unwatch repository. | ||||
| func WatchRepo(userID, repoID int64, watch bool) (err error) { | |||||
| return watchRepo(x, userID, repoID, watch) | |||||
| func WatchRepo(userID, repoID int64, watch bool, notifyType ...NotifyType) (err error) { | |||||
| return watchRepo(x, userID, repoID, watch, notifyType...) | |||||
| } | } | ||||
| func getWatchers(e Engine, repoID int64) ([]*Watch, error) { | func getWatchers(e Engine, repoID int64) ([]*Watch, error) { | ||||
| @@ -156,6 +182,7 @@ func getRepoWatchersIDs(e Engine, repoID int64) ([]int64, error) { | |||||
| return ids, e.Table("watch"). | return ids, e.Table("watch"). | ||||
| Where("watch.repo_id=?", repoID). | Where("watch.repo_id=?", repoID). | ||||
| And("watch.mode<>?", RepoWatchModeDont). | And("watch.mode<>?", RepoWatchModeDont). | ||||
| And("watch.notify_type > ?", RejectAllNotification). | |||||
| Select("user_id"). | Select("user_id"). | ||||
| Find(&ids) | Find(&ids) | ||||
| } | } | ||||
| @@ -216,6 +216,27 @@ func (email *EmailAddress) updateActivation(e Engine, activate bool) error { | |||||
| return updateUserCols(e, user, "rands") | return updateUserCols(e, user, "rands") | ||||
| } | } | ||||
| // UpdateEmailAddress update an email address of given user. | |||||
| func (email *EmailAddress) UpdateEmailAddress(newEmailAddress string) error { | |||||
| return email.updateEmailAddress(x, newEmailAddress) | |||||
| } | |||||
| func (email *EmailAddress) updateEmailAddress(e Engine, newEmailAddress string) error { | |||||
| user, err := getUserByID(e, email.UID) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| if user.Rands, err = GetUserSalt(); err != nil { | |||||
| return err | |||||
| } | |||||
| user.Email = newEmailAddress | |||||
| user.AvatarEmail = newEmailAddress | |||||
| email.Email = newEmailAddress | |||||
| if _, err := e.ID(email.ID).Cols("email").Update(email); err != nil { | |||||
| return err | |||||
| } | |||||
| return updateUserCols(e, user, "email", "avatar_email") | |||||
| } | |||||
| // DeleteEmailAddress deletes an email address of given user. | // DeleteEmailAddress deletes an email address of given user. | ||||
| func DeleteEmailAddress(email *EmailAddress) (err error) { | func DeleteEmailAddress(email *EmailAddress) (err error) { | ||||
| var deleted int64 | var deleted int64 | ||||
| @@ -88,6 +88,10 @@ type RegisterForm struct { | |||||
| Agree bool | Agree bool | ||||
| } | } | ||||
| type UpdateEmailForm struct { | |||||
| NewEmail string `binding:"Required;MaxSize(254)"` | |||||
| } | |||||
| // Validate valideates the fields | // Validate valideates the fields | ||||
| func (f *RegisterForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *RegisterForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| return validate(errs, ctx.Data, f, ctx.Locale) | return validate(errs, ctx.Data, f, ctx.Locale) | ||||
| @@ -474,6 +474,7 @@ func RepoAssignment() macaron.Handler { | |||||
| if ctx.IsSigned { | if ctx.IsSigned { | ||||
| ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) | ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) | ||||
| ctx.Data["WatchNotifyType"] = models.GetWatchNotifyType(ctx.User.ID, repo.ID) | |||||
| ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | ||||
| ctx.Data["IsStaringDataset"] = models.IsDatasetStaringByRepoId(ctx.User.ID, repo.ID) | ctx.Data["IsStaringDataset"] = models.IsDatasetStaringByRepoId(ctx.User.ID, repo.ID) | ||||
| @@ -389,9 +389,12 @@ authorize_application_created_by = This application was created by %s. | |||||
| authorize_application_description = If you grant the access, it will be able to access and write to all your account information, including private repos and organisations. | authorize_application_description = If you grant the access, it will be able to access and write to all your account information, including private repos and organisations. | ||||
| authorize_title = Authorize "%s" to access your account? | authorize_title = Authorize "%s" to access your account? | ||||
| authorization_failed = Authorization failed | authorization_failed = Authorization failed | ||||
| authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you've tried to authorize. | |||||
| authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you have tried to authorize. | |||||
| disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator. | disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator. | ||||
| sspi_auth_failed = SSPI authentication failed | sspi_auth_failed = SSPI authentication failed | ||||
| change_email = Change email | |||||
| change_email_address = Change email address | |||||
| new_email_address = New email address | |||||
| [phone] | [phone] | ||||
| format_err=The format of phone number is wrong. | format_err=The format of phone number is wrong. | ||||
| query_err=Fail to query phone number, please try again later. | query_err=Fail to query phone number, please try again later. | ||||
| @@ -1400,6 +1403,11 @@ star = Star | |||||
| fork = Fork | fork = Fork | ||||
| download_archive = Download Repository | download_archive = Download Repository | ||||
| star_fail=Failed to %s the dataset. | star_fail=Failed to %s the dataset. | ||||
| watched=Watched | |||||
| notWatched=Not watched | |||||
| un_watch=Unwatch | |||||
| watch_all=Watch all | |||||
| watch_no_notify=Watch but not notify | |||||
| no_desc = No Description | no_desc = No Description | ||||
| no_label = No labels | no_label = No labels | ||||
| @@ -396,6 +396,9 @@ authorization_failed=授权失败 | |||||
| authorization_failed_desc=授权失败,这是一个无效的请求。请联系尝试授权应用的管理员。 | authorization_failed_desc=授权失败,这是一个无效的请求。请联系尝试授权应用的管理员。 | ||||
| disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator. | disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator. | ||||
| sspi_auth_failed=SSPI 认证失败 | sspi_auth_failed=SSPI 认证失败 | ||||
| change_email=修改邮箱 | |||||
| change_email_address=修改邮箱地址 | |||||
| new_email_address=新邮箱地址 | |||||
| [phone] | [phone] | ||||
| format_err=手机号格式错误。 | format_err=手机号格式错误。 | ||||
| query_err=查询手机号失败,请稍后再试。 | query_err=查询手机号失败,请稍后再试。 | ||||
| @@ -1416,6 +1419,11 @@ star=点赞 | |||||
| fork=派生 | fork=派生 | ||||
| download_archive=下载此项目 | download_archive=下载此项目 | ||||
| star_fail=%s失败。 | star_fail=%s失败。 | ||||
| watched=已关注 | |||||
| notWatched=未关注 | |||||
| un_watch=不关注 | |||||
| watch_all=关注所有动态 | |||||
| watch_no_notify=关注但不提醒动态 | |||||
| no_desc=暂无描述 | no_desc=暂无描述 | ||||
| @@ -123,8 +123,9 @@ func GetOverviewDuration(ctx *context.Context) { | |||||
| recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix | recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix | ||||
| now := time.Now() | now := time.Now() | ||||
| endTime := now | endTime := now | ||||
| // worker_server_num := 1 | |||||
| // cardNum := 1 | |||||
| var workServerNumber int64 | |||||
| var cardNum int64 | |||||
| durationAllSum := int64(0) | durationAllSum := int64(0) | ||||
| cardDuSum := int64(0) | cardDuSum := int64(0) | ||||
| @@ -138,52 +139,60 @@ func GetOverviewDuration(ctx *context.Context) { | |||||
| c2NetDuration := int64(0) | c2NetDuration := int64(0) | ||||
| cDCenterDuration := int64(0) | cDCenterDuration := int64(0) | ||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| Type: models.TypeCloudBrainAll, | |||||
| BeginTimeUnix: int64(recordBeginTime), | |||||
| EndTimeUnix: endTime.Unix(), | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.ServerError("Get cloudbrains failed:", err) | |||||
| return | |||||
| } | |||||
| models.LoadSpecs4CloudbrainInfo(cloudbrains) | |||||
| for _, cloudbrain := range cloudbrains { | |||||
| cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain) | |||||
| CardDurationString := repo.GetCloudbrainCardDuration(cloudbrain.Cloudbrain) | |||||
| CardDuration := models.ConvertStrToDuration(CardDurationString) | |||||
| // if cloudbrain.Cloudbrain.WorkServerNumber >= 1 { | |||||
| // worker_server_num = cloudbrain.Cloudbrain.WorkServerNumber | |||||
| // } else { | |||||
| // worker_server_num = 1 | |||||
| // } | |||||
| // if cloudbrain.Cloudbrain.Spec == nil { | |||||
| // cardNum = 1 | |||||
| // } else { | |||||
| // cardNum = cloudbrain.Cloudbrain.Spec.AccCardsNum | |||||
| // } | |||||
| // duration := cloudbrain.Duration | |||||
| // duration := cloudbrain.Duration | |||||
| duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration) | |||||
| // CardDuration := cloudbrain.Duration * int64(worker_server_num) * int64(cardNum) | |||||
| if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne { | |||||
| cloudBrainOneDuration += duration | |||||
| cloudBrainOneCardDuSum += CardDuration | |||||
| } else if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo { | |||||
| cloudBrainTwoDuration += duration | |||||
| cloudBrainTwoCardDuSum += CardDuration | |||||
| } else if cloudbrain.Cloudbrain.Type == models.TypeC2Net { | |||||
| c2NetDuration += duration | |||||
| c2NetCardDuSum += CardDuration | |||||
| } else if cloudbrain.Cloudbrain.Type == models.TypeCDCenter { | |||||
| cDCenterDuration += duration | |||||
| cDNetCardDuSum += CardDuration | |||||
| page := 1 | |||||
| pagesize := 10000 | |||||
| count := pagesize | |||||
| // Each time a maximum of 10000 pieces of data are detected to the memory, batch processing | |||||
| for count == pagesize && count != 0 { | |||||
| cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: pagesize, | |||||
| }, | |||||
| Type: models.TypeCloudBrainAll, | |||||
| BeginTimeUnix: int64(recordBeginTime), | |||||
| EndTimeUnix: endTime.Unix(), | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.ServerError("Get cloudbrains failed:", err) | |||||
| return | |||||
| } | } | ||||
| models.LoadSpecs4CloudbrainInfo(cloudbrains) | |||||
| for _, cloudbrain := range cloudbrains { | |||||
| cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain) | |||||
| if cloudbrain.Cloudbrain.Spec != nil { | |||||
| cardNum = int64(cloudbrain.Cloudbrain.Spec.AccCardsNum) | |||||
| } else { | |||||
| cardNum = 1 | |||||
| } | |||||
| if cloudbrain.Cloudbrain.WorkServerNumber >= 1 { | |||||
| workServerNumber = int64(cloudbrain.Cloudbrain.WorkServerNumber) | |||||
| } else { | |||||
| workServerNumber = 1 | |||||
| } | |||||
| duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration) | |||||
| CardDuration := workServerNumber * int64(cardNum) * duration | |||||
| if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne { | |||||
| cloudBrainOneDuration += duration | |||||
| cloudBrainOneCardDuSum += CardDuration | |||||
| } else if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo { | |||||
| cloudBrainTwoDuration += duration | |||||
| cloudBrainTwoCardDuSum += CardDuration | |||||
| } else if cloudbrain.Cloudbrain.Type == models.TypeC2Net { | |||||
| c2NetDuration += duration | |||||
| c2NetCardDuSum += CardDuration | |||||
| } else if cloudbrain.Cloudbrain.Type == models.TypeCDCenter { | |||||
| cDCenterDuration += duration | |||||
| cDNetCardDuSum += CardDuration | |||||
| } | |||||
| durationAllSum += duration | |||||
| cardDuSum += CardDuration | |||||
| durationAllSum += duration | |||||
| cardDuSum += CardDuration | |||||
| } | |||||
| count = len(cloudbrains) | |||||
| page += 1 | |||||
| } | } | ||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "cloudBrainOneCardDuSum": cloudBrainOneCardDuSum, | "cloudBrainOneCardDuSum": cloudBrainOneCardDuSum, | ||||
| @@ -246,13 +246,20 @@ func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, be | |||||
| func CloudbrainUpdateHistoryData(ctx *context.Context) { | func CloudbrainUpdateHistoryData(ctx *context.Context) { | ||||
| beginTimeStr := ctx.QueryTrim("beginTime") | beginTimeStr := ctx.QueryTrim("beginTime") | ||||
| endTimeStr := ctx.QueryTrim("endTime") | endTimeStr := ctx.QueryTrim("endTime") | ||||
| beginTime, _ := time.ParseInLocation("2006-01-02 15:04:05", beginTimeStr, time.Local) | |||||
| endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local) | |||||
| beginTimeUnix := timeutil.TimeStamp(beginTime.Unix()) | |||||
| endTimeUnix := timeutil.TimeStamp(endTime.Unix()) | |||||
| var count int64 | |||||
| var err error | |||||
| if beginTimeStr != "" && endTimeStr != "" { | |||||
| beginTime, _ := time.ParseInLocation("2006-01-02 15:04:05", beginTimeStr, time.Local) | |||||
| endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local) | |||||
| if time.Now().Before(endTime) { | |||||
| endTime = time.Now() | |||||
| } | |||||
| beginTimeUnix := timeutil.TimeStamp(beginTime.Unix()) | |||||
| endTimeUnix := timeutil.TimeStamp(endTime.Unix()) | |||||
| err := models.DeleteCloudbrainDurationStatistic(beginTimeUnix, endTimeUnix) | |||||
| count := UpdateDurationStatisticHistoryData(beginTime, endTime) | |||||
| err = models.DeleteCloudbrainDurationStatistic(beginTimeUnix, endTimeUnix) | |||||
| count = UpdateDurationStatisticHistoryData(beginTime.Add(+1*time.Hour), endTime) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "message": 0, | "message": 0, | ||||
| "count": count, | "count": count, | ||||
| @@ -414,7 +414,9 @@ func Action(ctx *context.Context) { | |||||
| var err error | var err error | ||||
| switch ctx.Params(":action") { | switch ctx.Params(":action") { | ||||
| case "watch": | case "watch": | ||||
| err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) | |||||
| err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true, models.ReceiveAllNotification) | |||||
| case "watch_but_reject": | |||||
| err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true, models.RejectAllNotification) | |||||
| case "unwatch": | case "unwatch": | ||||
| err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) | err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) | ||||
| case "star": | case "star": | ||||
| @@ -518,6 +518,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| // r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) | // r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) | ||||
| m.Any("/activate", user.Activate, reqSignIn) | m.Any("/activate", user.Activate, reqSignIn) | ||||
| m.Any("/activate_email", user.ActivateEmail) | m.Any("/activate_email", user.ActivateEmail) | ||||
| m.Post("/update_email", bindIgnErr(auth.UpdateEmailForm{}), user.UpdateEmailPost) | |||||
| m.Get("/avatar/:username/:size", user.Avatar) | m.Get("/avatar/:username/:size", user.Avatar) | ||||
| m.Get("/email2user", user.Email2User) | m.Get("/email2user", user.Email2User) | ||||
| m.Get("/recover_account", user.ResetPasswd) | m.Get("/recover_account", user.ResetPasswd) | ||||
| @@ -1413,6 +1413,34 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | |||||
| handleSignInFull(ctx, u, false, true) | handleSignInFull(ctx, u, false, true) | ||||
| } | } | ||||
| //update user emailAddress | |||||
| func UpdateEmailPost(ctx *context.Context, form auth.UpdateEmailForm) { | |||||
| newEmailAddress := ctx.Query("NewEmail") | |||||
| if newEmailAddress == "" { | |||||
| log.Error("please input the newEmail") | |||||
| return | |||||
| } | |||||
| if used, _ := models.IsEmailUsed(newEmailAddress); used { | |||||
| ctx.RenderWithErr(ctx.Tr("form.email_been_used"), TplActivate, &form) | |||||
| return | |||||
| } | |||||
| user := ctx.User | |||||
| email, err := models.GetEmailAddressByIDAndEmail(user.ID, user.Email) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetEmailAddressByIDAndEmail failed", err) | |||||
| return | |||||
| } | |||||
| err = email.UpdateEmailAddress(newEmailAddress) | |||||
| if err != nil { | |||||
| ctx.ServerError("UpdateEmailAddress failed", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["Email"] = newEmailAddress | |||||
| ctx.User.Email = newEmailAddress | |||||
| Activate(ctx) | |||||
| } | |||||
| // Activate render activate user page | // Activate render activate user page | ||||
| func Activate(ctx *context.Context) { | func Activate(ctx *context.Context) { | ||||
| code := ctx.Query("code") | code := ctx.Query("code") | ||||
| @@ -362,7 +362,7 @@ | |||||
| </tr> | </tr> | ||||
| <tr class="ti-no-ng-animate"> | <tr class="ti-no-ng-animate"> | ||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | <td class="ti-no-ng-animate ti-text-form-label text-width80"> | ||||
| 创建人 | |||||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| @@ -444,6 +444,7 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.BranchName}} | {{.BranchName}} | ||||
| <span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -337,6 +337,7 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-code"> | <div class="text-span text-span-w" id="{{.VersionName}}-code"> | ||||
| {{.BranchName}} | {{.BranchName}} | ||||
| <span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -410,6 +410,7 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.BranchName}} | {{.BranchName}} | ||||
| <span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -422,6 +422,7 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.BranchName}} | {{.BranchName}} | ||||
| <span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -51,6 +51,49 @@ | |||||
| </div> | </div> | ||||
| {{if not .IsBeingCreated}} | {{if not .IsBeingCreated}} | ||||
| <div class="repo-buttons"> | <div class="repo-buttons"> | ||||
| <div class="ui labeled button" tabindex="0"> | |||||
| <div class="ui compact basic button" onclick="$('.__watch_btn__').dropdown('show')"> | |||||
| <i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.watched"}}{{else}}{{$.i18n.Tr "repo.notWatched"}}{{end}} | |||||
| <i class="dropdown icon" style="margin:0 -8px 0 4px"></i> | |||||
| <div class="ui dropdown floating __watch_btn__" onclick="event.stopPropagation();"> | |||||
| <div class="text" style="display:none;"></div> | |||||
| {{$WatchNotifyType := or $.WatchNotifyType 0}} | |||||
| <div class="menu" style="margin-left:-64px;"> | |||||
| <div class="item {{if not $.IsWatchingRepo}}active selected{{end}}"> | |||||
| <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/unwatch?redirect_to={{$.Link}}"> | |||||
| {{$.CsrfTokenHtml}} | |||||
| <button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||||
| <i class="check icon" style="{{if $.IsWatchingRepo}}opacity:0{{end}}"></i> | |||||
| {{$.i18n.Tr "repo.un_watch"}} | |||||
| </button> | |||||
| </form> | |||||
| </div> | |||||
| <div class="item {{if and $.IsWatchingRepo (eq $WatchNotifyType 9)}}active selected{{end}}"> | |||||
| <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/watch?redirect_to={{$.Link}}"> | |||||
| {{$.CsrfTokenHtml}} | |||||
| <button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||||
| <i class="check icon" style="{{if not (and $.IsWatchingRepo (eq $WatchNotifyType 9))}}opacity:0{{end}}"></i> | |||||
| {{$.i18n.Tr "repo.watch_all"}} | |||||
| </button> | |||||
| </form> | |||||
| </div> | |||||
| <div class="item {{if and $.IsWatchingRepo (eq $WatchNotifyType 0)}}active selected{{end}}"> | |||||
| <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/watch_but_reject?redirect_to={{$.Link}}"> | |||||
| {{$.CsrfTokenHtml}} | |||||
| <button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||||
| <i class="check icon" style="{{if not (and $.IsWatchingRepo (eq $WatchNotifyType 0))}}opacity:0{{end}}"></i> | |||||
| {{$.i18n.Tr "repo.watch_no_notify"}} | |||||
| </button> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <a class="ui basic label" href="{{.Link}}/watchers"> | |||||
| {{.NumWatches}} | |||||
| </a> | |||||
| </div> | |||||
| <!-- | |||||
| <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}"> | <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| <div class="ui labeled button" tabindex="0"> | <div class="ui labeled button" tabindex="0"> | ||||
| @@ -61,7 +104,7 @@ | |||||
| {{.NumWatches}} | {{.NumWatches}} | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| </form> | |||||
| </form> --> | |||||
| <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}"> | <form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| <div class="ui labeled button" tabindex="0"> | <div class="ui labeled button" tabindex="0"> | ||||
| @@ -388,6 +388,7 @@ td, th { | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.BranchName}} | {{.BranchName}} | ||||
| <span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -442,6 +442,7 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.BranchName}} | {{.BranchName}} | ||||
| <span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -833,6 +833,7 @@ | |||||
| $(`[vfield="Description"]`).text(res['Description'] || '--'); | $(`[vfield="Description"]`).text(res['Description'] || '--'); | ||||
| $(`[vfield="Parameters"]`).text(res['Parameters'] || '--'); | $(`[vfield="Parameters"]`).text(res['Parameters'] || '--'); | ||||
| $(`[vfield="BranchName"]`).html(res['BranchName'] + '<span style="margin-left:1rem" class="ui label">' + res['CommitID'].slice(0, 10) + '</span>'); | |||||
| var imageName = res['Image'] || res['EngineName']; | var imageName = res['Image'] || res['EngineName']; | ||||
| $(`[vimagetitle="Image"] span`).hide(); | $(`[vimagetitle="Image"] span`).hide(); | ||||
| @@ -15,7 +15,7 @@ | |||||
| {{else if .ResendLimited}} | {{else if .ResendLimited}} | ||||
| <p class="center">{{.i18n.Tr "auth.resent_limit_prompt"}}</p> | <p class="center">{{.i18n.Tr "auth.resent_limit_prompt"}}</p> | ||||
| {{else}} | {{else}} | ||||
| <p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" .SignedUser.Email .ActiveCodeLives | Str2html}}</p> | |||||
| <p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" .Email .ActiveCodeLives | Str2html}}</p> | |||||
| {{end}} | {{end}} | ||||
| {{else}} | {{else}} | ||||
| {{if .IsSendRegisterMail}} | {{if .IsSendRegisterMail}} | ||||
| @@ -26,6 +26,7 @@ | |||||
| <p>{{.i18n.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email | Str2html}}</p> | <p>{{.i18n.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email | Str2html}}</p> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| <div class="text right"> | <div class="text right"> | ||||
| <button type="button" class="ui blue button change">{{.i18n.Tr "auth.change_email"}}</button> | |||||
| <button class="ui blue button">{{.i18n.Tr "auth.resend_mail"}}</button> | <button class="ui blue button">{{.i18n.Tr "auth.resend_mail"}}</button> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| @@ -34,5 +35,32 @@ | |||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div> | |||||
| <div class="ui modal chang-email"> | |||||
| <div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | |||||
| <h4>{{.i18n.Tr "auth.change_email_address"}}</h4> | |||||
| </div> | |||||
| <form id="formId" action="{{AppSubUrl}}/user/update_email" method="POST" class="ui form"> | |||||
| <div class="content content-padding"> | |||||
| <div class="ui error message"> | |||||
| </div> | |||||
| {{$.CsrfTokenHtml}} | |||||
| <div class="inline required field"> | |||||
| <label>{{.i18n.Tr "auth.new_email_address"}}</label> | |||||
| <input style="width: 80%;" id="label" name="NewEmail" maxlength="255" value="{{.SignedUser.Email}}"> | |||||
| </div> | |||||
| </div> | |||||
| <div class="center actions"> | |||||
| <button class="ui green button">{{.i18n.Tr "repo.confirm_choice"}}</button> | |||||
| <div class="ui deny button">{{.i18n.Tr "cancel"}}</div> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| <script> | |||||
| $('.ui.blue.button.change').on('click',function(){ | |||||
| $('.ui.modal').modal('show') | |||||
| }) | |||||
| </script> | |||||
| @@ -1301,3 +1301,17 @@ i.SUCCEEDED { | |||||
| max-height: 500px; | max-height: 500px; | ||||
| overflow: auto; | overflow: auto; | ||||
| } | } | ||||
| .chang-email .content { | |||||
| display: block; | |||||
| width: 100%; | |||||
| font-size: 1em; | |||||
| line-height: 1.4; | |||||
| padding: 1.5rem; | |||||
| background: #fff; | |||||
| } | |||||
| .chang-email .actions { | |||||
| background: #f9fafb; | |||||
| padding: 1rem 1rem; | |||||
| border-top: 1px solid rgba(34,36,38,.15); | |||||
| text-align: right; | |||||
| } | |||||
| @@ -228,7 +228,7 @@ const en = { | |||||
| local: 'Local', | local: 'Local', | ||||
| online: 'Online', | online: 'Online', | ||||
| createModel: 'Create Model', | createModel: 'Create Model', | ||||
| importLocalModel: 'Import Lacal Model', | |||||
| importLocalModel: 'Import Local Model', | |||||
| importOnlineModel: 'Import Online Model', | importOnlineModel: 'Import Online Model', | ||||
| modifyModelInfo: 'Modify model information', | modifyModelInfo: 'Modify model information', | ||||
| addModelFiles: 'Add model files', | addModelFiles: 'Add model files', | ||||