1
0
Fork 0
mirror of https://github.com/Luzifer/badge-gen.git synced 2024-11-09 13:50:03 +00:00

Add demo page with / route

This commit is contained in:
Knut Ahlers 2016-06-28 23:56:22 +02:00
parent 8fdea66933
commit cddda0944d
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
5 changed files with 428 additions and 31718 deletions

51
app.go
View file

@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net/http"
"sort"
"strings"
"text/template"
@ -25,12 +26,34 @@ var (
Port int64 `env:"PORT"`
Listen string `flag:"listen" default:":3000" description:"Port/IP to listen on"`
}{}
serviceHandlers = map[string]serviceHandlerFunction{}
serviceHandlers = map[string]serviceHandler{}
)
type serviceHandlerFunction func(params []string) (title, text, color string, err error)
type serviceHandlerDocumentation struct {
ServiceName string
DemoPath string
Arguments []string
Register string
}
func registerServiceHandler(service string, f serviceHandlerFunction) error {
func (s serviceHandlerDocumentation) DocFormat() string {
return "/" + s.Register + "/" + strings.Join(s.Arguments, "/")
}
type serviceHandlerDocumentationList []serviceHandlerDocumentation
func (s serviceHandlerDocumentationList) Len() int { return len(s) }
func (s serviceHandlerDocumentationList) Less(i, j int) bool {
return s[i].ServiceName < s[j].ServiceName
}
func (s serviceHandlerDocumentationList) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type serviceHandler interface {
GetDocumentation() serviceHandlerDocumentation
Handle(params []string) (title, text, color string, err error)
}
func registerServiceHandler(service string, f serviceHandler) error {
if _, ok := serviceHandlers[service]; ok {
return errors.New("Duplicate service handler")
}
@ -47,6 +70,7 @@ func main() {
r := mux.NewRouter()
r.HandleFunc("/v1/badge", generateBadge).Methods("GET")
r.HandleFunc("/{service}/{parameters:.*}", generateServiceBadge).Methods("GET")
r.HandleFunc("/", handleDemoPage)
http.ListenAndServe(cfg.Listen, r)
}
@ -62,7 +86,7 @@ func generateServiceBadge(res http.ResponseWriter, r *http.Request) {
return
}
title, text, color, err := handler(params)
title, text, color, err := handler.Handle(params)
if err != nil {
http.Error(res, "Error while executing service: "+err.Error(), http.StatusInternalServerError)
return
@ -136,3 +160,22 @@ func createBadge(title, text, color string) ([]byte, string) {
func generateETag(in []byte) string {
return fmt.Sprintf("%x", sha1.Sum(in))
}
func handleDemoPage(res http.ResponseWriter, r *http.Request) {
t, _ := Asset("assets/demoPage.tpl.html")
tpl, _ := template.New("demoPage").Parse(string(t))
examples := serviceHandlerDocumentationList{}
for register, handler := range serviceHandlers {
tmp := handler.GetDocumentation()
tmp.Register = register
examples = append(examples, tmp)
}
sort.Sort(examples)
tpl.Execute(res, map[string]interface{}{
"Examples": examples,
})
}

81
assets/demoPage.tpl.html Normal file
View file

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="//bootswatch.com/flatly/bootstrap.min.css" rel="stylesheet">
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
<style>
.block {
background-color: #f9f9f9;
margin-bottom: 30px;
margin-top: 30px;
padding: 30px 0;
text-align: center;
}
.footnote {
font-size: 0.9em;
}
.red {
color: #c7254e;
}
h1 {
margin-bottom: 20px;
}
</style>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 block">
<h1><code>badge-gen</code> Demo</h1>
<p>
The path formats contains elements in <code>&lt;angle&gt;</code> and <code>[square]</code> brackets. All elements in angle brackets are mandantory while those in square brackets are optional. Colors need to be specified as 3 or 6 character hex codes (for example <code>4c1</code> or <code>e05d44</code>). Text needs to be URL encoded.
</p>
</div>
</div> <!-- ./row -->
<div class="row">
<div class="col-md-12">
<table class="table table-striped">
<tr><th>Service</th><th>Example</th><th>Path Format</th></tr>
{{ range .Examples }}
<tr><th>{{ .ServiceName }}</th><td><img src="{{ .DemoPath }}"></td><td><code>{{ .DocFormat | html }}</code></td></tr>
{{ end }}
</table>
</div>
</div> <!-- ./row -->
<div class="row">
<div class="col-md-8 col-md-offset-2 block">
<p class="footnote">
Made with <i class="fa fa-heart red"></i> and Go by <a href="https://luzifer.io/">Knut Ahlers</a>
</p>
</div>
</div> <!-- ./row -->
</div> <!-- ./container -->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
<a href="https://github.com/Luzifer/badge-gen" class="github-corner"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#64CEAA; color:#fff; position: absolute; top: 0; border: 0; right: 0;"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
</body>
</html>

31872
bindata.go

File diff suppressed because one or more lines are too long

View file

@ -3,19 +3,31 @@ package main
import "errors"
func init() {
registerServiceHandler("static", func(params []string) (title, text, color string, err error) {
if len(params) < 2 {
err = errors.New("You need to provide title and text")
return
}
if len(params) < 3 {
params = append(params, defaultColor)
}
title = params[0]
text = params[1]
color = params[2]
return
})
registerServiceHandler("static", staticServiceHandler{})
}
type staticServiceHandler struct{}
func (s staticServiceHandler) GetDocumentation() serviceHandlerDocumentation {
return serviceHandlerDocumentation{
ServiceName: "Static Badge",
DemoPath: "/static/API/Documentation/4c1",
Arguments: []string{"<title>", "<text>", "[color]"},
}
}
func (s staticServiceHandler) Handle(params []string) (title, text, color string, err error) {
if len(params) < 2 {
err = errors.New("You need to provide title and text")
return
}
if len(params) < 3 {
params = append(params, defaultColor)
}
title = params[0]
text = params[1]
color = params[2]
return
}

View file

@ -8,48 +8,60 @@ import (
)
func init() {
registerServiceHandler("travis", func(params []string) (title, text, color string, err error) {
if len(params) < 2 {
err = errors.New("You need to provide user and repo")
return
}
if len(params) < 3 {
params = append(params, "master")
}
path := strings.Join([]string{"repos", params[0], params[1], "branches", params[2]}, "/")
var resp *http.Response
resp, err = http.Get("https://api.travis-ci.org/" + path)
if err != nil {
return
}
defer resp.Body.Close()
r := struct {
File string `json:"file"`
Branch struct {
State string `json:"state"`
} `json:"branch"`
}{}
if err = json.NewDecoder(resp.Body).Decode(&r); err != nil {
return
}
title = "travis"
text = r.Branch.State
if text == "" {
text = "unknown"
}
color = map[string]string{
"unknown": "9f9f9f",
"passed": "4c1",
"failed": "e05d44",
"canceled": "9f9f9f",
}[text]
return
})
registerServiceHandler("travis", travisServiceHandler{})
}
type travisServiceHandler struct{}
func (t travisServiceHandler) GetDocumentation() serviceHandlerDocumentation {
return serviceHandlerDocumentation{
ServiceName: "Travis-CI",
DemoPath: "/travis/Luzifer/password",
Arguments: []string{"<user>", "<repo>", "[branch]"},
}
}
func (t travisServiceHandler) Handle(params []string) (title, text, color string, err error) {
if len(params) < 2 {
err = errors.New("You need to provide user and repo")
return
}
if len(params) < 3 {
params = append(params, "master")
}
path := strings.Join([]string{"repos", params[0], params[1], "branches", params[2]}, "/")
var resp *http.Response
resp, err = http.Get("https://api.travis-ci.org/" + path)
if err != nil {
return
}
defer resp.Body.Close()
r := struct {
File string `json:"file"`
Branch struct {
State string `json:"state"`
} `json:"branch"`
}{}
if err = json.NewDecoder(resp.Body).Decode(&r); err != nil {
return
}
title = "travis"
text = r.Branch.State
if text == "" {
text = "unknown"
}
color = map[string]string{
"unknown": "9f9f9f",
"passed": "4c1",
"failed": "e05d44",
"canceled": "9f9f9f",
}[text]
return
}