1#! /usr/bin/env python3 

2 

3"""Produces a set of graphs of NEW/BYHAND/DEFERRED 

4 

5@contact: Debian FTPMaster <ftpmaster@debian.org> 

6@copyright: 2011 Paul Wise <pabs@debian.org> 

7""" 

8 

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. 

13 

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. 

18 

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 

22 

23import colorsys 

24import os 

25import sys 

26 

27import apt_pkg 

28import rrdtool 

29 

30from daklib import utils 

31 

32Cnf = None 

33default_names = ["byhand", "new", "deferred"] 

34 

35################################################################################ 

36 

37 

38def usage(exit_code=0): 

39 print( 

40 """Usage: dak graph 

41Graphs the number of packages in queue directories (usually new and byhand). 

42 

43 -h, --help show this help and exit. 

44 -r, --rrd=key Directory where rrd files to be updated are stored 

45 -x, --extra-rrd=key File containing extra options to rrdtool graphing 

46 -i, --images=key Directory where image graphs to be updated are stored 

47 -n, --names=key A comma separated list of rrd files to be scanned 

48 

49""" 

50 ) 

51 sys.exit(exit_code) 

52 

53 

54################################################################################ 

55 

56 

57def graph(*args): 

58 if args[2] == "deferred": 

59 graph_deferred(*args) 

60 else: 

61 graph_normal(*args) 

62 

63 

64def deferred_colours(): 

65 colours = [0] * 16 

66 for i in range(0, 16): 

67 colours[i] = colorsys.hsv_to_rgb(i / 16.0, 1.0, 0.5 + i / 32.0) 

68 colours[i] = "".join("%02X" % int(c * 255) for c in colours[i]) 

69 return colours 

70 

71 

72colours = deferred_colours() 

73 

74 

75def graph_deferred( 

76 rrd_dir, image_dir, name, extra_args, graph, title, start, year_lines=False 

77): 

78 image_file = os.path.join(image_dir, "%s-%s.png" % (name, graph)) 

79 rrd_file = os.path.join(rrd_dir, "%s.rrd" % name) 

80 rrd_args = [image_file, "--start", start] 

81 rrd_args += ( 

82 ( 

83 """ 

84--end 

85now 

86--width 

87600 

88--height 

89150 

90--vertical-label 

91changes 

92--title 

93%s changes count for the last %s 

94--lower-limit 

950 

96-E 

97""" 

98 % (name.upper(), title) 

99 ) 

100 .strip() 

101 .split("\n") 

102 ) 

103 

104 if year_lines: 

105 rrd_args += ["--x-grid", "MONTH:1:YEAR:1:YEAR:1:31536000:%Y"] 

106 

107 for i in range(0, 16): 

108 rrd_args += ( 

109 ( 

110 """ 

111DEF:d%i=%s:day%i:AVERAGE 

112AREA:d%i#%s:%i-day changes count:STACK 

113VDEF:ld%i=d%i,LAST 

114VDEF:mind%i=d%i,MINIMUM 

115VDEF:maxd%i=d%i,MAXIMUM 

116VDEF:avgd%i=d%i,AVERAGE 

117GPRINT:ld%i:cur\\: %%.0lf 

118GPRINT:mind%i:min\\: %%.0lf 

119GPRINT:maxd%i:max\\: %%.0lf 

120GPRINT:avgd%i:avg\\: %%.0lf\\j 

121""" 

122 % ((i, rrd_file, i, i, colours[i]) + (i,) * 13) 

123 ) 

124 .strip() 

125 .split("\n") 

126 ) 

127 

128 rrd_args += extra_args 

129 try: 

130 rrdtool.graph(*rrd_args) 

131 except rrdtool.error as e: 

132 print( 

133 ("warning: graph: rrdtool error, skipping %s-%s.png: %s" % (name, graph, e)) 

134 ) 

135 

136 

137def graph_normal( 

138 rrd_dir, image_dir, name, extra_args, graph, title, start, year_lines=False 

139): 

140 image_file = os.path.join(image_dir, "%s-%s.png" % (name, graph)) 

141 rrd_file = os.path.join(rrd_dir, "%s.rrd" % name) 

142 rrd_args = [image_file, "--start", start] 

143 rrd_args += ( 

144 ( 

145 """ 

146--end 

147now 

148--width 

149600 

150--height 

151150 

152--vertical-label 

153packages 

154--title 

155%s package count for the last %s 

156--lower-limit 

1570 

158-E 

159""" 

160 % (name.upper(), title) 

161 ) 

162 .strip() 

163 .split("\n") 

164 ) 

165 

166 if year_lines: 

167 rrd_args += ["--x-grid", "MONTH:1:YEAR:1:YEAR:1:31536000:%Y"] 

168 

