Coverage for dak/graph.py: 26%

88 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2026-08-03 16:46 +0000

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

2 

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

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

5""" 

6 

7# This program is free software; you can redistribute it and/or modify 

8# it under the terms of the GNU General Public License as published by 

9# the Free Software Foundation; either version 2 of the License, or 

10# (at your option) any later version. 

11 

12# This program is distributed in the hope that it will be useful, 

13# but WITHOUT ANY WARRANTY; without even the implied warranty of 

14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

15# GNU General Public License for more details. 

16 

17# You should have received a copy of the GNU General Public License 

18# along with this program; if not, write to the Free Software 

19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

20 

21import colorsys 

22import os 

23import sys 

24from typing import NoReturn 

25 

26import apt_pkg 

27import rrdtool 

28 

29from daklib import utils 

30 

31Cnf: apt_pkg.Configuration 

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

33 

34################################################################################ 

35 

36 

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

38 print( 

39 """Usage: dak graph 

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

41 

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 

47 

48""" 

49 ) 

50 sys.exit(exit_code) 

51 

52 

53################################################################################ 

54 

55 

56def graph( 

57 rrd_dir: str, 

58 image_dir: str, 

59 name: str, 

60 extra_args: list[str], 

61 graph: str, 

62 title: str, 

63 start: str, 

64 year_lines=False, 

65) -> None: 

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

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

68 

69 

70colours = [ 

71 "".join( 

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

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

74 ) 

75 for i in range(16) 

76] 

77 

78 

79def graph_deferred( 

80 rrd_dir: str, 

81 image_dir: str, 

82 name: str, 

83 extra_args: list[str], 

84 graph: str, 

85 title: str, 

86 start: str, 

87 year_lines=False, 

88) -> None: 

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

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

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

92 rrd_args += ( 

93 ( 

94 """ 

95--end 

96now 

97--width 

98600 

99--height 

100150 

101--vertical-label 

102changes 

103--title 

104%s changes count for the last %s 

105--lower-limit 

1060 

107-E 

108""" 

109 % (name.upper(), title) 

110 ) 

111 .strip() 

112 .split("\n") 

113 ) 

114 

115 if year_lines: 

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

117 

118 for i in range(16): 

119 rrd_args += ( 

120 ( 

121 """ 

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

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

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

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

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

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

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

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

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

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

132""" 

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

134 ) 

135 .strip() 

136 .split("\n") 

137 ) 

138 

139 rrd_args += extra_args 

140 try: 

141 rrdtool.graph(*rrd_args) 

142 except rrdtool.error as e: 

143 print( 

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

145 ) 

146 

147 

148def graph_normal( 

149 rrd_dir: str, 

150 image_dir: str, 

151 name: str, 

152 extra_args: list[str], 

153 graph: str, 

154 title: str, 

155 start: str, 

156 year_lines=False, 

157) -> None: 

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

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

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

161 rrd_args += ( 

162 ( 

163 """ 

164--end 

165now 

166--width 

167600 

168--height 

169150 

170--vertical-label 

171packages 

172--title 

173%s package count for the last %s 

174--lower-limit 

1750 

176-E 

177""" 

178 % (name.upper(), title) 

179 ) 

180 .strip() 

181 .split("\n") 

182 ) 

183 

184 if year_lines: 

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

186 

187 rrd_args += ( 

188 ( 

189 """ 

190DEF:ds1=%s:ds1:AVERAGE 

191LINE2:ds1#D9382B:changes count 

192VDEF:lds1=ds1,LAST 

193VDEF:minds1=ds1,MINIMUM 

194VDEF:maxds1=ds1,MAXIMUM 

195VDEF:avgds1=ds1,AVERAGE 

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

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

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

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

200DEF:ds0=%s:ds0:AVERAGE 

201VDEF:lds0=ds0,LAST 

202VDEF:minds0=ds0,MINIMUM 

203VDEF:maxds0=ds0,MAXIMUM 

204VDEF:avgds0=ds0,AVERAGE 

205LINE2:ds0#3069DA:src pkg count 

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

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

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

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

210""" 

211 % (rrd_file, rrd_file) 

212 ) 

213 .strip() 

214 .split("\n") 

215 ) 

216 

217 rrd_args += extra_args 

218 try: 

219 rrdtool.graph(*rrd_args) 

220 except rrdtool.error as e: 

221 print( 

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

223 ) 

224 

225 

226################################################################################ 

227 

228 

229def main() -> None: 

230 global Cnf 

231 

232 Cnf = utils.get_conf() 

233 Arguments = [ 

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

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

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

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

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

239 ] 

240 for i in ["help"]: 

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

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

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

244 

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

246 

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

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

249 usage() 

250 

251 names = [] 

252 

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

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

255 names.append(i) 

256 elif "Graph::Names" in Cnf: 

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

258 else: 

259 names = default_names 

260 

261 extra_rrdtool_args = [] 

262 

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

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

265 with open(i) as f: 

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

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

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

269 with open(i) as f: 

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

271 

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

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

274 elif "Dir::Rrd" in Cnf: 

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

276 else: 

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

278 sys.exit(1) 

279 

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

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

282 else: 

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

284 sys.exit(1) 

285 

286 for name in names: 

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

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

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

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

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

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

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