package handler
import (
"net/http"
"time"
"github.com/drone/drone/server/database"
"github.com/drone/drone/shared/model"
"github.com/gorilla/pat"
)
// badges that indicate the current build status for a repository
// and branch combination.
var (
badgeSuccess = []byte(``)
badgeFailure = []byte(``)
badgeStarted = []byte(``)
badgeError = []byte(``)
badgeNone = []byte(``)
)
type BadgeHandler struct {
commits database.CommitManager
repos database.RepoManager
}
func NewBadgeHandler(repos database.RepoManager, commits database.CommitManager) *BadgeHandler {
return &BadgeHandler{commits, repos}
}
// GetStatus gets the build status badge.
// GET /v1/badge/:host/:owner/:name/status.svg
func (h *BadgeHandler) GetStatus(w http.ResponseWriter, r *http.Request) error {
host, owner, name := parseRepo(r)
branch := r.FormValue("branch")
// github has insanely aggressive caching so we'll set almost
// every parameter possible to try to prevent caching.
w.Header().Set("Content-Type", "image/svg+xml")
w.Header().Add("Cache-Control", "no-cache")
w.Header().Add("Cache-Control", "no-store")
w.Header().Add("Cache-Control", "max-age=0")
w.Header().Add("Cache-Control", "must-revalidate")
w.Header().Add("Cache-Control", "value")
w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
w.Header().Set("Expires", "Thu, 01 Jan 1970 00:00:00 GMT")
// get the repository from the database
arepo, err := h.repos.FindName(host, owner, name)
if err != nil {
w.Write(badgeNone)
return nil
}
// if no branch, use the default
if len(branch) == 0 {
branch = model.DefaultBranch
}
// get the latest commit
c, _ := h.commits.FindLatest(arepo.ID, branch)
// if no commit was found then display
// the 'none' badge
if c == nil {
w.Write(badgeNone)
return nil
}
// determine which badge to load
switch c.Status {
case model.StatusSuccess:
w.Write(badgeSuccess)
case model.StatusFailure:
w.Write(badgeFailure)
case model.StatusError:
w.Write(badgeError)
case model.StatusEnqueue, model.StatusStarted:
w.Write(badgeStarted)
default:
w.Write(badgeNone)
}
return nil
}
// GetCoverage gets the build status badge.
// GET /v1/badges/:host/:owner/:name/coverage.svg
func (h *BadgeHandler) GetCoverage(w http.ResponseWriter, r *http.Request) error {
return notImplemented{}
}
func (h *BadgeHandler) GetCC(w http.ResponseWriter, r *http.Request) error {
return notImplemented{}
}
func (h *BadgeHandler) Register(r *pat.Router) {
r.Get("/v1/badge/{host}/{owner}/{name}/coverage.svg", errorHandler(h.GetCoverage))
r.Get("/v1/badge/{host}/{owner}/{name}/status.svg", errorHandler(h.GetStatus))
r.Get("/v1/badge/{host}/{owner}/{name}/cc.xml", errorHandler(h.GetCC))
}