| @@ -17,7 +17,7 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| ) | ) | ||||
| const APP_VER = "0.6.18.1026 Beta" | |||||
| const APP_VER = "0.6.18.1029 Beta" | |||||
| func init() { | func init() { | ||||
| runtime.GOMAXPROCS(runtime.NumCPU()) | runtime.GOMAXPROCS(runtime.NumCPU()) | ||||
| @@ -160,7 +160,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error | |||||
| } | } | ||||
| // Clone base repo. | // Clone base repo. | ||||
| tmpBasePath := path.Join("data/tmp/repos", com.ToStr(time.Now().Nanosecond())+".git") | |||||
| tmpBasePath := path.Join(setting.AppDataPath, "tmp/repos", com.ToStr(time.Now().Nanosecond())+".git") | |||||
| os.MkdirAll(path.Dir(tmpBasePath), os.ModePerm) | os.MkdirAll(path.Dir(tmpBasePath), os.ModePerm) | ||||
| defer os.RemoveAll(path.Dir(tmpBasePath)) | defer os.RemoveAll(path.Dir(tmpBasePath)) | ||||
| @@ -214,6 +214,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error | |||||
| var patchConflicts = []string{ | var patchConflicts = []string{ | ||||
| "patch does not apply", | "patch does not apply", | ||||
| "already exists in working directory", | "already exists in working directory", | ||||
| "unrecognized input", | |||||
| } | } | ||||
| // testPatch checks if patch can be merged to base repository without conflit. | // testPatch checks if patch can be merged to base repository without conflit. | ||||
| @@ -300,7 +300,7 @@ func (repo *Repository) DescriptionHtml() template.HTML { | |||||
| } | } | ||||
| func (repo *Repository) LocalCopyPath() string { | func (repo *Repository) LocalCopyPath() string { | ||||
| return path.Join(setting.RepoRootPath, "local", com.ToStr(repo.ID)) | |||||
| return path.Join(setting.AppDataPath, "tmp/local", com.ToStr(repo.ID)) | |||||
| } | } | ||||
| // UpdateLocalCopy makes sure the local copy of repository is up-to-date. | // UpdateLocalCopy makes sure the local copy of repository is up-to-date. | ||||
| @@ -1488,6 +1488,12 @@ func CheckRepoStats() { | |||||
| "UPDATE `user` SET num_repos=(SELECT COUNT(*) FROM `repository` WHERE owner_id=?) WHERE id=?", | "UPDATE `user` SET num_repos=(SELECT COUNT(*) FROM `repository` WHERE owner_id=?) WHERE id=?", | ||||
| "user count 'num_repos'", | "user count 'num_repos'", | ||||
| }, | }, | ||||
| // Issue.NumComments | |||||
| { | |||||
| "SELECT `issue`.id FROM `issue` WHERE `issue`.num_comments!=(SELECT COUNT(*) FROM `comment` WHERE issue_id=`issue`.id AND type=0)", | |||||
| "UPDATE `issue` SET num_comments=(SELECT COUNT(*) FROM `comment` WHERE issue_id=? AND type=0) WHERE id=?", | |||||
| "issue count 'num_comments'", | |||||
| }, | |||||
| } | } | ||||
| for i := range checkers { | for i := range checkers { | ||||
| repoStatsCheck(checkers[i]) | repoStatsCheck(checkers[i]) | ||||
| @@ -43,10 +43,11 @@ const ( | |||||
| var ( | var ( | ||||
| // App settings. | // App settings. | ||||
| AppVer string | |||||
| AppName string | |||||
| AppUrl string | |||||
| AppSubUrl string | |||||
| AppVer string | |||||
| AppName string | |||||
| AppUrl string | |||||
| AppSubUrl string | |||||
| AppDataPath = "data" | |||||
| // Server settings. | // Server settings. | ||||
| Protocol Scheme | Protocol Scheme | ||||
| @@ -319,7 +320,7 @@ func NewContext() { | |||||
| ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER") | ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER") | ||||
| sec = Cfg.Section("attachment") | sec = Cfg.Section("attachment") | ||||
| AttachmentPath = sec.Key("PATH").MustString("data/attachments") | |||||
| AttachmentPath = sec.Key("PATH").MustString(path.Join(AppDataPath, "attachments")) | |||||
| if !filepath.IsAbs(AttachmentPath) { | if !filepath.IsAbs(AttachmentPath) { | ||||
| AttachmentPath = path.Join(workDir, AttachmentPath) | AttachmentPath = path.Join(workDir, AttachmentPath) | ||||
| } | } | ||||
| @@ -387,7 +388,7 @@ func NewContext() { | |||||
| sec = Cfg.Section("picture") | sec = Cfg.Section("picture") | ||||
| PictureService = sec.Key("SERVICE").In("server", []string{"server"}) | PictureService = sec.Key("SERVICE").In("server", []string{"server"}) | ||||
| AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString("data/avatars") | |||||
| AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString(path.Join(AppDataPath, "avatars")) | |||||
| forcePathSeparator(AvatarUploadPath) | forcePathSeparator(AvatarUploadPath) | ||||
| if !filepath.IsAbs(AvatarUploadPath) { | if !filepath.IsAbs(AvatarUploadPath) { | ||||
| AvatarUploadPath = path.Join(workDir, AvatarUploadPath) | AvatarUploadPath = path.Join(workDir, AvatarUploadPath) | ||||
| @@ -324,6 +324,47 @@ func ValidateRepoMetas(ctx *middleware.Context, form auth.CreateIssueForm) ([]in | |||||
| return labelIDs, milestoneID, assigneeID | return labelIDs, milestoneID, assigneeID | ||||
| } | } | ||||
| func checkMentions(ctx *middleware.Context, issue *models.Issue) { | |||||
| // Update mentions. | |||||
| mentions := base.MentionPattern.FindAllString(issue.Content, -1) | |||||
| if len(mentions) > 0 { | |||||
| for i := range mentions { | |||||
| mentions[i] = strings.TrimSpace(mentions[i])[1:] | |||||
| } | |||||
| if err := models.UpdateMentions(mentions, issue.ID); err != nil { | |||||
| ctx.Handle(500, "UpdateMentions", err) | |||||
| return | |||||
| } | |||||
| } | |||||
| repo := ctx.Repo.Repository | |||||
| // Mail watchers and mentions. | |||||
| if setting.Service.EnableNotifyMail { | |||||
| tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, repo, issue) | |||||
| if err != nil { | |||||
| ctx.Handle(500, "SendIssueNotifyMail", err) | |||||
| return | |||||
| } | |||||
| tos = append(tos, ctx.User.LowerName) | |||||
| newTos := make([]string, 0, len(mentions)) | |||||
| for _, m := range mentions { | |||||
| if com.IsSliceContainsStr(tos, m) { | |||||
| continue | |||||
| } | |||||
| newTos = append(newTos, m) | |||||
| } | |||||
| if err = mailer.SendIssueMentionMail(ctx.Render, ctx.User, ctx.Repo.Owner, | |||||
| repo, issue, models.GetUserEmailsByNames(newTos)); err != nil { | |||||
| ctx.Handle(500, "SendIssueMentionMail", err) | |||||
| return | |||||
| } | |||||
| } | |||||
| } | |||||
| func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { | func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { | ||||
| ctx.Data["Title"] = ctx.Tr("repo.issues.new") | ctx.Data["Title"] = ctx.Tr("repo.issues.new") | ||||
| ctx.Data["PageIsIssueList"] = true | ctx.Data["PageIsIssueList"] = true | ||||
| @@ -363,41 +404,9 @@ func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { | |||||
| return | return | ||||
| } | } | ||||
| // Update mentions. | |||||
| mentions := base.MentionPattern.FindAllString(issue.Content, -1) | |||||
| if len(mentions) > 0 { | |||||
| for i := range mentions { | |||||
| mentions[i] = strings.TrimSpace(mentions[i])[1:] | |||||
| } | |||||
| if err := models.UpdateMentions(mentions, issue.ID); err != nil { | |||||
| ctx.Handle(500, "UpdateMentions", err) | |||||
| return | |||||
| } | |||||
| } | |||||
| // Mail watchers and mentions. | |||||
| if setting.Service.EnableNotifyMail { | |||||
| tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, repo, issue) | |||||
| if err != nil { | |||||
| ctx.Handle(500, "SendIssueNotifyMail", err) | |||||
| return | |||||
| } | |||||
| tos = append(tos, ctx.User.LowerName) | |||||
| newTos := make([]string, 0, len(mentions)) | |||||
| for _, m := range mentions { | |||||
| if com.IsSliceContainsStr(tos, m) { | |||||
| continue | |||||
| } | |||||
| newTos = append(newTos, m) | |||||
| } | |||||
| if err = mailer.SendIssueMentionMail(ctx.Render, ctx.User, ctx.Repo.Owner, | |||||
| repo, issue, models.GetUserEmailsByNames(newTos)); err != nil { | |||||
| ctx.Handle(500, "SendIssueMentionMail", err) | |||||
| return | |||||
| } | |||||
| checkMentions(ctx, issue) | |||||
| if ctx.Written() { | |||||
| return | |||||
| } | } | ||||
| log.Trace("Issue created: %d/%d", repo.ID, issue.ID) | log.Trace("Issue created: %d/%d", repo.ID, issue.ID) | ||||
| @@ -836,46 +845,16 @@ func NewComment(ctx *middleware.Context, form auth.CreateCommentForm) { | |||||
| return | return | ||||
| } | } | ||||
| // Update mentions. | |||||
| mentions := base.MentionPattern.FindAllString(comment.Content, -1) | |||||
| if len(mentions) > 0 { | |||||
| for i := range mentions { | |||||
| mentions[i] = mentions[i][1:] | |||||
| } | |||||
| if err := models.UpdateMentions(mentions, issue.ID); err != nil { | |||||
| ctx.Handle(500, "UpdateMentions", err) | |||||
| return | |||||
| } | |||||
| checkMentions(ctx, &models.Issue{ | |||||
| ID: issue.ID, | |||||
| Index: issue.Index, | |||||
| Name: issue.Name, | |||||
| Content: form.Content, | |||||
| }) | |||||
| if ctx.Written() { | |||||
| return | |||||
| } | } | ||||
| // Mail watchers and mentions. | |||||
| if setting.Service.EnableNotifyMail { | |||||
| tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, &models.Issue{ | |||||
| Index: issue.Index, | |||||
| Name: issue.Name, | |||||
| Content: form.Content, | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.Handle(500, "SendIssueNotifyMail", err) | |||||
| return | |||||
| } | |||||
| tos = append(tos, ctx.User.LowerName) | |||||
| newTos := make([]string, 0, len(mentions)) | |||||
| for _, m := range mentions { | |||||
| if com.IsSliceContainsStr(tos, m) { | |||||
| continue | |||||
| } | |||||
| newTos = append(newTos, m) | |||||
| } | |||||
| if err = mailer.SendIssueMentionMail(ctx.Render, ctx.User, ctx.Repo.Owner, | |||||
| ctx.Repo.Repository, issue, models.GetUserEmailsByNames(newTos)); err != nil { | |||||
| ctx.Handle(500, "SendIssueMentionMail", err) | |||||
| return | |||||
| } | |||||
| } | |||||
| log.Trace("Comment created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID) | log.Trace("Comment created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID) | ||||
| } | } | ||||
| @@ -1 +1 @@ | |||||
| 0.6.18.1026 Beta | |||||
| 0.6.18.1029 Beta | |||||