1
0
Fork 0
mirror of https://github.com/Luzifer/badge-gen.git synced 2024-12-20 16:41:16 +00:00

add GitHub downloads integration

This commit is contained in:
Knut Ahlers 2016-07-07 01:25:09 +02:00
parent 5eb8fb0286
commit 88dc545477
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
3 changed files with 142 additions and 3 deletions

17
metric.go Normal file
View file

@ -0,0 +1,17 @@
package main
import (
"fmt"
"math"
)
func metricFormat(in int64) string {
siUnits := []string{"k", "M", "G", "T", "P", "E"}
for i := len(siUnits) - 1; i >= 0; i-- {
p := int64(math.Pow(1000, float64(i+1)))
if in >= p {
return fmt.Sprintf("%d%s", in/p, siUnits[i])
}
}
return fmt.Sprintf("%d", in)
}

20
metric_test.go Normal file
View file

@ -0,0 +1,20 @@
package main
import "testing"
func TestMetricFormat(t *testing.T) {
cases := map[int64]string{
1000: "1k",
1234: "1k",
10023: "10k",
100000: "100k",
1000000: "1M",
1023555: "1M",
6012355: "6M",
}
for v, r := range cases {
if cr := metricFormat(v); cr != r {
t.Errorf("Metric format of number %d did not match '%s': '%s'", v, r, cr)
}
}
}

View file

@ -16,6 +16,16 @@ func init() {
registerServiceHandler("github", githubServiceHandler{}) registerServiceHandler("github", githubServiceHandler{})
} }
type githubRelease struct {
TagName string `json:"tag_name"`
Assets []githubAsset `json:"assets"`
}
type githubAsset struct {
Name string `json:"name"`
Downloads int64 `json:"download_count"`
}
type githubServiceHandler struct{} type githubServiceHandler struct{}
func (g githubServiceHandler) GetDocumentation() serviceHandlerDocumentationList { func (g githubServiceHandler) GetDocumentation() serviceHandlerDocumentationList {
@ -35,6 +45,21 @@ func (g githubServiceHandler) GetDocumentation() serviceHandlerDocumentationList
DemoPath: "/github/latest-release/lastpass/lastpass-cli", DemoPath: "/github/latest-release/lastpass/lastpass-cli",
Arguments: []string{"latest-release", "<user>", "<repo>"}, Arguments: []string{"latest-release", "<user>", "<repo>"},
}, },
{
ServiceName: "GitHub downloads by repo",
DemoPath: "/github/downloads/atom/atom",
Arguments: []string{"downloads", "<user>", "<repo>"},
},
{
ServiceName: "GitHub downloads by release",
DemoPath: "/github/downloads/atom/atom/latest",
Arguments: []string{"downloads", "<user>", "<repo>", "<tag or \"latest\">"},
},
{
ServiceName: "GitHub downloads by release and asset",
DemoPath: "/github/downloads/atom/atom/v1.8.0/atom-amd64.deb",
Arguments: []string{"downloads", "<user>", "<repo>", "<tag or \"latest\">", "<asset>"},
},
} }
} }
@ -51,6 +76,8 @@ func (g githubServiceHandler) Handle(ctx context.Context, params []string) (titl
title, text, color, err = g.handleLatestTag(ctx, params[1:]) title, text, color, err = g.handleLatestTag(ctx, params[1:])
case "latest-release": case "latest-release":
title, text, color, err = g.handleLatestRelease(ctx, params[1:]) title, text, color, err = g.handleLatestRelease(ctx, params[1:])
case "downloads":
title, text, color, err = g.handleDownloads(ctx, params[1:])
default: default:
err = errors.New("An unknown service command was called") err = errors.New("An unknown service command was called")
} }
@ -58,15 +85,90 @@ func (g githubServiceHandler) Handle(ctx context.Context, params []string) (titl
return return
} }
func (g githubServiceHandler) handleDownloads(ctx context.Context, params []string) (title, text, color string, err error) {
switch len(params) {
case 2:
title, text, color, err = g.handleRepoDownloads(ctx, params)
case 3:
params = append(params, "total")
fallthrough
case 4:
title, text, color, err = g.handleReleaseDownloads(ctx, params)
default:
err = errors.New("Unsupported number of arguments")
}
return
}
func (g githubServiceHandler) handleReleaseDownloads(ctx context.Context, params []string) (title, text, color string, err error) {
path := strings.Join([]string{"repos", params[0], params[1], "releases", "tags", params[2]}, "/")
if params[2] == "latest" {
path = strings.Join([]string{"repos", params[0], params[1], "releases", params[2]}, "/")
}
text, err = cacheStore.Get("github_release_downloads", path)
if err != nil {
r := githubRelease{}
if err = g.fetchAPI(ctx, path, nil, &r); err != nil {
return
}
var sum int64
for _, rel := range r.Assets {
if params[3] == "total" || rel.Name == params[3] {
sum = sum + rel.Downloads
}
}
text = metricFormat(sum)
cacheStore.Set("github_release_downloads", path, text, 10*time.Minute)
}
title = "downloads"
color = "brightgreen"
return
}
func (g githubServiceHandler) handleRepoDownloads(ctx context.Context, params []string) (title, text, color string, err error) {
path := strings.Join([]string{"repos", params[0], params[1], "releases"}, "/")
text, err = cacheStore.Get("github_repo_downloads", path)
if err != nil {
r := []githubRelease{}
// TODO: This does not respect pagination!
if err = g.fetchAPI(ctx, path, nil, &r); err != nil {
return
}
var sum int64
for _, rel := range r {
for _, rea := range rel.Assets {
sum = sum + rea.Downloads
}
}
text = metricFormat(sum)
cacheStore.Set("github_repo_downloads", path, text, 10*time.Minute)
}
title = "downloads"
color = "brightgreen"
return
}
func (g githubServiceHandler) handleLatestRelease(ctx context.Context, params []string) (title, text, color string, err error) { func (g githubServiceHandler) handleLatestRelease(ctx context.Context, params []string) (title, text, color string, err error) {
path := strings.Join([]string{"repos", params[0], params[1], "releases", "latest"}, "/") path := strings.Join([]string{"repos", params[0], params[1], "releases", "latest"}, "/")
text, err = cacheStore.Get("github_latest_release", path) text, err = cacheStore.Get("github_latest_release", path)
if err != nil { if err != nil {
r := struct { r := githubRelease{}
TagName string `json:"tag_name"`
}{}
if err = g.fetchAPI(ctx, path, nil, &r); err != nil { if err = g.fetchAPI(ctx, path, nil, &r); err != nil {
return return