You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

issue.go 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package convert
  5. import (
  6. "strings"
  7. "code.gitea.io/gitea/models"
  8. api "code.gitea.io/gitea/modules/structs"
  9. )
  10. // ToAPIIssue converts an Issue to API format
  11. // it assumes some fields assigned with values:
  12. // Required - Poster, Labels,
  13. // Optional - Milestone, Assignee, PullRequest
  14. func ToAPIIssue(issue *models.Issue) *api.Issue {
  15. if err := issue.LoadLabels(); err != nil {
  16. return &api.Issue{}
  17. }
  18. if err := issue.LoadPoster(); err != nil {
  19. return &api.Issue{}
  20. }
  21. if err := issue.LoadRepo(); err != nil {
  22. return &api.Issue{}
  23. }
  24. apiIssue := &api.Issue{
  25. ID: issue.ID,
  26. URL: issue.APIURL(),
  27. HTMLURL: issue.HTMLURL(),
  28. Index: issue.Index,
  29. Poster: issue.Poster.APIFormat(),
  30. Title: issue.Title,
  31. Body: issue.Content,
  32. Labels: ToLabelList(issue.Labels),
  33. State: issue.State(),
  34. Comments: issue.NumComments,
  35. Created: issue.CreatedUnix.AsTime(),
  36. Updated: issue.UpdatedUnix.AsTime(),
  37. }
  38. apiIssue.Repo = &api.RepositoryMeta{
  39. ID: issue.Repo.ID,
  40. Name: issue.Repo.Name,
  41. Owner: issue.Repo.OwnerName,
  42. FullName: issue.Repo.FullName(),
  43. }
  44. if issue.ClosedUnix != 0 {
  45. apiIssue.Closed = issue.ClosedUnix.AsTimePtr()
  46. }
  47. if err := issue.LoadMilestone(); err != nil {
  48. return &api.Issue{}
  49. }
  50. if issue.Milestone != nil {
  51. apiIssue.Milestone = ToAPIMilestone(issue.Milestone)
  52. }
  53. if err := issue.LoadAssignees(); err != nil {
  54. return &api.Issue{}
  55. }
  56. if len(issue.Assignees) > 0 {
  57. for _, assignee := range issue.Assignees {
  58. apiIssue.Assignees = append(apiIssue.Assignees, assignee.APIFormat())
  59. }
  60. apiIssue.Assignee = issue.Assignees[0].APIFormat() // For compatibility, we're keeping the first assignee as `apiIssue.Assignee`
  61. }
  62. if issue.IsPull {
  63. if err := issue.LoadPullRequest(); err != nil {
  64. return &api.Issue{}
  65. }
  66. apiIssue.PullRequest = &api.PullRequestMeta{
  67. HasMerged: issue.PullRequest.HasMerged,
  68. }
  69. if issue.PullRequest.HasMerged {
  70. apiIssue.PullRequest.Merged = issue.PullRequest.MergedUnix.AsTimePtr()
  71. }
  72. }
  73. if issue.DeadlineUnix != 0 {
  74. apiIssue.Deadline = issue.DeadlineUnix.AsTimePtr()
  75. }
  76. return apiIssue
  77. }
  78. // ToAPIIssueList converts an IssueList to API format
  79. func ToAPIIssueList(il models.IssueList) []*api.Issue {
  80. result := make([]*api.Issue, len(il))
  81. for i := range il {
  82. result[i] = ToAPIIssue(il[i])
  83. }
  84. return result
  85. }
  86. // ToTrackedTime converts TrackedTime to API format
  87. func ToTrackedTime(t *models.TrackedTime) (apiT *api.TrackedTime) {
  88. apiT = &api.TrackedTime{
  89. ID: t.ID,
  90. IssueID: t.IssueID,
  91. UserID: t.UserID,
  92. UserName: t.User.Name,
  93. Time: t.Time,
  94. Created: t.Created,
  95. }
  96. if t.Issue != nil {
  97. apiT.Issue = ToAPIIssue(t.Issue)
  98. }
  99. if t.User != nil {
  100. apiT.UserName = t.User.Name
  101. }
  102. return
  103. }
  104. // ToTrackedTimeList converts TrackedTimeList to API format
  105. func ToTrackedTimeList(tl models.TrackedTimeList) api.TrackedTimeList {
  106. result := make([]*api.TrackedTime, 0, len(tl))
  107. for _, t := range tl {
  108. result = append(result, ToTrackedTime(t))
  109. }
  110. return result
  111. }
  112. // ToLabel converts Label to API format
  113. func ToLabel(label *models.Label) *api.Label {
  114. return &api.Label{
  115. ID: label.ID,
  116. Name: label.Name,
  117. Color: strings.TrimLeft(label.Color, "#"),
  118. Description: label.Description,
  119. }
  120. }
  121. // ToLabelList converts list of Label to API format
  122. func ToLabelList(labels []*models.Label) []*api.Label {
  123. result := make([]*api.Label, len(labels))
  124. for i := range labels {
  125. result[i] = ToLabel(labels[i])
  126. }
  127. return result
  128. }
  129. // ToAPIMilestone converts Milestone into API Format
  130. func ToAPIMilestone(m *models.Milestone) *api.Milestone {
  131. apiMilestone := &api.Milestone{
  132. ID: m.ID,
  133. State: m.State(),
  134. Title: m.Name,
  135. Description: m.Content,
  136. OpenIssues: m.NumOpenIssues,
  137. ClosedIssues: m.NumClosedIssues,
  138. }
  139. if m.IsClosed {
  140. apiMilestone.Closed = m.ClosedDateUnix.AsTimePtr()
  141. }
  142. if m.DeadlineUnix.Year() < 9999 {
  143. apiMilestone.Deadline = m.DeadlineUnix.AsTimePtr()
  144. }
  145. return apiMilestone
  146. }