Coverage for dak/graph.py: 26%

88 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2026-01-04 16:18 +0000

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 

26from typing import NoReturn 

27 

28import apt_pkg 

29import rrdtool 

30 

31from daklib import utils 

32 

33Cnf: apt_pkg.Configuration 

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

35 

36################################################################################ 

37 

38 

39def usage(exit_code=0) -> NoReturn: 

40 print( 

41 """Usage: dak graph 

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

43 

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

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

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

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

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

49 

50""" 

51 ) 

52 sys.exit(exit_code) 

53 

54 

55################################################################################ 

56 

57 

58def graph( 

59 rrd_dir: str, 

60 image_dir: str, 

61 name: str, 

62 extra_args: list[str], 

63 graph: str, 

64 title: str, 

65 start: str, 

66 year_lines=False, 

67) -> None: 

68 fn = graph_deferred if name == "deferred" else graph_normal 

69 fn(rrd_dir, image_dir, name, extra_args, graph, title, start, year_lines) 

70 

71 

72colours = [ 

73 "".join( 

74 "%02X" % int(c * 255) 

75 for c in colorsys.hsv_to_rgb(i / 16.0, 1.0, 0.5 + i / 32.0) 

76 ) 

77 for i in range(0, 16) 

78] 

79 

80 

81def graph_deferred( 

82 rrd_dir: str, 

83 image_dir: str, 

84 name: str, 

85 extra_args: list[str], 

86 graph: str, 

87 title: str, 

88 start: str, 

89 year_lines=False, 

90) -> None: 

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

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

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

94 rrd_args += ( 

95 ( 

96 """ 

97--end 

98now 

99--width 

100600 

101--height 

102150 

103--vertical-label 

104changes 

105--title 

106%s changes count for the last %s 

107--lower-limit 

1080 

109-E 

110""" 

111 % (name.upper(), title) 

112 ) 

113 .strip() 

114 .split("\n") 

115 ) 

116 

117 if year_lines: 

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

119 

120 for i in range(0, 16): 

121 rrd_args += ( 

122 ( 

123 """ 

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

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

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

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

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

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

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

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

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

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

134""" 

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

136 ) 

137 .strip() 

138 .split("\n") 

139 ) 

140 

141 rrd_args += extra_args 

142 try: 

143 rrdtool.graph(*rrd_args) 

144 except rrdtool.error as e: 

145 print( 

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

147 ) 

148 

149 

150def graph_normal( 

151 rrd_dir: str, 

152 image_dir: str, 

153 name: str, 

154 extra_args: list[str], 

155 graph: str, 

156 title: str, 

157 start: str, 

158 year_lines=False, 

159) -> None: 

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

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

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

163 rrd_args += ( 

164 ( 

165 """ 

166--end 

167now 

168--width 

169600 

170--height 

171150 

172--vertical-label 

173packages 

174--title 

175%s package count for the last %s 

176--lower-limit 

1770 

178-E 

179""" 

180 % (name.upper(), title) 

181 ) 

182 .strip() 

183 .split("\n") 

184 ) 

185 

186 if year_lines: 

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

188 

189 rrd_args += ( 

190 ( 

191 """ 

192DEF:ds1=%s:ds1:AVERAGE 

193LINE2:ds1#D9382B:changes count 

194VDEF:lds1=ds1,LAST 

195VDEF:minds1=ds1,MINIMUM 

196VDEF:maxds1=ds1,MAXIMUM 

197VDEF:avgds1=ds1,AVERAGE 

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

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

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

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

202DEF:ds0=%s:ds0:AVERAGE 

203VDEF:lds0=ds0,LAST 

204VDEF:minds0=ds0,MINIMUM 

205VDEF:maxds0=ds0,MAXIMUM 

206VDEF:avgds0=ds0,AVERAGE 

207LINE2:ds0#3069DA:src pkg count 

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

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

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

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

212""" 

213 % (rrd_file, rrd_file) 

214 ) 

215 .strip() 

216 .split("\n") 

217 ) 

218 

219 rrd_args += extra_args 

220 try: 

221 rrdtool.graph(*rrd_args) 

222 except rrdtool.error as e: 

223 print( 

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

225 ) 

226 

227 

228################################################################################ 

229 

230 

231def main() -> None: 

232 global Cnf 

233 

234 Cnf = utils.get_conf() 

235 Arguments = [ 

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

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

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

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

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

241 ] 

242 for i in ["help"]: 

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

244 if key not in Cnf: 244 ↛ 242line 244 didn't jump to line 242 because the condition on line 244 was always true

245 Cnf[key] = "" # type: ignore[index] 

246 

247 apt_pkg.parse_commandline(Cnf, Arguments, sys.argv) # type: ignore[attr-defined] 

248 

249 Options = Cnf.subtree("Graph::Options") # type: ignore[attr-defined] 

250 if Options["Help"]: 250 ↛ 253line 250 didn't jump to line 253 because the condition on line 250 was always true

251 usage() 

252 

253 names = [] 

254 

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

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

257 names.append(i) 

258 elif "Graph::Names" in Cnf: 

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

260 else: 

261 names = default_names 

262 

263 extra_rrdtool_args = [] 

264 

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

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

267 with open(i) as f: 

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

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

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

271 with open(i) as f: 

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

273 

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

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

276 elif "Dir::Rrd" in Cnf: 

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

278 else: 

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

280 sys.exit(1) 

281 

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

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

284 else: 

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

286 sys.exit(1) 

287 

288 for name in names: 

289 stdargs = (rrd_dir, image_dir, name, extra_rrdtool_args) 

290 graph(*stdargs, "day", "day", "now-1d") 

291 graph(*stdargs, "week", "week", "now-1w") 

292 graph(*stdargs, "month", "month", "now-1m") 

293 graph(*stdargs, "year", "year", "now-1y") 

294 graph(*stdargs, "5years", "5 years", "now-5y", True) 

295 graph(*stdargs, "10years", "10 years", "now-10y", True) 

296 

297 

298################################################################################ 

299 

300 

301if __name__ == "__main__": 

302 main()