More details version/platform stats

This commit is contained in:
Jakob Borg 2016-05-30 09:52:38 +02:00
parent ed45c43033
commit 82621f250c
3 changed files with 107 additions and 54 deletions

View File

@ -1,16 +1,26 @@
package main package main
import "sort" import (
"sort"
"strings"
)
type analytic struct { type analytic struct {
Key string Key string
Count int Count int
Percentage float64 Percentage float64
Items []analytic `json:",omitempty"`
} }
type analyticList []analytic type analyticList []analytic
func (l analyticList) Less(a, b int) bool { func (l analyticList) Less(a, b int) bool {
if l[a].Key == "Others" {
return true
}
if l[b].Key == "Others" {
return false
}
return l[b].Count < l[a].Count // inverse return l[b].Count < l[a].Count // inverse
} }
@ -33,7 +43,11 @@ func analyticsFor(ss []string, cutoff int) []analytic {
l := make([]analytic, 0, len(m)) l := make([]analytic, 0, len(m))
for k, c := range m { for k, c := range m {
l = append(l, analytic{k, c, 100 * float64(c) / float64(t)}) l = append(l, analytic{
Key: k,
Count: c,
Percentage: 100 * float64(c) / float64(t),
})
} }
sort.Sort(analyticList(l)) sort.Sort(analyticList(l))
@ -43,7 +57,11 @@ func analyticsFor(ss []string, cutoff int) []analytic {
for _, i := range l[cutoff:] { for _, i := range l[cutoff:] {
c += i.Count c += i.Count
} }
l = append(l[:cutoff], analytic{"Others", c, 100 * float64(c) / float64(t)}) l = append(l[:cutoff], analytic{
Key: "Others",
Count: c,
Percentage: 100 * float64(c) / float64(t),
})
} }
return l return l
@ -76,3 +94,47 @@ func statsForFloats(data []float64) [4]float64 {
res[3] = data[len(data)-1] res[3] = data[len(data)-1]
return res return res
} }
func group(by func(string) string, as []analytic, perGroup int) []analytic {
var res []analytic
next:
for _, a := range as {
group := by(a.Key)
for i := range res {
if res[i].Key == group {
res[i].Count += a.Count
res[i].Percentage += a.Percentage
if len(res[i].Items) < perGroup {
res[i].Items = append(res[i].Items, a)
}
continue next
}
}
res = append(res, analytic{
Key: group,
Count: a.Count,
Percentage: a.Percentage,
Items: []analytic{a},
})
}
sort.Sort(analyticList(res))
return res
}
func byVersion(s string) string {
parts := strings.Split(s, ".")
if len(parts) >= 2 {
return strings.Join(parts[:2], ".")
}
return s
}
func byPlatform(s string) string {
parts := strings.Split(s, "-")
if len(parts) >= 2 {
return parts[0]
}
return s
}

View File

