13 "github.com/stapelberg/godebiancontrol"
17 asciiMatch
= regexp
.MustCompile(`^(?P<package>[A-Za-z0-9-.+_]+)(:(?P<arch>[a-z0-9]+))?$`)
20 func popconInstallations(binaryPackages
[]godebiancontrol
.Paragraph
) (map[string]float32, error
) {
21 binaryToSource
:= make(map[string]string)
22 for _
, pkg
:= range binaryPackages
{
23 source
, ok
:= pkg
["Source"]
25 source
= pkg
["Package"]
27 idx
:= strings
.Index(source
, " ")
31 binaryToSource
[pkg
["Package"]] = source
34 installations
:= make(map[string]float32)
36 // Modeled after UDD’s popcon_gatherer.py:
37 // https://anonscm.debian.org/cgit/collab-qa/udd.git/tree/udd/popcon_gatherer.py?id=9db1e97eff32691f4df03d1b9ee8a9290a91fc7a
38 url
:= "http://popcon.debian.org/all-popcon-results.txt.gz"
39 resp
, err
:= http
.Get(url
)
43 if resp
.StatusCode
!= http
.StatusOK
{
44 return nil, fmt
.Errorf("HTTP Status %s for URL %q, expected OK", resp
.Status
, url
)
46 defer resp
.Body
.Close()
47 reader
, err
:= gzip
.NewReader(resp
.Body
)
51 scanner
:= bufio
.NewScanner(reader
)
53 line
:= scanner
.Text()
54 if !strings
.HasPrefix(line
, "Package: ") {
57 // line is e.g. “Package: 0ad 269 1380 121 4”
58 fields
:= strings
.Fields(line
)
59 // 2016/03/28 16:30:58 fields = ["Package:" "zyne" "16" "14" "3" "0"]
61 log
.Printf("Skipping line %q: expected %d fields, got %d\n", fields
, 6, len(fields
))
65 for _
, field
:= range fields
[2:] {
66 converted
, err
:= strconv
.ParseInt(field
, 0, 64)
68 log
.Printf("Could not convert field %q to integer: %v", field
, err
)
73 matches
:= asciiMatch
.FindStringSubmatch(fields
[1])
74 if len(matches
) == 0 {
76 fmt
.Printf("%q is not a valid package name, skipping\n", fields
[1])
80 binaryPackage
:= matches
[1]
82 sourcePackage
, ok
:= binaryToSource
[binaryPackage
]
85 fmt
.Printf("Could not find package %q in binary→source mapping, skipping\n", binaryPackage
)
89 installations
[sourcePackage
] += float32(insts
)
91 return installations
, scanner
.Err()