1#! /usr/bin/env python3
3""" Produces a set of graphs of NEW/BYHAND/DEFERRED
5@contact: Debian FTPMaster <ftpmaster@debian.org>
6@copyright: 2011 Paul Wise <pabs@debian.org>
7"""
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23import os
24import sys
25import colorsys
27import rrdtool
28import apt_pkg
30from daklib import utils
32Cnf = None
33default_names = ["byhand", "new", "deferred"]
35################################################################################
38def usage(exit_code=0):
39 print("""Usage: dak graph
40Graphs the number of packages in queue directories (usually new and byhand).
42 -h, --help show this help and exit.
43 -r, --rrd=key Directory where rrd files to be updated are stored
44 -x, --extra-rrd=key File containing extra options to rrdtool graphing
45 -i, --images=key Directory where image graphs to be updated are stored
46 -n, --names=key A comma separated list of rrd files to be scanned
48""")
49 sys.exit(exit_code)
51################################################################################
54def graph(*args):
55 if args[2] == "deferred":
56 graph_deferred(*args)
57 else:
58 graph_normal(*args)
61def deferred_colours():
62 colours = [0] * 16
63 for i in range(0, 16):
64 colours[i] = colorsys.hsv_to_rgb(i / 16.0, 1.0, 0.5 + i / 32.0)
65 colours[i] = ''.join('%02X' % int(c * 255) for c in colours[i])
66 return colours
69colours = deferred_colours()
72def graph_deferred(rrd_dir, image_dir, name, extra_args, graph, title, start, year_lines=False):
73 image_file = os.path.join(image_dir, "%s-%s.png" % (name, graph))
74 rrd_file = os.path.join(rrd_dir, "%s.rrd" % name)
75 rrd_args = [image_file, "--start", start]
76 rrd_args += ("""
77--end
78now
79--width
80600
81--height
82150
83--vertical-label
84changes
85--title
86%s changes count for the last %s
87--lower-limit
880
89-E
90""" % (name.upper(), title)).strip().split("\n")
92 if year_lines:
93 rrd_args += ["--x-grid", "MONTH:1:YEAR:1:YEAR:1:31536000:%Y"]
95 for i in range(0, 16):
96 rrd_args += ("""
97DEF:d%i=%s:day%i:AVERAGE
98AREA:d%i#%s:%i-day changes count:STACK
99VDEF:ld%i=d%i,LAST
100VDEF:mind%i=d%i,MINIMUM
101VDEF:maxd%i=d%i,MAXIMUM
102VDEF:avgd%i=d%i,AVERAGE
103GPRINT:ld%i:cur\\: %%.0lf
104GPRINT:mind%i:min\\: %%.0lf
105GPRINT:maxd%i:max\\: %%.0lf
106GPRINT:avgd%i:avg\\: %%.0lf\\j
107""" % ((i, rrd_file, i, i, colours[i]) + (i,) * 13)).strip().split("\n")
109 rrd_args += extra_args
110 try:
111 ret = rrdtool.graph(*rrd_args)
112 except rrdtool.error as e:
113 print(('warning: graph: rrdtool error, skipping %s-%s.png: %s' % (name, graph, e)))
116def graph_normal(rrd_dir, image_dir, name, extra_args, graph, title, start, year_lines=False):
117 image_file = os.path.join(image_dir, "%s-%s.png" % (name, graph))
118 rrd_file = os.path.join(rrd_dir, "%s.rrd" % name)
119 rrd_args = [image_file, "--start", start]
120 rrd_args += ("""
121--end
122now
123--width
124600
125--height
126150
127--vertical-label
128packages
129--title
130%s package count for the last %s
131--lower-limit
1320
133-E
134""" % (name.upper(), title)).strip().split("\n")
136 if year_lines:
137 rrd_args += ["--x-grid", "MONTH:1:YEAR:1:YEAR:1:31536000:%Y"]
139 rrd_args += ("""
140DEF:ds1=%s:ds1:AVERAGE
141LINE2:ds1#D9382B:changes count
142VDEF:lds1=ds1,LAST
143VDEF:minds1=ds1,MINIMUM
144VDEF:maxds1=ds1,MAXIMUM
145VDEF:avgds1=ds1,AVERAGE
146GPRINT:lds1:cur\\: %%.0lf
147GPRINT:minds1:min\\: %%.0lf
148GPRINT:maxds1:max\\: %%.0lf
149GPRINT:avgds1:avg\\: %%.0lf\\j
150DEF:ds0=%s:ds0:AVERAGE
151VDEF:lds0=ds0,LAST
152VDEF:minds0=ds0,MINIMUM
153VDEF:maxds0=ds0,MAXIMUM
154VDEF:avgds0=ds0,AVERAGE
155LINE2:ds0#3069DA:src pkg count
156GPRINT:lds0:cur\\: %%.0lf
157GPRINT:minds0:min\\: %%.0lf
158GPRINT:maxds0:max\\: %%.0lf
159GPRINT:avgds0:avg\\: %%.0lf\\j
160""" % (rrd_file, rrd_file)).strip().split("\n")
162 rrd_args += extra_args
163 try:
164 ret = rrdtool.graph(*rrd_args)
165 except rrdtool.error as e:
166 print(('warning: graph: rrdtool error, skipping %s-%s.png: %s' % (name, graph, e)))
168################################################################################
171def main():
172 global Cnf
174 Cnf = utils.get_conf()
175 Arguments = [('h', "help", "Graph::Options::Help"),
176 ('x', "extra-rrd", "Graph::Options::Extra-Rrd", "HasArg"),
177 ('r', "rrd", "Graph::Options::Rrd", "HasArg"),
178 ('i', "images", "Graph::Options::Images", "HasArg"),
179 ('n', "names", "Graph::Options::Names", "HasArg")]
180 for i in ["help"]:
181 key = "Graph::Options::%s" % i
182 if key not in Cnf: 182 ↛ 180line 182 didn't jump to line 180, because the condition on line 182 was never false
183 Cnf[key] = ""
185 apt_pkg.parse_commandline(Cnf, Arguments, sys.argv)
187 Options = Cnf.subtree("Graph::Options")
188 if Options["Help"]: 188 ↛ 191line 188 didn't jump to line 191, because the condition on line 188 was never false
189 usage()
191 names = []
193 if "Graph::Options::Names" in Cnf:
194 for i in Cnf["Graph::Options::Names"].split(","):
195 names.append(i)
196 elif "Graph::Names" in Cnf:
197 names = Cnf.value_list("Graph::Names")
198 else:
199 names = default_names
201 extra_rrdtool_args = []
203 if "Graph::Options::Extra-Rrd" in Cnf:
204 for i in Cnf["Graph::Options::Extra-Rrd"].split(","):
205 with open(i) as f:
206 extra_rrdtool_args.extend(f.read().strip().split("\n"))
207 elif "Graph::Extra-Rrd" in Cnf:
208 for i in Cnf.value_list("Graph::Extra-Rrd"):
209 with open(i) as f:
210 extra_rrdtool_args.extend(f.read().strip().split("\n"))
212 if "Graph::Options::Rrd" in Cnf:
213 rrd_dir = Cnf["Graph::Options::Rrd"]
214 elif "Dir::Rrd" in Cnf:
215 rrd_dir = Cnf["Dir::Rrd"]
216 else:
217 print("No directory to read RRD files from\n", file=sys.stderr)
218 sys.exit(1)
220 if "Graph::Options::Images" in Cnf:
221 image_dir = Cnf["Graph::Options::Images"]
222 else:
223 print("No directory to write graph images to\n", file=sys.stderr)
224 sys.exit(1)
226 for name in names:
227 stdargs = [rrd_dir, image_dir, name, extra_rrdtool_args]
228 graph(*(stdargs + ['day', 'day', 'now-1d']))
229 graph(*(stdargs + ['week', 'week', 'now-1w']))
230 graph(*(stdargs + ['month', 'month', 'now-1m']))
231 graph(*(stdargs + ['year', 'year', 'now-1y']))
232 graph(*(stdargs + ['5years', '5 years', 'now-5y', True]))
233 graph(*(stdargs + ['10years', '10 years', 'now-10y', True]))
235################################################################################
238if __name__ == '__main__':
239 main()