1
2
3 """Output html for packages in NEW"""
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 import os
29 import sys
30 import time
31 from multiprocessing import Manager
32
33 import apt_pkg
34
35 import dak.examine_package
36 from daklib import policy
37 from daklib.config import Config
38 from daklib.dakmultiprocessing import (
39 PROC_STATUS_EXCEPTION,
40 PROC_STATUS_SUCCESS,
41 DakProcessPool,
42 )
43 from daklib.dbconn import DBChange, DBConn, PolicyQueue, PolicyQueueUpload
44
45
46 Cnf = None
47 Options = None
48 manager = Manager()
49 sources = manager.list()
50 htmlfiles_to_process = manager.list()
51 timeout_str = "Error or timeout while processing"
52
53
54
55
56
57
58
60 if name.endswith(".changes"):
61 name = " ".join(name.split("_")[:2])
62 result = """<!DOCTYPE html>
63 <html lang="en">
64 <head>
65 <meta charset="utf-8">
66 <title>%(name)s - Debian NEW package overview</title>
67 <link rel="stylesheet" href="/style.css">
68 <link rel="shortcut icon" href="https://www.debian.org/favicon.ico">
69 <script>
70 function toggle(id, initial, display) {
71 var o = document.getElementById(id);
72 toggleObj(o, initial, display);
73 }
74 function show(id, display) {
75 var o = document.getElementById(id);
76 o.style.display = 'table-row-group';
77 }
78 function toggleObj(o, initial, display) {
79 if(! o.style.display)
80 o.style.display = initial;
81 if(o.style.display == display) {
82 o.style.display = "none";
83 } else {
84 o.style.display = display;
85 }
86 }
87 </script>
88 </head>
89 <body id="NEW-details-page">
90 <div id="logo">
91 <a href="https://www.debian.org/">
92 <img src="https://www.debian.org/logos/openlogo-nd-50.png"
93 alt=""></a>
94 <a href="https://www.debian.org/">
95 <img src="https://www.debian.org/Pics/debian.png"
96 alt="Debian Project"></a>
97 </div>
98 <div id="titleblock">
99 <img src="https://www.debian.org/Pics/red-upperleft.png"
100 id="red-upperleft" alt="">
101 <img src="https://www.debian.org/Pics/red-lowerleft.png"
102 id="red-lowerleft" alt="">
103 <img src="https://www.debian.org/Pics/red-upperright.png"
104 id="red-upperright" alt="">
105 <img src="https://www.debian.org/Pics/red-lowerright.png"
106 id="red-lowerright" alt="">
107 <span class="title">
108 Debian NEW package overview for %(name)s
109 </span>
110 </div>
111
112 """ % {
113 "name": name
114 }
115
116
117 result += """
118 <div id="menu">
119 <p class="title">Navigation</p>
120 <p><a href="#changes" onclick="show('changes-body')">.changes</a></p>
121 <p><a href="#dsc" onclick="show('dsc-body')">.dsc</a></p>
122 <p><a href="#source-lintian" onclick="show('source-lintian-body')">source lintian</a></p>
123
124 """
125 for binarytype, packagename in [m for m in missing if m[0] in ("deb", "udeb")]:
126 result += """
127 <p class="subtitle">%(pkg)s</p>
128 <p><a href="#binary-%(pkg)s-control" onclick="show('binary-%(pkg)s-control-body')">control file</a></p>
129 <p><a href="#binary-%(pkg)s-lintian" onclick="show('binary-%(pkg)s-lintian-body')">binary lintian</a></p>
130 <p><a href="#binary-%(pkg)s-contents" onclick="show('binary-%(pkg)s-contents-body')">.deb contents</a></p>
131 <p><a href="#binary-%(pkg)s-copyright" onclick="show('binary-%(pkg)s-copyright-body')">copyright</a></p>
132 <p><a href="#binary-%(pkg)s-file-listing" onclick="show('binary-%(pkg)s-file-listing-body')">file listing</a></p>
133
134 """ % {
135 "pkg": packagename
136 }
137 result += " </div>"
138 return result
139
140
148
149
150
151
152
154 cnf = Config()
155
156 session = DBConn().session()
157 upload = session.query(PolicyQueueUpload).filter_by(id=upload_id).one()
158
159 queue = upload.policy_queue
160 changes = upload.changes
161
162 origchanges = os.path.join(queue.path, changes.changesname)
163 print(origchanges)
164
165 htmlname = "{0}_{1}.html".format(changes.source, changes.version)
166 htmlfile = os.path.join(cnf["Show-New::HTMLPath"], htmlname)
167
168
169 if os.path.exists(htmlfile) and os.stat(htmlfile).st_mtime > time.mktime(
170 changes.created.timetuple()
171 ):
172 with open(htmlfile, "r") as fd:
173 if fd.read() != timeout_str:
174 sources.append(htmlname)
175 return (PROC_STATUS_SUCCESS, "%s already up-to-date" % htmlfile)
176
177
178 htmlfiles_to_process.append(htmlfile)
179 sources.append(htmlname)
180
181 group = cnf.get("Dinstall::UnprivGroup") or None
182
183 with open(htmlfile, "w") as outfile, policy.UploadCopy(
184 upload, group=group
185 ) as upload_copy:
186 handler = policy.PolicyQueueUploadHandler(upload, session)
187 missing = [(o["type"], o["package"]) for o in handler.missing_overrides()]
188 distribution = changes.distribution
189
190 outfile.write(html_header(changes.source, missing))
191 outfile.write(dak.examine_package.display_changes(distribution, origchanges))
192
193 if upload.source is not None and ("dsc", upload.source.source) in missing:
194 fn = os.path.join(upload_copy.directory, upload.source.poolfile.basename)
195 outfile.write(dak.examine_package.check_dsc(distribution, fn, session))
196 for binary in upload.binaries:
197 if (binary.binarytype, binary.package) not in missing:
198 continue
199 fn = os.path.join(upload_copy.directory, binary.poolfile.basename)
200 outfile.write(dak.examine_package.check_deb(distribution, fn, session))
201
202 outfile.write(html_footer())
203
204 session.close()
205 htmlfiles_to_process.remove(htmlfile)
206 return (PROC_STATUS_SUCCESS, "{0} already updated".format(htmlfile))
207
208
209
210
211
213 print(
214 """Usage: dak show-new [OPTION]... [CHANGES]...
215 -h, --help show this help and exit.
216 -p, --html-path [path] override output directory.
217 """
218 )
219 sys.exit(exit_code)
220
221
222
223
224
226 global cnf, Options
227
228 cnf = Config()
229
230 Arguments = [
231 ("h", "help", "Show-New::Options::Help"),
232 ("p", "html-path", "Show-New::HTMLPath", "HasArg"),
233 ("q", "queue", "Show-New::Options::Queue", "HasArg"),
234 ]
235
236 for i in ["help"]:
237 key = "Show-New::Options::%s" % i
238 if key not in cnf:
239 cnf[key] = ""
240
241 changesnames = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv)
242 Options = cnf.subtree("Show-New::Options")
243
244 if Options["help"]:
245 usage()
246
247 queue_names = Options.find("Queue", "new").split(",")
248 uploads = (
249 session.query(PolicyQueueUpload)
250 .join(PolicyQueueUpload.policy_queue)
251 .filter(PolicyQueue.queue_name.in_(queue_names))
252 .join(PolicyQueueUpload.changes)
253 .order_by(DBChange.source)
254 )
255
256 if len(changesnames) > 0:
257 uploads = uploads.filter(DBChange.changesname.in_(changesnames))
258
259 return uploads
260
261
263 code, msg = r
264 if code == PROC_STATUS_EXCEPTION:
265 print("Job raised exception: %s" % (msg))
266 elif code != PROC_STATUS_SUCCESS:
267 print("Job failed: %s" % (msg))
268
269
270
271
272
273
275 dak.examine_package.use_html = True
276 pool = DakProcessPool(processes=5)
277
278 session = DBConn().session()
279 upload_ids = [u.id for u in init(session)]
280 session.close()
281
282 for upload_id in upload_ids:
283 pool.apply_async(do_pkg, [upload_id], callback=result_callback)
284 pool.close()
285
286 pool.join()
287
288 for htmlfile in htmlfiles_to_process:
289 with open(htmlfile, "w") as fd:
290 fd.write(timeout_str)
291
292 if pool.overall_status() != PROC_STATUS_SUCCESS:
293 raise Exception("Processing failed (code %s)" % (pool.overall_status()))
294
295 files = set(os.listdir(cnf["Show-New::HTMLPath"]))
296 to_delete = [x for x in files.difference(set(sources)) if x.endswith(".html")]
297 for f in to_delete:
298 os.remove(os.path.join(cnf["Show-New::HTMLPath"], f))
299
300
301
302
303
304 if __name__ == "__main__":
305 main()
306