@ -22,13 +22,12 @@ import (
) )
var ( var (
keyFile = getEnvDefault("UR_KEY_FILE", "key.pem") keyFile = getEnvDefault("UR_KEY_FILE", "key.pem")
certFile = getEnvDefault("UR_CRT_FILE", "crt.pem") certFile = getEnvDefault("UR_CRT_FILE", "crt.pem")
dbConn = getEnvDefault("UR_DB_URL", "postgres://user:password@localhost/ur?sslmode=disable") dbConn = getEnvDefault("UR_DB_URL", "postgres://user:password@localhost/ur?sslmode=disable")
listenAddr = getEnvDefault("UR_LISTEN", "0.0.0.0:8443") listenAddr = getEnvDefault("UR_LISTEN", "0.0.0.0:8443")
tpl *template.Template tpl *template.Template
compilerRe = regexp.MustCompile(`\(([A-Za-z0-9()., -]+) \w+-\w+(?:| android| default)\) ([\w@.-]+)`) compilerRe = regexp.MustCompile(`\(([A-Za-z0-9()., -]+) \w+-\w+(?:| android| default)\) ([\w@.-]+)`)
aggregateVersions = []string{"v0.7", "v0.8", "v0.9", "v0.10", "v0.11"}
) )
var funcs = map[string]interface{}{ var funcs = map[string]interface{}{
@ -476,7 +475,6 @@ func getReport(db *sql.DB) map[string]interface{} {
nodes := 0 nodes := 0
var versions []string var versions []string
var platforms []string var platforms []string
var oses []string
var numFolders []int var numFolders []int
var numDevices []int var numDevices []int
var totFiles []int var totFiles []int
@ -540,8 +538,6 @@ func getReport(db *sql.DB) map[string]interface{} {
nodes++ nodes++
versions = append(versions, transformVersion(rep.Version)) versions = append(versions, transformVersion(rep.Version))
platforms = append(platforms, rep.Platform) platforms = append(platforms, rep.Platform)
ps := strings.Split(rep.Platform, "-")
oses = append(oses, ps[0])
if m := compilerRe.FindStringSubmatch(rep.LongVersion); len(m) == 3 { if m := compilerRe.FindStringSubmatch(rep.LongVersion); len(m) == 3 {
compilers = append(compilers, m[1]) compilers = append(compilers, m[1])
builders = append(builders, m[2]) builders = append(builders, m[2])
@ -739,9 +735,8 @@ func getReport(db *sql.DB) map[string]interface{} {
r["nodes"] = nodes r["nodes"] = nodes
r["v2nodes"] = v2Reports r["v2nodes"] = v2Reports
r["categories"] = categories r["categories"] = categories
r["versions"] = analyticsFor(versions, 10) r["versions"] = group(byVersion, analyticsFor(versions, 2000), 5)
r["platforms"] = analyticsFor(platforms, 0) r["platforms"] = group(byPlatform, analyticsFor(platforms, 2000), 5)
r["os"] = analyticsFor(oses, 0)
r["compilers"] = analyticsFor(compilers, 12) r["compilers"] = analyticsFor(compilers, 12)
r["builders"] = analyticsFor(builders, 12) r["builders"] = analyticsFor(builders, 12)
r["features"] = featureList r["features"] = featureList
@ -773,13 +768,6 @@ func transformVersion(v string) string {
return m[1] + " (+dev)" return m[1] + " (+dev)"
} }
// Truncate old versions to just the generation part
for _, agg := range aggregateVersions {
if strings.HasPrefix(v, agg) {
return agg + ".x"
}
}
return v return v
} }

View File

@ -22,6 +22,12 @@ found in the LICENSE file.
margin: 40px; margin: 40px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
} }
tr.main td {
font-weight: bold;
}
tr.child td.first {
padding-left: 2em;
}
</style> </style>
<script type="text/javascript" <script type="text/javascript"
src="https://www.google.com/jsapi?autoload={ src="https://www.google.com/jsapi?autoload={
@ -144,7 +150,7 @@ found in the LICENSE file.
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-6">
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
@ -153,17 +159,26 @@ found in the LICENSE file.
</thead> </thead>
<tbody> <tbody>
{{range .versions}} {{range .versions}}
<tr> {{if gt .Percentage 0.5}}
<td>{{.Key}}</td> <tr class="main">
<td class="text-right">{{.Count}}</td> <td>{{.Key}}</td>
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td> <td class="text-right">{{.Count}}</td>
</tr> <td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
</tr>
{{range .Items}}
<tr class="child">
<td class="first">{{.Key}}</td>
<td class="text-right">{{.Count}}</td>
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
</tr>
{{end}}
{{end}}
{{end}} {{end}}
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="col-md-4"> <div class="col-md-6">
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
@ -172,30 +187,18 @@ found in the LICENSE file.
</thead> </thead>
<tbody> <tbody>
{{range .platforms}} {{range .platforms}}
<tr> <tr class="main">
<td>{{.Key}}</td> <td>{{.Key}}</td>
<td class="text-right">{{.Count}}</td> <td class="text-right">{{.Count}}</td>
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td> <td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
</tr> </tr>
{{end}} {{range .Items}}
</tbody> <tr class="child">
</table> <td class="first">{{.Key}}</td>
</div> <td class="text-right">{{.Count}}</td>
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
<div class="col-md-4"> </tr>
<table class="table table-striped"> {{end}}
<thead>
<tr>
<th>OS</th><th class="text-right">Devices</th><th class="text-right">Share</th>
</tr>
</thead>
<tbody>
{{range .os}}
<tr>
<td>{{.Key}}</td>
<td class="text-right">{{.Count}}</td>
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
</tr>
{{end}} {{end}}
</tbody> </tbody>
</table> </table>