/usr/bin/nd_popcon2stats is in neurodebian-dev 0.37.6.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | #!/usr/bin/python
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
#
import fileinput
import sys
import time
from datetime import datetime
import re
import json
import operator
# Bleh: not used
releases = {
'etch': 'Debian GNU/Linux 4.0 (etch)',
'lenny': 'Debian GNU/Linux 5.0 (lenny)',
'squeeze': 'Debian GNU/Linux 6.0 (squeeze)',
'wheezy': 'Debian GNU/Linux 7.0 (wheezy)',
'jessie': 'Debian GNU/Linux 8.0 (jessie)',
'stretch': 'Debian testing (stretch)',
'sid': 'Debian unstable (sid)',
'hardy': 'Ubuntu 08.04 LTS "Hardy Heron" (hardy)',
'jaunty': 'Ubuntu 09.04 "Jaunty Jackalope" (jaunty)',
'karmic': 'Ubuntu 09.10 "Karmic Koala" (karmic)',
'lucid': 'Ubuntu 10.04 LTS "Lucid Lynx" (lucid)',
'maverick': 'Ubuntu 10.10 "Maverick Meerkat" (maverick)',
'natty': 'Ubuntu 11.04 "Natty Narwhal" (natty)',
'oneiric': 'Ubuntu 11.10 "Oneiric Ocelot" (oneiric)',
'precise': 'Ubuntu 12.04 LTS "Precise Pangolin" (precise)',
'quantal': 'Ubuntu 12.10 "Quantal Quetzal" (quantal)',
'raring': 'Ubuntu 13.04 "Raring Ringtail" (raring)',
'saucy': 'Ubuntu 13.10 "Saucy Salamander" (saucy)',
'trusty': 'Ubuntu 14.04 LTS "Trusty Tahr" (trusty)',
'utopic': 'Ubuntu 14.10 "Utopic Unicorn" (utopic)',
'vivid': 'Ubuntu 15.04 "Vivid Vervet" (vivid)',
'wily': 'Ubuntu 15.10 "Wily Werewolf" (wily)',
'xenial': 'Ubuntu 16.04 "Xenial Xerus" (xenial)',
'yakkety': 'Ubuntu 16.10 "Yakkety Yak" (yakkety)',
}
def error(msg):
sys.stderr.write('E: %s\n' % msg)
def info(msg):
# print nothing ATM
# sys.stderr.write("I: %s\n" % msg)
pass
file_regex = re.compile('.*popcon-(\d{4}-\d{1,2}-\d{1,2})(|.gz)')
def read_popcon_stats(filename, read_packages=True):
info("Reading %s" % filename)
entry = dict(submissions = None,
package = {},
release = {},
architecture = {},
vendor = {})
for line in fileinput.FileInput(filename, openhook=fileinput.hook_compressed):
key, values = [x.strip().lower() for x in line.split(':', 1)]
if key == 'package': # most probable
if not read_packages:
break
try:
pkg, vote, old, recent, nofiles = values.split()
except ValueError:
raise ValueError("Failed to split %s" % values)
entry[key][pkg] = tuple(int(x) for x in (vote, old, recent, nofiles))
elif key in ('release', 'architecture', 'vendor'):
kvalue, value = values.split()
entry[key][kvalue] = int(value)
elif key == 'submissions':
entry[key] = int(values)
else:
raise ValueError("Do not know how to handle line %r" % line)
return entry
if __name__ == '__main__':
data = {}
popcon_versions = {}
timestamps = set()
for f in sys.argv[1:]:
file_reg = file_regex.match(f)
if not file_reg:
error("Failed to recognize filename %s" % f)
continue
date = time.strptime(file_reg.groups()[0], '%Y-%m-%d')
entry = read_popcon_stats(f, read_packages=False)
date_int = int(time.mktime(date)*1000)
# Let's coarsen a bit -- to a week which makes sense anyways
# since popcon submissions are spread over a week for balanced
# load
coarsen_days = 7
coarsen = coarsen_days*24*3600*1000
# coarsen and place marker at the end of the duration
# but not later than today
date_int = min((date_int//coarsen + 1)*coarsen,
time.time()*1000)
for version, count in entry['release'].iteritems():
if not version in popcon_versions:
popcon_versions[version] = {}
popcon_ = popcon_versions[version]
popcon_[date_int] = count + popcon_.get(date_int, 0)
timestamps.add(date_int)
versions = sorted([x for x in popcon_versions.keys() if not 'ubuntu' in x]) + \
sorted([x for x in popcon_versions.keys() if 'ubuntu' in x])
# we need to make sure that for every date we have an entry for
# every version, otherwise d3 pukes because of ... d3.v2.js:expand
export = [{'key': k,
'values': [[date, popcon_versions[k].get(date, 0)/coarsen_days]
for date in sorted(list(timestamps))]}
for k in versions]
print json.dumps(export)
|