diff options
Diffstat (limited to 'models/issue.go')
-rw-r--r-- | models/issue.go | 502 |
1 files changed, 0 insertions, 502 deletions
diff --git a/models/issue.go b/models/issue.go index dbe01f6f..0997f3bb 100644 --- a/models/issue.go +++ b/models/issue.go @@ -7,17 +7,12 @@ package models import ( "errors" "fmt" - "io" - "mime/multipart" - "os" - "path" "strings" "time" "github.com/Unknwon/com" "github.com/go-xorm/xorm" api "github.com/gogits/go-gogs-client" - gouuid "github.com/satori/go.uuid" log "gopkg.in/clog.v1" "github.com/gogits/gogs/modules/base" @@ -1332,500 +1327,3 @@ func updateIssueUsersByMentions(e Engine, issueID int64, uids []int64) error { } return nil } - -// _____ .__.__ __ -// / \ |__| | ____ _______/ |_ ____ ____ ____ -// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \ -// / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/ -// \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ > -// \/ \/ \/ \/ \/ - -// Milestone represents a milestone of repository. -type Milestone struct { - ID int64 `xorm:"pk autoincr"` - RepoID int64 `xorm:"INDEX"` - Name string - Content string `xorm:"TEXT"` - RenderedContent string `xorm:"-"` - IsClosed bool - NumIssues int - NumClosedIssues int - NumOpenIssues int `xorm:"-"` - Completeness int // Percentage(1-100). - IsOverDue bool `xorm:"-"` - - DeadlineString string `xorm:"-"` - Deadline time.Time `xorm:"-"` - DeadlineUnix int64 - ClosedDate time.Time `xorm:"-"` - ClosedDateUnix int64 -} - -func (m *Milestone) BeforeInsert() { - m.DeadlineUnix = m.Deadline.Unix() -} - -func (m *Milestone) BeforeUpdate() { - if m.NumIssues > 0 { - m.Completeness = m.NumClosedIssues * 100 / m.NumIssues - } else { - m.Completeness = 0 - } - - m.DeadlineUnix = m.Deadline.Unix() - m.ClosedDateUnix = m.ClosedDate.Unix() -} - -func (m *Milestone) AfterSet(colName string, _ xorm.Cell) { - switch colName { - case "num_closed_issues": - m.NumOpenIssues = m.NumIssues - m.NumClosedIssues - - case "deadline_unix": - m.Deadline = time.Unix(m.DeadlineUnix, 0).Local() - if m.Deadline.Year() == 9999 { - return - } - - m.DeadlineString = m.Deadline.Format("2006-01-02") - if time.Now().Local().After(m.Deadline) { - m.IsOverDue = true - } - - case "closed_date_unix": - m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local() - } -} - -// State returns string representation of milestone status. -func (m *Milestone) State() api.StateType { - if m.IsClosed { - return api.STATE_CLOSED - } - return api.STATE_OPEN -} - -func (m *Milestone) ChangeStatus(isClosed bool) error { - return ChangeMilestoneStatus(m, isClosed) -} - -func (m *Milestone) APIFormat() *api.Milestone { - apiMilestone := &api.Milestone{ - ID: m.ID, - State: m.State(), - Title: m.Name, - Description: m.Content, - OpenIssues: m.NumOpenIssues, - ClosedIssues: m.NumClosedIssues, - } - if m.IsClosed { - apiMilestone.Closed = &m.ClosedDate - } - if m.Deadline.Year() < 9999 { - apiMilestone.Deadline = &m.Deadline - } - return apiMilestone -} - -// NewMilestone creates new milestone of repository. -func NewMilestone(m *Milestone) (err error) { - sess := x.NewSession() - defer sessionRelease(sess) - if err = sess.Begin(); err != nil { - return err - } - - if _, err = sess.Insert(m); err != nil { - return err - } - - if _, err = sess.Exec("UPDATE `repository` SET num_milestones = num_milestones + 1 WHERE id = ?", m.RepoID); err != nil { - return err - } - return sess.Commit() -} - -func getMilestoneByRepoID(e Engine, repoID, id int64) (*Milestone, error) { - m := &Milestone{ - ID: id, - RepoID: repoID, - } - has, err := e.Get(m) - if err != nil { - return nil, err - } else if !has { - return nil, ErrMilestoneNotExist{id, repoID} - } - return m, nil -} - -// GetWebhookByRepoID returns the milestone in a repository. -func GetMilestoneByRepoID(repoID, id int64) (*Milestone, error) { - return getMilestoneByRepoID(x, repoID, id) -} - -// GetMilestonesByRepoID returns all milestones of a repository. -func GetMilestonesByRepoID(repoID int64) ([]*Milestone, error) { - miles := make([]*Milestone, 0, 10) - return miles, x.Where("repo_id = ?", repoID).Find(&miles) -} - -// GetMilestones returns a list of milestones of given repository and status. -func GetMilestones(repoID int64, page int, isClosed bool) ([]*Milestone, error) { - miles := make([]*Milestone, 0, setting.UI.IssuePagingNum) - sess := x.Where("repo_id = ? AND is_closed = ?", repoID, isClosed) - if page > 0 { - sess = sess.Limit(setting.UI.IssuePagingNum, (page-1)*setting.UI.IssuePagingNum) - } - return miles, sess.Find(&miles) -} - -func updateMilestone(e Engine, m *Milestone) error { - _, err := e.Id(m.ID).AllCols().Update(m) - return err -} - -// UpdateMilestone updates information of given milestone. -func UpdateMilestone(m *Milestone) error { - return updateMilestone(x, m) -} - -func countRepoMilestones(e Engine, repoID int64) int64 { - count, _ := e.Where("repo_id=?", repoID).Count(new(Milestone)) - return count -} - -// CountRepoMilestones returns number of milestones in given repository. -func CountRepoMilestones(repoID int64) int64 { - return countRepoMilestones(x, repoID) -} - -func countRepoClosedMilestones(e Engine, repoID int64) int64 { - closed, _ := e.Where("repo_id=? AND is_closed=?", repoID, true).Count(new(Milestone)) - return closed -} - -// CountRepoClosedMilestones returns number of closed milestones in given repository. -func CountRepoClosedMilestones(repoID int64) int64 { - return countRepoClosedMilestones(x, repoID) -} - -// MilestoneStats returns number of open and closed milestones of given repository. -func MilestoneStats(repoID int64) (open int64, closed int64) { - open, _ = x.Where("repo_id=? AND is_closed=?", repoID, false).Count(new(Milestone)) - return open, CountRepoClosedMilestones(repoID) -} - -// ChangeMilestoneStatus changes the milestone open/closed status. -// If milestone passes with changed values, those values will be -// updated to database as well. -func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) { - repo, err := GetRepositoryByID(m.RepoID) - if err != nil { - return err - } - - sess := x.NewSession() - defer sessionRelease(sess) - if err = sess.Begin(); err != nil { - return err - } - - m.IsClosed = isClosed - if err = updateMilestone(sess, m); err != nil { - return err - } - - repo.NumMilestones = int(countRepoMilestones(sess, repo.ID)) - repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.ID)) - if _, err = sess.Id(repo.ID).AllCols().Update(repo); err != nil { - return err - } - return sess.Commit() -} - -func changeMilestoneIssueStats(e *xorm.Session, issue *Issue) error { - if issue.MilestoneID == 0 { - return nil - } - - m, err := getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID) - if err != nil { - return err - } - - if issue.IsClosed { - m.NumOpenIssues-- - m.NumClosedIssues++ - } else { - m.NumOpenIssues++ - m.NumClosedIssues-- - } - - return updateMilestone(e, m) -} - -// ChangeMilestoneIssueStats updates the open/closed issues counter and progress -// for the milestone associated with the given issue. -func ChangeMilestoneIssueStats(issue *Issue) (err error) { - sess := x.NewSession() - defer sessionRelease(sess) - if err = sess.Begin(); err != nil { - return err - } - - if err = changeMilestoneIssueStats(sess, issue); err != nil { - return err - } - - return sess.Commit() -} - -func changeMilestoneAssign(e *xorm.Session, issue *Issue, oldMilestoneID int64) error { - if oldMilestoneID > 0 { - m, err := getMilestoneByRepoID(e, issue.RepoID, oldMilestoneID) - if err != nil { - return err - } - - m.NumIssues-- - if issue.IsClosed { - m.NumClosedIssues-- - } - - if err = updateMilestone(e, m); err != nil { - return err - } else if _, err = e.Exec("UPDATE `issue_user` SET milestone_id = 0 WHERE issue_id = ?", issue.ID); err != nil { - return err - } - } - - if issue.MilestoneID > 0 { - m, err := getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID) - if err != nil { - return err - } - - m.NumIssues++ - if issue.IsClosed { - m.NumClosedIssues++ - } - - if err = updateMilestone(e, m); err != nil { - return err - } else if _, err = e.Exec("UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?", m.ID, issue.ID); err != nil { - return err - } - } - - return updateIssue(e, issue) -} - -// ChangeMilestoneAssign changes assignment of milestone for issue. -func ChangeMilestoneAssign(issue *Issue, oldMilestoneID int64) (err error) { - sess := x.NewSession() - defer sess.Close() - if err = sess.Begin(); err != nil { - return err - } - - if err = changeMilestoneAssign(sess, issue, oldMilestoneID); err != nil { - return err - } - return sess.Commit() -} - -// DeleteMilestoneOfRepoByID deletes a milestone from a repository. -func DeleteMilestoneOfRepoByID(repoID, id int64) error { - m, err := GetMilestoneByRepoID(repoID, id) - if err != nil { - if IsErrMilestoneNotExist(err) { - return nil - } - return err - } - - repo, err := GetRepositoryByID(m.RepoID) - if err != nil { - return err - } - - sess := x.NewSession() - defer sessionRelease(sess) - if err = sess.Begin(); err != nil { - return err - } - - if _, err = sess.Id(m.ID).Delete(new(Milestone)); err != nil { - return err - } - - repo.NumMilestones = int(countRepoMilestones(sess, repo.ID)) - repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.ID)) - if _, err = sess.Id(repo.ID).AllCols().Update(repo); err != nil { - return err - } - - if _, err = sess.Exec("UPDATE `issue` SET milestone_id = 0 WHERE milestone_id = ?", m.ID); err != nil { - return err - } else if _, err = sess.Exec("UPDATE `issue_user` SET milestone_id = 0 WHERE milestone_id = ?", m.ID); err != nil { - return err - } - return sess.Commit() -} - -// Attachment represent a attachment of issue/comment/release. -type Attachment struct { - ID int64 `xorm:"pk autoincr"` - UUID string `xorm:"uuid UNIQUE"` - IssueID int64 `xorm:"INDEX"` - CommentID int64 - ReleaseID int64 `xorm:"INDEX"` - Name string - - Created time.Time `xorm:"-"` - CreatedUnix int64 -} - -func (a *Attachment) BeforeInsert() { - a.CreatedUnix = time.Now().Unix() -} - -func (a *Attachment) AfterSet(colName string, _ xorm.Cell) { - switch colName { - case "created_unix": - a.Created = time.Unix(a.CreatedUnix, 0).Local() - } -} - -// AttachmentLocalPath returns where attachment is stored in local file system based on given UUID. -func AttachmentLocalPath(uuid string) string { - return path.Join(setting.AttachmentPath, uuid[0:1], uuid[1:2], uuid) -} - -// LocalPath returns where attachment is stored in local file system. -func (attach *Attachment) LocalPath() string { - return AttachmentLocalPath(attach.UUID) -} - -// NewAttachment creates a new attachment object. -func NewAttachment(name string, buf []byte, file multipart.File) (_ *Attachment, err error) { - attach := &Attachment{ - UUID: gouuid.NewV4().String(), - Name: name, - } - - localPath := attach.LocalPath() - if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil { - return nil, fmt.Errorf("MkdirAll: %v", err) - } - - fw, err := os.Create(localPath) - if err != nil { - return nil, fmt.Errorf("Create: %v", err) - } - defer fw.Close() - - if _, err = fw.Write(buf); err != nil { - return nil, fmt.Errorf("Write: %v", err) - } else if _, err = io.Copy(fw, file); err != nil { - return nil, fmt.Errorf("Copy: %v", err) - } - - if _, err := x.Insert(attach); err != nil { - return nil, err - } - - return attach, nil -} - -func getAttachmentByUUID(e Engine, uuid string) (*Attachment, error) { - attach := &Attachment{UUID: uuid} - has, err := x.Get(attach) - if err != nil { - return nil, err - } else if !has { - return nil, ErrAttachmentNotExist{0, uuid} - } - return attach, nil -} - -func getAttachmentsByUUIDs(e Engine, uuids []string) ([]*Attachment, error) { - if len(uuids) == 0 { - return []*Attachment{}, nil - } - - // Silently drop invalid uuids. - attachments := make([]*Attachment, 0, len(uuids)) - return attachments, e.In("uuid", uuids).Find(&attachments) -} - -// GetAttachmentByUUID returns attachment by given UUID. -func GetAttachmentByUUID(uuid string) (*Attachment, error) { - return getAttachmentByUUID(x, uuid) -} - -func getAttachmentsByIssueID(e Engine, issueID int64) ([]*Attachment, error) { - attachments := make([]*Attachment, 0, 10) - return attachments, e.Where("issue_id = ? AND comment_id = 0", issueID).Find(&attachments) -} - -// GetAttachmentsByIssueID returns all attachments of an issue. -func GetAttachmentsByIssueID(issueID int64) ([]*Attachment, error) { - return getAttachmentsByIssueID(x, issueID) -} - -func getAttachmentsByCommentID(e Engine, commentID int64) ([]*Attachment, error) { - attachments := make([]*Attachment, 0, 10) - return attachments, e.Where("comment_id=?", commentID).Find(&attachments) -} - -// GetAttachmentsByCommentID returns all attachments if comment by given ID. -func GetAttachmentsByCommentID(commentID int64) ([]*Attachment, error) { - return getAttachmentsByCommentID(x, commentID) -} - -// DeleteAttachment deletes the given attachment and optionally the associated file. -func DeleteAttachment(a *Attachment, remove bool) error { - _, err := DeleteAttachments([]*Attachment{a}, remove) - return err -} - -// DeleteAttachments deletes the given attachments and optionally the associated files. -func DeleteAttachments(attachments []*Attachment, remove bool) (int, error) { - for i, a := range attachments { - if remove { - if err := os.Remove(a.LocalPath()); err != nil { - return i, err - } - } - - if _, err := x.Delete(a); err != nil { - return i, err - } - } - - return len(attachments), nil -} - -// DeleteAttachmentsByIssue deletes all attachments associated with the given issue. -func DeleteAttachmentsByIssue(issueId int64, remove bool) (int, error) { - attachments, err := GetAttachmentsByIssueID(issueId) - - if err != nil { - return 0, err - } - - return DeleteAttachments(attachments, remove) -} - -// DeleteAttachmentsByComment deletes all attachments associated with the given comment. -func DeleteAttachmentsByComment(commentId int64, remove bool) (int, error) { - attachments, err := GetAttachmentsByCommentID(commentId) - - if err != nil { - return 0, err - } - - return DeleteAttachments(attachments, remove) -} |