169 rrd_args += ( 

170 ( 

171 """ 

172DEF:ds1=%s:ds1:AVERAGE 

173LINE2:ds1#D9382B:changes count 

174VDEF:lds1=ds1,LAST 

175VDEF:minds1=ds1,MINIMUM 

176VDEF:maxds1=ds1,MAXIMUM 

177VDEF:avgds1=ds1,AVERAGE 

178GPRINT:lds1:cur\\: %%.0lf 

179GPRINT:minds1:min\\: %%.0lf 

180GPRINT:maxds1:max\\: %%.0lf 

181GPRINT:avgds1:avg\\: %%.0lf\\j 

182DEF:ds0=%s:ds0:AVERAGE 

183VDEF:lds0=ds0,LAST 

184VDEF:minds0=ds0,MINIMUM 

185VDEF:maxds0=ds0,MAXIMUM 

186VDEF:avgds0=ds0,AVERAGE 

187LINE2:ds0#3069DA:src pkg count 

188GPRINT:lds0:cur\\: %%.0lf 

189GPRINT:minds0:min\\: %%.0lf 

190GPRINT:maxds0:max\\: %%.0lf 

191GPRINT:avgds0:avg\\: %%.0lf\\j 

192""" 

193 % (rrd_file, rrd_file) 

194 ) 

195 .strip() 

196 .split("\n") 

197 ) 

198 

199 rrd_args += extra_args 

200 try: 

201 rrdtool.graph(*rrd_args) 

202 except rrdtool.error as e: 

203 print( 

204 ("warning: graph: rrdtool error, skipping %s-%s.png: %s" % (name, graph, e)) 

205 ) 

206 

207 

208################################################################################ 

209 

210 

211def main(): 

212 global Cnf 

213 

214 Cnf = utils.get_conf() 

215 Arguments = [ 

216 ("h", "help", "Graph::Options::Help"), 

217 ("x", "extra-rrd", "Graph::Options::Extra-Rrd", "HasArg"), 

218 ("r", "rrd", "Graph::Options::Rrd", "HasArg"), 

219 ("i", "images", "Graph::Options::Images", "HasArg"), 

220 ("n", "names", "Graph::Options::Names", "HasArg"), 

221 ] 

222 for i in ["help"]: 

223 key = "Graph::Options::%s" % i 

224 if key not in Cnf: 224 ↛ 222line 224 didn't jump to line 222, because the condition on line 224 was never false

225 Cnf[key] = "" 

226 

227 apt_pkg.parse_commandline(Cnf, Arguments, sys.argv) 

228 

229 Options = Cnf.subtree("Graph::Options") 

230 if Options["Help"]: 230 ↛ 233line 230 didn't jump to line 233, because the condition on line 230 was never false

231 usage() 

232 

233 names = [] 

234 

235 if "Graph::Options::Names" in Cnf: 

236 for i in Cnf["Graph::Options::Names"].split(","): 

237 names.append(i) 

238 elif "Graph::Names" in Cnf: 

239 names = Cnf.value_list("Graph::Names") 

240 else: 

241 names = default_names 

242 

243 extra_rrdtool_args = [] 

244 

245 if "Graph::Options::Extra-Rrd" in Cnf: 

246 for i in Cnf["Graph::Options::Extra-Rrd"].split(","): 

247 with open(i) as f: 

248 extra_rrdtool_args.extend(f.read().strip().split("\n")) 

249 elif "Graph::Extra-Rrd" in Cnf: 

250 for i in Cnf.value_list("Graph::Extra-Rrd"): 

251 with open(i) as f: 

252 extra_rrdtool_args.extend(f.read().strip().split("\n")) 

253 

254 if "Graph::Options::Rrd" in Cnf: 

255 rrd_dir = Cnf["Graph::Options::Rrd"] 

256 elif "Dir::Rrd" in Cnf: 

257 rrd_dir = Cnf["Dir::Rrd"] 

258 else: 

259 print("No directory to read RRD files from\n", file=sys.stderr) 

260 sys.exit(1) 

261 

262 if "Graph::Options::Images" in Cnf: 

263 image_dir = Cnf["Graph::Options::Images"] 

264 else: 

265 print("No directory to write graph images to\n", file=sys.stderr) 

266 sys.exit(1) 

267 

268 for name in names: 

269 stdargs = [rrd_dir, image_dir, name, extra_rrdtool_args] 

270 graph(*(stdargs + ["day", "day", "now-1d"])) 

271 graph(*(stdargs + ["week", "week", "now-1w"])) 

272 graph(*(stdargs + ["month", "month", "now-1m"])) 

273 graph(*(stdargs + ["year", "year", "now-1y"])) 

274 graph(*(stdargs + ["5years", "5 years", "now-5y", True])) 

275 graph(*(stdargs + ["10years", "10 years", "now-10y", True])) 

276 

277 

278################################################################################ 

279 

280 

281if __name__ == "__main__": 

282 main()