package handler
import (
"encoding/xml"
"net/http"
"github.com/drone/drone/server/datastore"
"github.com/drone/drone/shared/httputil"
"github.com/drone/drone/shared/model"
"github.com/goji/context"
"github.com/zenazn/goji/web"
)
// badges that indicate the current build status for a repository
// and branch combination.
type badge struct {
success, failure, started, err, none []byte
}
var defaultBadge = badge{
[]byte(``),
[]byte(``),
[]byte(``),
[]byte(``),
[]byte(``),
}
var badgeStyles = map[string]badge{
"flat": badge{
[]byte(``),
[]byte(``),
[]byte(``),
[]byte(``),
[]byte(``),
},
"flat-square": badge{
[]byte(``),
[]byte(``),
[]byte(``),
[]byte(``),
[]byte(``),
},
}
// GetBadge accepts a request to retrieve the named
// repo and branhes latest build details from the datastore
// and return an SVG badges representing the build results.
//
// GET /api/badge/:host/:owner/:name/status.svg
//
func GetBadge(c web.C, w http.ResponseWriter, r *http.Request) {
var ctx = context.FromC(c)
var (
host = c.URLParams["host"]
owner = c.URLParams["owner"]
name = c.URLParams["name"]
branch = r.FormValue("branch")
style = r.FormValue("style")
)
// an SVG response is always served, even when error, so
// we can go ahead and set the content type appropriately.
w.Header().Set("Content-Type", "image/svg+xml")
badge, ok := badgeStyles[style]
if !ok {
badge = defaultBadge
}
repo, err := datastore.GetRepoName(ctx, host, owner, name)
if err != nil {
w.Write(badge.none)
return
}
if len(branch) == 0 {
branch = model.DefaultBranch
}
commit, _ := datastore.GetCommitLast(ctx, repo, branch)
// if no commit was found then display
// the 'none' badge, instead of throwing
// an error response
if commit == nil {
w.Write(badge.none)
return
}
switch commit.Status {
case model.StatusSuccess:
w.Write(badge.success)
case model.StatusFailure:
w.Write(badge.failure)
case model.StatusError:
w.Write(badge.err)
case model.StatusEnqueue, model.StatusStarted:
w.Write(badge.started)
default:
w.Write(badge.none)
}
}
// GetCC accepts a request to retrieve the latest build
// status for the given repository from the datastore and
// in CCTray XML format.
//
// GET /api/badge/:host/:owner/:name/cc.xml
//
func GetCC(c web.C, w http.ResponseWriter, r *http.Request) {
var ctx = context.FromC(c)
var (
host = c.URLParams["host"]
owner = c.URLParams["owner"]
name = c.URLParams["name"]
)
w.Header().Set("Content-Type", "application/xml")
repo, err := datastore.GetRepoName(ctx, host, owner, name)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
commits, err := datastore.GetCommitList(ctx, repo, 1, 0)
if err != nil || len(commits) == 0 {
w.WriteHeader(http.StatusNotFound)
return
}
var link = httputil.GetURL(r) + "/" + repo.Host + "/" + repo.Owner + "/" + repo.Name
var cc = model.NewCC(repo, commits[0], link)
xml.NewEncoder(w).Encode(cc)
}