github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/api/pipelineserver/list_builds.go (about) 1 package pipelineserver 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strconv" 8 9 "github.com/pf-qiu/concourse/v6/atc" 10 "github.com/pf-qiu/concourse/v6/atc/api/present" 11 "github.com/pf-qiu/concourse/v6/atc/db" 12 ) 13 14 func (s *Server) ListPipelineBuilds(pipeline db.Pipeline) http.Handler { 15 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 16 var ( 17 err error 18 from int 19 to int 20 limit int 21 builds []db.Build 22 pagination db.Pagination 23 ) 24 25 logger := s.logger.Session("list-pipeline-builds") 26 27 teamName := r.FormValue(":team_name") 28 timestamps := r.FormValue(atc.PaginationQueryTimestamps) 29 30 urlFrom := r.FormValue(atc.PaginationQueryFrom) 31 urlTo := r.FormValue(atc.PaginationQueryTo) 32 33 urlLimit := r.FormValue(atc.PaginationQueryLimit) 34 35 limit, _ = strconv.Atoi(urlLimit) 36 if limit == 0 { 37 limit = atc.PaginationAPIDefaultLimit 38 } 39 40 page := db.Page{Limit: limit} 41 if urlFrom != "" { 42 from, _ = strconv.Atoi(urlFrom) 43 page.From = db.NewIntPtr(from) 44 } 45 if urlTo != "" { 46 to, _ = strconv.Atoi(urlTo) 47 page.To = db.NewIntPtr(to) 48 } 49 50 if timestamps == "" { 51 builds, pagination, err = pipeline.Builds(page) 52 if err != nil { 53 logger.Error("failed-to-get-pipeline-builds", err) 54 w.WriteHeader(http.StatusNotFound) 55 return 56 } 57 } else { 58 page.UseDate = true 59 builds, pagination, err = pipeline.BuildsWithTime(page) 60 if err != nil { 61 logger.Error("failed-to-get-pipeline-builds-in-range", err) 62 w.WriteHeader(http.StatusNotFound) 63 return 64 } 65 } 66 67 pipelineRef := atc.PipelineRef{ 68 Name: pipeline.Name(), 69 InstanceVars: pipeline.InstanceVars(), 70 } 71 if pagination.Older != nil { 72 s.addNextLink(w, teamName, pipelineRef, *pagination.Older) 73 } 74 75 if pagination.Newer != nil { 76 s.addPreviousLink(w, teamName, pipelineRef, *pagination.Newer) 77 } 78 79 w.Header().Set("Content-Type", "application/json") 80 w.WriteHeader(http.StatusOK) 81 82 atc := make([]atc.Build, len(builds)) 83 for i := 0; i < len(builds); i++ { 84 build := builds[i] 85 atc[i] = present.Build(build) 86 } 87 88 err = json.NewEncoder(w).Encode(atc) 89 if err != nil { 90 logger.Error("failed-to-encode-builds", err) 91 w.WriteHeader(http.StatusInternalServerError) 92 } 93 }) 94 } 95 96 func (s *Server) addNextLink(w http.ResponseWriter, teamName string, pipelineRef atc.PipelineRef, page db.Page) { 97 if pipelineRef.InstanceVars != nil { 98 w.Header().Add("Link", fmt.Sprintf( 99 `<%s/api/v1/teams/%s/pipelines/%s/builds?%s=%d&%s=%d&%s>; rel="%s"`, 100 s.externalURL, 101 teamName, 102 pipelineRef.Name, 103 atc.PaginationQueryTo, 104 *page.To, 105 atc.PaginationQueryLimit, 106 page.Limit, 107 pipelineRef.QueryParams().Encode(), 108 atc.LinkRelNext, 109 )) 110 } else { 111 w.Header().Add("Link", fmt.Sprintf( 112 `<%s/api/v1/teams/%s/pipelines/%s/builds?%s=%d&%s=%d>; rel="%s"`, 113 s.externalURL, 114 teamName, 115 pipelineRef.Name, 116 atc.PaginationQueryTo, 117 *page.To, 118 atc.PaginationQueryLimit, 119 page.Limit, 120 atc.LinkRelNext, 121 )) 122 } 123 } 124 125 func (s *Server) addPreviousLink(w http.ResponseWriter, teamName string, pipelineRef atc.PipelineRef, page db.Page) { 126 if pipelineRef.InstanceVars != nil { 127 w.Header().Add("Link", fmt.Sprintf( 128 `<%s/api/v1/teams/%s/pipelines/%s/builds?%s=%d&%s=%d&%s>; rel="%s"`, 129 s.externalURL, 130 teamName, 131 pipelineRef.Name, 132 atc.PaginationQueryFrom, 133 *page.From, 134 atc.PaginationQueryLimit, 135 page.Limit, 136 pipelineRef.QueryParams().Encode(), 137 atc.LinkRelPrevious, 138 )) 139 } else { 140 w.Header().Add("Link", fmt.Sprintf( 141 `<%s/api/v1/teams/%s/pipelines/%s/builds?%s=%d&%s=%d>; rel="%s"`, 142 s.externalURL, 143 teamName, 144 pipelineRef.Name, 145 atc.PaginationQueryFrom, 146 *page.From, 147 atc.PaginationQueryLimit, 148 page.Limit, 149 atc.LinkRelPrevious, 150 )) 151 } 152 }