#!/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(" \n") sys.stdout.write(" \n") def tableFooter(): sys.stdout.write("
"+c+"
\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()