Package dak :: Module show_new
[hide private]
[frames] | no frames]

Source Code for Module dak.show_new

  1  #! /usr/bin/env python3 
  2   
  3  """Output html for packages in NEW""" 
  4  # Copyright (C) 2007, 2009 Joerg Jaspert <joerg@debian.org> 
  5   
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10   
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15   
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 19   
 20  ################################################################################ 
 21   
 22  # <elmo> I'm James Troup, long term source of all evil in Debian. you may 
 23  #        know me from such debian-devel-announce gems as "Serious 
 24  #        Problems With ...." 
 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  # Globals 
 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   
59 -def html_header(name, missing):
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 # we assume only one source (.dsc) per changes here 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
153 -def do_pkg(upload_id):
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 # Have we already processed this? 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 # Go, process it... Now! 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
212 -def usage(exit_code=0):
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
225 -def init(session):
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
262 -def result_callback(r):
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
274 -def main():
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