2020-01-11 05:59:41 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package convert
import (
2021-09-10 19:03:16 +03:00
"fmt"
2021-11-16 21:18:25 +03:00
"net/url"
2020-02-29 05:49:50 +03:00
"strings"
2020-01-11 05:59:41 +03:00
"code.gitea.io/gitea/models"
2021-12-10 04:27:50 +03:00
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2021-09-10 19:03:16 +03:00
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
2020-01-11 05:59:41 +03:00
api "code.gitea.io/gitea/modules/structs"
)
2020-02-29 05:49:50 +03:00
// ToAPIIssue converts an Issue to API format
// it assumes some fields assigned with values:
// Required - Poster, Labels,
// Optional - Milestone, Assignee, PullRequest
func ToAPIIssue ( issue * models . Issue ) * api . Issue {
if err := issue . LoadLabels ( ) ; err != nil {
return & api . Issue { }
}
if err := issue . LoadPoster ( ) ; err != nil {
return & api . Issue { }
}
if err := issue . LoadRepo ( ) ; err != nil {
return & api . Issue { }
}
2021-12-10 04:27:50 +03:00
if err := issue . Repo . GetOwner ( db . DefaultContext ) ; err != nil {
2021-09-10 19:03:16 +03:00
return & api . Issue { }
}
2020-02-29 05:49:50 +03:00
apiIssue := & api . Issue {
ID : issue . ID ,
URL : issue . APIURL ( ) ,
HTMLURL : issue . HTMLURL ( ) ,
Index : issue . Index ,
2021-03-27 19:45:26 +03:00
Poster : ToUser ( issue . Poster , nil ) ,
2020-02-29 05:49:50 +03:00
Title : issue . Title ,
Body : issue . Content ,
2020-12-13 14:34:11 +03:00
Ref : issue . Ref ,
2021-09-10 19:03:16 +03:00
Labels : ToLabelList ( issue . Labels , issue . Repo , issue . Repo . Owner ) ,
2020-02-29 05:49:50 +03:00
State : issue . State ( ) ,
2020-06-02 00:01:55 +03:00
IsLocked : issue . IsLocked ,
2020-02-29 05:49:50 +03:00
Comments : issue . NumComments ,
Created : issue . CreatedUnix . AsTime ( ) ,
Updated : issue . UpdatedUnix . AsTime ( ) ,
}
apiIssue . Repo = & api . RepositoryMeta {
ID : issue . Repo . ID ,
Name : issue . Repo . Name ,
Owner : issue . Repo . OwnerName ,
FullName : issue . Repo . FullName ( ) ,
}
if issue . ClosedUnix != 0 {
apiIssue . Closed = issue . ClosedUnix . AsTimePtr ( )
}
if err := issue . LoadMilestone ( ) ; err != nil {
return & api . Issue { }
}
if issue . Milestone != nil {
2020-05-13 00:54:35 +03:00
apiIssue . Milestone = ToAPIMilestone ( issue . Milestone )
2020-02-29 05:49:50 +03:00
}
if err := issue . LoadAssignees ( ) ; err != nil {
return & api . Issue { }
}
if len ( issue . Assignees ) > 0 {
for _ , assignee := range issue . Assignees {
2021-03-27 19:45:26 +03:00
apiIssue . Assignees = append ( apiIssue . Assignees , ToUser ( assignee , nil ) )
2020-02-29 05:49:50 +03:00
}
2021-03-27 19:45:26 +03:00
apiIssue . Assignee = ToUser ( issue . Assignees [ 0 ] , nil ) // For compatibility, we're keeping the first assignee as `apiIssue.Assignee`
2020-02-29 05:49:50 +03:00
}
if issue . IsPull {
if err := issue . LoadPullRequest ( ) ; err != nil {
return & api . Issue { }
}
apiIssue . PullRequest = & api . PullRequestMeta {
HasMerged : issue . PullRequest . HasMerged ,
}
if issue . PullRequest . HasMerged {
apiIssue . PullRequest . Merged = issue . PullRequest . MergedUnix . AsTimePtr ( )
}
}
if issue . DeadlineUnix != 0 {
apiIssue . Deadline = issue . DeadlineUnix . AsTimePtr ( )
}
return apiIssue
}
// ToAPIIssueList converts an IssueList to API format
func ToAPIIssueList ( il models . IssueList ) [ ] * api . Issue {
result := make ( [ ] * api . Issue , len ( il ) )
for i := range il {
result [ i ] = ToAPIIssue ( il [ i ] )
}
return result
}
2020-01-11 05:59:41 +03:00
// ToTrackedTime converts TrackedTime to API format
func ToTrackedTime ( t * models . TrackedTime ) ( apiT * api . TrackedTime ) {
apiT = & api . TrackedTime {
ID : t . ID ,
IssueID : t . IssueID ,
UserID : t . UserID ,
UserName : t . User . Name ,
Time : t . Time ,
Created : t . Created ,
}
if t . Issue != nil {
2020-02-29 05:49:50 +03:00
apiT . Issue = ToAPIIssue ( t . Issue )
2020-01-11 05:59:41 +03:00
}
if t . User != nil {
apiT . UserName = t . User . Name
}
return
}
2020-09-18 15:09:26 +03:00
// ToStopWatches convert Stopwatch list to api.StopWatches
func ToStopWatches ( sws [ ] * models . Stopwatch ) ( api . StopWatches , error ) {
result := api . StopWatches ( make ( [ ] api . StopWatch , 0 , len ( sws ) ) )
issueCache := make ( map [ int64 ] * models . Issue )
2021-12-10 04:27:50 +03:00
repoCache := make ( map [ int64 ] * repo_model . Repository )
2020-09-18 15:09:26 +03:00
var (
issue * models . Issue
2021-12-10 04:27:50 +03:00
repo * repo_model . Repository
2020-09-18 15:09:26 +03:00
ok bool
err error
)
for _ , sw := range sws {
issue , ok = issueCache [ sw . IssueID ]
if ! ok {
issue , err = models . GetIssueByID ( sw . IssueID )
if err != nil {
return nil , err
}
}
repo , ok = repoCache [ issue . RepoID ]
if ! ok {
2021-12-10 04:27:50 +03:00
repo , err = repo_model . GetRepositoryByID ( issue . RepoID )
2020-09-18 15:09:26 +03:00
if err != nil {
return nil , err
}
}
result = append ( result , api . StopWatch {
Created : sw . CreatedUnix . AsTime ( ) ,
2021-01-21 17:51:52 +03:00
Seconds : sw . Seconds ( ) ,
Duration : sw . Duration ( ) ,
2020-09-18 15:09:26 +03:00
IssueIndex : issue . Index ,
IssueTitle : issue . Title ,
RepoOwnerName : repo . OwnerName ,
RepoName : repo . Name ,
} )
}
return result , nil
}
2020-01-11 05:59:41 +03:00
// ToTrackedTimeList converts TrackedTimeList to API format
func ToTrackedTimeList ( tl models . TrackedTimeList ) api . TrackedTimeList {
result := make ( [ ] * api . TrackedTime , 0 , len ( tl ) )
for _ , t := range tl {
result = append ( result , ToTrackedTime ( t ) )
}
return result
}
2020-02-29 05:49:50 +03:00
// ToLabel converts Label to API format
2021-12-10 04:27:50 +03:00
func ToLabel ( label * models . Label , repo * repo_model . Repository , org * user_model . User ) * api . Label {
2021-09-10 19:03:16 +03:00
result := & api . Label {
2020-02-29 05:49:50 +03:00
ID : label . ID ,
Name : label . Name ,
Color : strings . TrimLeft ( label . Color , "#" ) ,
Description : label . Description ,
}
2021-09-10 19:03:16 +03:00
// calculate URL
if label . BelongsToRepo ( ) && repo != nil {
if repo != nil {
result . URL = fmt . Sprintf ( "%s/labels/%d" , repo . APIURL ( ) , label . ID )
} else {
log . Error ( "ToLabel did not get repo to calculate url for label with id '%d'" , label . ID )
}
} else { // BelongsToOrg
if org != nil {
2021-11-16 21:18:25 +03:00
result . URL = fmt . Sprintf ( "%sapi/v1/orgs/%s/labels/%d" , setting . AppURL , url . PathEscape ( org . Name ) , label . ID )
2021-09-10 19:03:16 +03:00
} else {
log . Error ( "ToLabel did not get org to calculate url for label with id '%d'" , label . ID )
}
}
return result
2020-02-29 05:49:50 +03:00
}
// ToLabelList converts list of Label to API format
2021-12-10 04:27:50 +03:00
func ToLabelList ( labels [ ] * models . Label , repo * repo_model . Repository , org * user_model . User ) [ ] * api . Label {
2020-02-29 05:49:50 +03:00
result := make ( [ ] * api . Label , len ( labels ) )
for i := range labels {
2021-09-10 19:03:16 +03:00
result [ i ] = ToLabel ( labels [ i ] , repo , org )
2020-02-29 05:49:50 +03:00
}
return result
}
2020-05-13 00:54:35 +03:00
// ToAPIMilestone converts Milestone into API Format
func ToAPIMilestone ( m * models . Milestone ) * api . Milestone {
apiMilestone := & api . Milestone {
ID : m . ID ,
State : m . State ( ) ,
Title : m . Name ,
Description : m . Content ,
OpenIssues : m . NumOpenIssues ,
ClosedIssues : m . NumClosedIssues ,
2020-09-05 20:38:54 +03:00
Created : m . CreatedUnix . AsTime ( ) ,
Updated : m . UpdatedUnix . AsTimePtr ( ) ,
2020-05-13 00:54:35 +03:00
}
if m . IsClosed {
apiMilestone . Closed = m . ClosedDateUnix . AsTimePtr ( )
}
if m . DeadlineUnix . Year ( ) < 9999 {
apiMilestone . Deadline = m . DeadlineUnix . AsTimePtr ( )
}
return apiMilestone
}