#!/usr/bin/python3 import os, re, sys, curses from optparse import OptionParser from issue import get_issues, parse_status def filter_out_states(issues, inc_releases, exc_releases, states, notstates): filteredissues = [] for i in issues: for release in (inc_releases or i.get_releases()) - exc_releases: # Current state must be within 'states' (if specified), and # must not be within 'notstates' (if specified). m = parse_status(i.status(release)) if ((m['state'] in states if states else True) and (m['state'] not in notstates if notstates else True)): filteredissues.append(i) break return filteredissues def tparm_unicode(*args): return curses.tparm(*args).decode('ascii') if __name__ == '__main__': parser = OptionParser() parser.add_option("-d", "--dirs", action="append") parser.add_option("-r", "--release", action="append") parser.add_option("-s", "--states", action="append") parser.add_option("-n", "--notstates", action="append") parser.add_option("-c", "--color", "--colour", action="store_true") parser.add_option("--no-color", "--no-colour", action="store_false", dest="color") (options, args) = parser.parse_args() if not options.dirs: print('I: Listing issues in active directory') options.dirs = ['active'] if not options.states and not options.notstates: print('I: Excluding N/A, ignored and released issues') options.notstates = ['N/A', 'ignored', 'released'] if options.release: inc_releases = set(options.release) exc_releases = set() else: print('I: Excluding EOL releases') inc_releases = None with open('eol_releases') as eol_file: exc_releases = set(line.strip() for line in eol_file if not line.startswith('#')) if options.color is None: options.color = sys.stdout.isatty() if options.color: curses.setupterm() status_color = {"needed": tparm_unicode(curses.tigetstr("setaf"), curses.COLOR_RED), "ignored": tparm_unicode(curses.tigetstr("setaf"), curses.COLOR_YELLOW), "pending": tparm_unicode(curses.tigetstr("setaf"), curses.COLOR_MAGENTA), "released": tparm_unicode(curses.tigetstr("setaf"), curses.COLOR_GREEN), "N/A": tparm_unicode(curses.tigetstr("setaf"), curses.COLOR_GREEN)} color_off = tparm_unicode(curses.tigetstr("op")) else: color_off = '' issues = [] for d in options.dirs: issues = issues + get_issues(d) if options.states or options.notstates: issues = filter_out_states(issues, inc_releases, exc_releases, options.states, options.notstates) if options.release: list_releases = options.release else: all_releases = set() for i in issues: all_releases |= i.get_releases() list_releases = sorted(list(all_releases - exc_releases)) name_width = max(len(i.name) for i in issues) if len(list_releases) == 1: min_width = 0 max_width = 1000 else: min_width = 20 max_width = 20 sys.stdout.write(" " * (name_width + 1)) for release in list_releases: sys.stdout.write(" %-20.20s " % release) sys.stdout.write("\n") for i in issues: sys.stdout.write("%*s:" % (name_width, i.name)) for release in list_releases: status = i.status(release) or "unknown" status_short = parse_status(status)['state'] if options.color and status_short in status_color: color_on = status_color[status_short] else: color_on = '' sys.stdout.write(" %s%-*.*s%s " % (color_on, min_width, max_width, status, color_off)) sys.stdout.write("\n")