cmd/ursrv: Summarize known distribution channels
That is, whether the binary was downloaded from GitHub, from our APT repository, etc.
This commit is contained in:
parent
c02aed0a21
commit
e16a65bacb
|
@ -24,10 +24,10 @@ type analyticList []analytic
|
||||||
|
|
||||||
func (l analyticList) Less(a, b int) bool {
|
func (l analyticList) Less(a, b int) bool {
|
||||||
if l[a].Key == "Others" {
|
if l[a].Key == "Others" {
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
if l[b].Key == "Others" {
|
if l[b].Key == "Others" {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
return l[b].Count < l[a].Count // inverse
|
return l[b].Count < l[a].Count // inverse
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,20 +33,36 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
useHTTP = os.Getenv("UR_USE_HTTP") != ""
|
useHTTP = os.Getenv("UR_USE_HTTP") != ""
|
||||||
debug = os.Getenv("UR_DEBUG") != ""
|
debug = os.Getenv("UR_DEBUG") != ""
|
||||||
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")
|
||||||
geoIPPath = getEnvDefault("UR_GEOIP", "GeoLite2-City.mmdb")
|
geoIPPath = getEnvDefault("UR_GEOIP", "GeoLite2-City.mmdb")
|
||||||
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@.-]+)`)
|
||||||
progressBarClass = []string{"", "progress-bar-success", "progress-bar-info", "progress-bar-warning", "progress-bar-danger"}
|
progressBarClass = []string{"", "progress-bar-success", "progress-bar-info", "progress-bar-warning", "progress-bar-danger"}
|
||||||
featureOrder = []string{"Various", "Folder", "Device", "Connection", "GUI"}
|
featureOrder = []string{"Various", "Folder", "Device", "Connection", "GUI"}
|
||||||
knownVersions = []string{"v2", "v3"}
|
knownVersions = []string{"v2", "v3"}
|
||||||
|
knownDistributions = []distributionMatch{
|
||||||
|
// Maps well known builders to the official distribution method that
|
||||||
|
// they represent
|
||||||
|
{regexp.MustCompile("android-.*teamcity@build.syncthing.net"), "Google Play"},
|
||||||
|
{regexp.MustCompile("teamcity@build.syncthing.net"), "GitHub"},
|
||||||
|
{regexp.MustCompile("deb@build.syncthing.net"), "APT"},
|
||||||
|
{regexp.MustCompile("docker@syncthing.net"), "Docker Hub"},
|
||||||
|
{regexp.MustCompile("jenkins@build.syncthing.net"), "GitHub"},
|
||||||
|
{regexp.MustCompile("snap@build.syncthing.net"), "Snappy"},
|
||||||
|
{regexp.MustCompile("."), "Others"},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type distributionMatch struct {
|
||||||
|
matcher *regexp.Regexp
|
||||||
|
distribution string
|
||||||
|
}
|
||||||
|
|
||||||
var funcs = map[string]interface{}{
|
var funcs = map[string]interface{}{
|
||||||
"commatize": commatize,
|
"commatize": commatize,
|
||||||
"number": number,
|
"number": number,
|
||||||
|
@ -1001,6 +1017,7 @@ func getReport(db *sql.DB) map[string]interface{} {
|
||||||
var uptime []int
|
var uptime []int
|
||||||
var compilers []string
|
var compilers []string
|
||||||
var builders []string
|
var builders []string
|
||||||
|
var distributions []string
|
||||||
locations := make(map[location]int)
|
locations := make(map[location]int)
|
||||||
countries := make(map[string]int)
|
countries := make(map[string]int)
|
||||||
|
|
||||||
|
@ -1070,10 +1087,19 @@ 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)
|
||||||
|
|
||||||
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])
|
||||||
|
loop:
|
||||||
|
for _, d := range knownDistributions {
|
||||||
|
if d.matcher.MatchString(rep.LongVersion) {
|
||||||
|
distributions = append(distributions, d.distribution)
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if rep.NumFolders > 0 {
|
if rep.NumFolders > 0 {
|
||||||
numFolders = append(numFolders, rep.NumFolders)
|
numFolders = append(numFolders, rep.NumFolders)
|
||||||
}
|
}
|
||||||
|
@ -1366,6 +1392,7 @@ func getReport(db *sql.DB) map[string]interface{} {
|
||||||
r["platforms"] = group(byPlatform, analyticsFor(platforms, 2000), 5)
|
r["platforms"] = group(byPlatform, analyticsFor(platforms, 2000), 5)
|
||||||
r["compilers"] = group(byCompiler, analyticsFor(compilers, 2000), 5)
|
r["compilers"] = group(byCompiler, analyticsFor(compilers, 2000), 5)
|
||||||
r["builders"] = analyticsFor(builders, 12)
|
r["builders"] = analyticsFor(builders, 12)
|
||||||
|
r["distributions"] = analyticsFor(distributions, 10)
|
||||||
r["featureOrder"] = featureOrder
|
r["featureOrder"] = featureOrder
|
||||||
r["locations"] = locations
|
r["locations"] = locations
|
||||||
r["contries"] = countryList
|
r["contries"] = countryList
|
||||||
|
|
|
@ -506,6 +506,27 @@ found in the LICENSE file.
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Distribution Channel</th>
|
||||||
|
<th class="text-right">Devices</th>
|
||||||
|
<th class="text-right">Share</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .distributions}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.Key}}</td>
|
||||||
|
<td class="text-right">{{.Count}}</td>
|
||||||
|
<td class="text-right">{{.Percentage | printf "%.01f"}}%</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
Loading…
Reference in New Issue