#!/usr/bin/python
import os, os.path, sys
import deb822, re
TrackerDir = "."
## get an unsorted list of tracked issues
def trackedIssues(dir):
ignores = [ re.compile('~$'),
re.compile('^#.*#$'),
re.compile('^00'),
re.compile('\.patch$')]
validpaths = []
for f in os.listdir(dir):
nogood = False
for i in ignores:
if i.search(f):
nogood = True
break
if nogood:
continue
else:
validpaths.append(f)
issues = []
for f in validpaths:
path = os.path.join(dir, f)
if os.path.isfile(path):
issues.append(f)
return issues
def trackedVersions(dir):
pkglist = os.path.join(dir, '00pkglist')
f = open(pkglist, 'r')
return f.read().split('\n')[:-1]
def issueStatus(issue, version):
path = os.path.join(TrackerDir, issue)
i = deb822.deb822(open(path, 'r'))
if i.hasField(version):
return i.map[version]
else:
return None
def statusMatrix(issues, versions):
Di = {}
for i in issues:
Dv = {}
for v in versions:
Dv[v] = issueStatus(i, v)
Di[i] = Dv
return Di
## remaining functions create the HTML
def htmlHeader():
sys.stdout.write('\n')
sys.stdout.write('
\n')
sys.stdout.write(' Debian Kernel Patch Tracker Status\n')
sys.stdout.write('\n')
sys.stdout.write('\n')
sys.stdout.write('Debian Kernel Patch Tracker Status
')
key = '''
Key |
Fixed or N/A - version is listed if specified |
Pending - version is listed if specified |
Needed |
Ignored |
'''
sys.stdout.write(key)
sys.stdout.write('
\n')
def htmlFooter():
sys.stdout.write(' \n')
sys.stdout.write('\n')
def tableHeader(columns):
## populateTable() will assume columns should be filled out
## in sort() order, so make sure our column names match
columns.sort()
sys.stdout.write("\n")
sys.stdout.write(" \n")
sys.stdout.write(" | \n")
for c in columns:
sys.stdout.write(" "+c+" | \n")
sys.stdout.write("
\n")
def tableFooter():
sys.stdout.write("
\n")
## Parse a status string, and return an html table entry
def statusCell(status):
if not status:
return 'Unknown | '
statusRe = re.compile("(?P\S+)(\s*\((?P.*)\))?(\s*\[(?P.*)\])?$")
m = statusRe.match(status)
if m:
d = m.groupdict()
ver = name = ""
if d.has_key('ver') and d['ver']:
ver = d['ver']
if d.has_key('name') and d['name']:
name = d['name']
if d['status'] == 'N/A':
return 'N/A | '
elif d['status'] == "released":
return '' + ver + ' | '
elif d['status'] == "pending":
return '' + ver + ' | '
elif d['status'] == "needed":
return '' + ver + ' | '
elif d['status'] == "ignored":
return '' + ver + ' | '
else:
return 'Unknown | '
def populateTable(matrix):
issues = matrix.keys()
issues.sort()
cvere = re.compile('^CVE-\d\d\d\d\-\d\d\d\d')
for i in issues:
if cvere.match(i):
issueref = ''+i+''
else:
issueref = i
versions = matrix[i].keys()
versions.sort()
sys.stdout.write(' \n')
sys.stdout.write(' ' + issueref + ' | \n')
for v in versions:
cell = statusCell(matrix[i][v].strip())
if cell:
sys.stdout.write(cell)
else:
sys.stderr.write("Error in field: " + i + ", " + v + "\n")
sys.stdout.write('
\n')
if __name__ == '__main__':
## Doing this in a separate stage means some unnecessary duplicate
## opens & closes... but oh well - our data set isn't very large
issues = trackedIssues(TrackerDir)
versions = trackedVersions(TrackerDir)
htmlHeader()
tableHeader(versions)
populateTable(statusMatrix(issues, versions))
tableFooter()
htmlFooter()