def ticket_list(): authors = None machine = None if 'query' in request.args: query = json.loads(request.args.get('query')) else: status = request.args.get('status', 'needs_review') if status == 'all': query = {} elif status in ('new', 'closed'): query = {'status': {'$regex': status + '.*' }} elif status in ('open'): query = {'status': {'$regex': 'needs_.*|positive_review' }} else: query = {'status': status} if 'todo' in request.args: query['patches'] = {'$not': {'$size': 0}} query['spkgs'] = {'$size': 0} if 'authors' in request.args: authors = request.args.get('authors').split(':') query['authors'] = {'$in': authors} if 'machine' in request.args: machine = request.args.get('machine').split('/') query['reports.machine'] = machine if 'order' in request.args: order = request.args.get('order') else: order = 'last_activity' if 'base' in request.args: base = request.args.get('base') if base == 'all': base = None else: base = 'latest' if 'author' in request.args: query['authors'] = request.args.get('author') if 'participant' in request.args: query['participants'] = request.args.get('participant') all = patchbot.filter_on_authors(tickets.find(query).sort(order), authors) if 'raw' in request.args: if 'pretty' in request.args: indent = 4 else: indent = None response = make_response(json.dumps(list(all), default=lambda x: None, indent=indent)) response.headers['Content-type'] = 'text/plain' return response summary = dict((key, 0) for key in status_order) def preprocess(all): for ticket in all: ticket['report_count'], ticket['report_status'], ticket['report_status_composite'] = get_ticket_status(ticket, machine=machine, base=base or 'latest') if 'reports' in ticket: ticket['pending'] = len([r for r in ticket['reports'] if r['status'] == 'Pending']) summary[ticket['report_status']] += 1 yield ticket ticket0 = db.lookup_ticket(0) versions = list(set(report['base'] for report in ticket0['reports'])) versions.sort(trac.compare_version) versions = [(v, get_ticket_status(ticket0, v)) for v in versions if v != '4.7.'] return render_template("ticket_list.html", tickets=preprocess(all), summary=summary, base=base, base_status=get_ticket_status(db.lookup_ticket(0), base), versions=versions, status_order=status_order)
def format_info(info): new_info = {} for key, value in info.items(): if key == 'patches': new_info['patches'] = format_patches(ticket, value) elif key == 'reports' or key == 'pending': pass elif key == 'depends_on': deps_status = {} for dep in tickets.find({'id': {'$in': [int(a) for a in value]}}, ['status', 'id']): if 'closed' in dep['status']: dep['style'] = 'text-decoration: line-through' else: dep['style'] = '' deps_status[dep['id']] = dep new_info[key] = ', '.join("<img src='/ticket/%s/status.png?fast' height=16><a href='/ticket/%s' style='%s'>%s</a>" % (a, a, deps_status[a]['style'], a) for a in value) elif key == 'authors': new_info[key] = ', '.join("<a href='/ticket/?author=%s'>%s</a>" % (a,a) for a in value) elif key == 'participants': new_info[key] = ', '.join("<a href='/ticket/?participant=%s'>%s</a>" % (a,a) for a in value) elif isinstance(value, list): new_info[key] = ', '.join(value) elif key not in ('id', '_id'): new_info[key] = value return new_info
def machines(): """ list of recently working machines, with some statistics """ # aggregate requires server version >= 2.1.0 query = get_query(request.args) if 'authors' in request.args: authors = request.args.get('authors').split(':') else: authors = None all = filter_on_authors(tickets.find(query).limit(100), authors) machines = {} for ticket in all: for report in ticket.get('reports', []): machine = tuple(report['machine']) if machine in machines: stats = machines[machine] else: stats = machines[machine] = MachineStats(machine) stats.add_report(report, ticket) all = [] return render_template("machines.html", machines=reversed(sorted(machines.values())), len=len, status=request.args.get('status', 'needs_review'))
def trusted_authors(): """ Defines the set of trusted authors Currently, somebody is trusted if he/she is the author of a closed patch with 'fixed' status """ authors = collections.defaultdict(int) for ticket in tickets.find({'status': 'closed : fixed'}): for author in ticket["authors"]: authors[author] += 1 for ticket in tickets.find({'status': 'closed', 'resolution': 'fixed'}): for author in ticket["authors"]: authors[author] += 1 if 'pretty' in request.args: indent = 4 else: indent = None response = make_response(json.dumps(authors, default=lambda x: None, indent=indent)) response.headers['Content-type'] = 'text/plain' return response
def trusted_authors(): authors = collections.defaultdict(int) for ticket in tickets.find({'status': 'closed : fixed'}): for author in ticket["authors"]: authors[author] += 1 if 'pretty' in request.args: indent = 4 else: indent = None response = make_response(json.dumps(authors, default=lambda x: None, indent=indent)) response.headers['Content-type'] = 'text/plain' return response
def ticket_list(): authors = None machine = None query = get_query(request.args) if 'machine' in request.args: machine = request.args.get('machine').split(':') if 'authors' in request.args: authors = request.args.get('authors').split(':') if 'order' in request.args: order = request.args.get('order') else: order = 'last_activity' limit = int(request.args.get('limit', 10000)) print query if 'base' in request.args: base = request.args.get('base') if base == 'all': base = None else: base = 'latest' all = patchbot.filter_on_authors(tickets.find(query).sort(order).limit(limit), authors) if 'raw' in request.args: def filter_reports(all): for ticket in all: ticket['reports'] = list(reversed(sorted(current_reports(ticket), key=lambda report: parse_datetime(report['time']))))[:10] for report in ticket['reports']: report['plugins'] = '...' yield ticket all = filter_reports(all) if 'pretty' in request.args: indent = 4 else: indent = None response = make_response(json.dumps(list(all), default=lambda x: None, indent=indent)) response.headers['Content-type'] = 'text/plain' return response summary = dict((key, 0) for key in status_order) def preprocess(all): for ticket in all: ticket['report_count'], ticket['report_status'], ticket['report_status_composite'] = get_ticket_status(ticket, machine=machine, base=base or 'latest') if 'reports' in ticket: ticket['pending'] = len([r for r in ticket['reports'] if r['status'] == 'Pending']) summary[ticket['report_status']] += 1 yield ticket ticket0 = db.lookup_ticket(0) versions = list(set(report['base'] for report in ticket0['reports'])) versions.sort(compare_version) versions = [(v, get_ticket_status(ticket0, v)) for v in versions if v != '4.7.'] return render_template("ticket_list.html", tickets=preprocess(all), summary=summary, base=base, base_status=get_ticket_status(db.lookup_ticket(0), base), versions=versions, status_order=status_order, compare_version=compare_version)
def format_info(info): new_info = {} for key, value in info.items(): if key in ['patches', 'reports', 'pending']: pass elif key == 'depends_on': deps_status = {} def is_int(a): try: int(a) return True except ValueError: return False for dep in tickets.find({'id': {'$in': [int(a) for a in value if is_int(a)]}}, ['status', 'id']): if 'closed' in dep['status']: dep['style'] = 'text-decoration: line-through' else: dep['style'] = '' deps_status[dep['id']] = dep new_info[key] = ', '.join("<img src='/ticket/%s/status.svg?fast' height=16><a href='/ticket/%s' style='%s'>%s</a>" % (a, a, deps_status[a]['style'], a) for a in value) elif key == 'authors': new_info[key] = ', '.join("<a href='/ticket/?author=%s'>%s</a>" % (a, a) for a in value) elif key == 'authors_fullnames': link = u"<a href='http://git.sagemath.org/sage.git/log/?qt=author&q={}'>{}</a>" auths = u", ".join(link.format(a.replace(u" ", u"%20"), a) for a in value) trust_check = u"(<a href='/trust_check?who=" trust_check += u",".join(u"{}".format(a) for a in value) trust_check += u"'>Check trust</a>) " new_info[key] = trust_check + auths elif key == 'participants': parts = ', '.join("<a href='/ticket/?participant=%s'>%s</a>" % (a, a) for a in value) new_info[key] = parts elif key == 'git_branch': new_info[key] = '<a href="http://git.sagemath.org/sage.git/log/?h=%s">%s</a>' % (value, value) elif key == 'spkgs': new_info[key] = ', '.join("<a href='%s'>%s</a>" % (a, a) for a in value) elif isinstance(value, list): new_info[key] = ', '.join(value) elif key not in ('id', '_id'): new_info[key] = value return new_info
def compute_trusted_authors(): """ Define the trusted authors. Currently, somebody is trusted if he/she is the author of a closed patch with 'fixed' status. The result is a dict, its keys being the trusted authors. This needs work ! We cannot rely on the branch names! """ authors = collections.defaultdict(int) for ticket in tickets.find({'status': 'closed', 'resolution': 'fixed'}): for author in ticket.get("authors_fullnames", []): a = author.strip() if a: authors[a] += 1 # code below is temporary and for backward compatibility only for author in ticket.get("authors", []): a = author.strip() if a: authors[a] += 1 return authors
def latest_base(betas=True): versions = list(tickets.find({'id': 0}).distinct('reports.base')) if not betas: versions = list(filter(re.compile(r'[0-9.]+$').match, versions)) versions.sort(compare_version) return versions[-1]
def ticket_list(): authors = None machine = None if 'base' in request.args: base = request.args.get('base') if base == 'all': base = None elif base == 'develop': base = 'latest' else: base = 'latest' query = get_query(request.args) if 'machine' in request.args: machine = request.args.get('machine').split(':') if 'authors' in request.args: authors = request.args.get('authors').split(':') if 'order' in request.args: order = request.args.get('order') else: order = 'last_activity' limit = int(request.args.get('limit', 1000)) print(query) all = filter_on_authors(tickets.find(query).sort(order).limit(limit), authors) if 'raw' in request.args: # raw json file for communication with patchbot clients def filter_reports(all): for ticket in all: current = sorted(current_reports(ticket), key=lambda report: report['time']) ticket['reports'] = list(reversed(current))[:10] for report in ticket['reports']: report['plugins'] = '...' yield ticket all = filter_reports(all) if 'pretty' in request.args: indent = 4 else: indent = None response = make_response(json.dumps(list(all), default=lambda x: None, indent=indent)) response.headers['Content-type'] = 'text/plain; charset=utf-8' return response summary = {key: 0 for key in status_order} def preprocess(all): for ticket in all: ticket['report_count'], ticket['report_status'], ticket['report_status_composite'] = get_ticket_status(ticket, machine=machine, base=base or 'latest') if 'reports' in ticket: ticket['pending'] = len([r for r in ticket['reports'] if r['status'] == 'Pending']) summary[ticket['report_status']] += 1 yield ticket ticket0 = tickets.find_one({'id': 0}) base_status = get_ticket_status(ticket0, base) versions = list(set(report['base'] for report in ticket0['reports'])) versions.sort(compare_version) versions = [v for v in versions if compare_version(v, OLDEST) == 1] versions = [(v, get_ticket_status(ticket0, v)) for v in versions] return render_template("ticket_list.html", tickets=preprocess(all), summary=summary, base=base, base_status=base_status, versions=versions, status_order=status_order, compare_version=compare_version)