def post_report(ticket_id): """ Posting a report to the database of reports. """ try: ticket = tickets.find_one({'id': ticket_id}) if ticket is None: ticket = scrape(ticket_id) if 'reports' not in ticket: ticket['reports'] = [] report = json.loads(request.form.get('report')) assert (isinstance(report, dict)), "report is not a dict" for fld in ['status', 'spkgs', 'base', 'machine', 'time']: assert (fld in report), "{} missing in report".format(fld) machine_name = report['machine'][-1] if machine_name in BLACKLIST: msg = 'machine {} is blacklisted'.format(machine_name) raise RuntimeError(msg) prune_pending(ticket, report['machine']) ticket['reports'].append(report) db.logs.put(request.files.get('log'), _id=log_name(ticket_id, report)) if 'retry' in ticket: ticket['retry'] = False ticket['last_activity'] = now_str() db.save_ticket(ticket) return "ok (report successfully posted)" except: traceback.print_exc() return "error in posting the report"
def render_ticket(ticket): try: info = trac.scrape(ticket, db=db, force='force' in request.args) except: info = tickets.find_one({'id': ticket}) if info is None: return "No such ticket." if 'kick' in request.args: info['retry'] = True db.save_ticket(info) if 'reports' in info: info['reports'].sort(lambda a, b: -cmp(a['time'], b['time'])) else: info['reports'] = [] old_reports = list(info['reports']) patchbot.prune_pending(info) if old_reports != info['reports']: db.save_ticket(info) 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': new_info[key] = ', '.join("<a href='/ticket/%s'>%s</a>" % (a, 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 preprocess_reports(all): for item in all: if 'patches' in item: required = info['depends_on'] + info['patches'] item['patch_list'] = format_patches(ticket, item['patches'], item.get('deps'), required) if item['base'] != base: item['base'] = "<span style='color: red'>%s</span>" % item['base'] if 'time' in item: item['log'] = log_name(info['id'], item) yield item return render_template("ticket.html", reports=preprocess_reports(info['reports']), ticket=ticket, info=format_info(info), status=get_ticket_status(info, base=base)[2])
def post_report(ticket_id): try: ticket = db.lookup_ticket(ticket_id) if ticket is None: ticket = trac.scrape(ticket_id) if 'reports' not in ticket: ticket['reports'] = [] report = json.loads(request.form.get('report')) assert isinstance(report, dict) for fld in ['status', 'patches', 'spkgs', 'base', 'machine', 'time']: assert fld in report patchbot.prune_pending(ticket, report['machine']) ticket['reports'].append(report) db.logs.put(request.files.get('log'), _id=log_name(ticket_id, report)) if 'retry' in ticket: ticket['retry'] = False ticket['last_activity'] = now_str() db.save_ticket(ticket) return "ok" except: traceback.print_exc() return "error"
def render_ticket(ticket): try: info = trac.scrape(ticket, db=db, force='force' in request.args) except: info = tickets.find_one({'id': ticket}) if info is None: return "No such ticket." if 'kick' in request.args: info['retry'] = True db.save_ticket(info) if 'reports' in info: info['reports'].sort(lambda a, b: -cmp(a['time'], b['time'])) else: info['reports'] = [] base_reports = base_reports_by_machine_and_base() old_reports = list(info['reports']) patchbot.prune_pending(info) if old_reports != info['reports']: db.save_ticket(info) 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 preprocess_reports(all): for item in all: base_report = base_reports.get(item['base'] + "/" + "/".join(item['machine']), base_reports.get(item['base'])) if base_report: item['base_log'] = urllib.quote(log_name(0, base_report)) if 'patches' in item: required = info['depends_on'] + info['patches'] item['patch_list'] = format_patches(ticket, item['patches'], item.get('deps'), required) item['raw_base'] = item['base'] if item['base'] != base: item['base'] = "<span style='color: red'>%s</span>" % item['base'] if 'time' in item: item['log'] = log_name(info['id'], item) yield item def normalize_plugin(plugin): while len(plugin) < 3: plugin.append(None) return plugin return render_template("ticket.html", reports=preprocess_reports(info['reports']), ticket=ticket, info=format_info(info), status=get_ticket_status(info, base=base)[2], normalize_plugin=normalize_plugin)
def render_ticket(ticket): try: info = trac.scrape(ticket, db=db, force='force' in request.args) except: info = tickets.find_one({'id': ticket}) if info is None: return "No such ticket." if 'kick' in request.args: info['retry'] = True db.save_ticket(info) if 'reports' in info: info['reports'].sort(lambda a, b: -cmp(a['time'], b['time'])) else: info['reports'] = [] base_reports = base_reports_by_machine_and_base() old_reports = list(info['reports']) patchbot.prune_pending(info) if old_reports != info['reports']: db.save_ticket(info) 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 = {} 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.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 base = latest_base() def format_git_describe(res): if res: if '-' in res: tag, commits = res.split('-')[:2] return "%s + %s commits" % (tag, commits) elif 'commits' in res: # old style return res else: return res + " + 0 commits" else: return '?' def preprocess_reports(all): for item in all: base_report = base_reports.get(item['base'] + "/" + "/".join(item['machine']), base_reports.get(item['base'])) if base_report: item['base_log'] = urllib.quote(log_name(0, base_report)) if 'patches' in item: required = info['depends_on'] + info['patches'] item['patch_list'] = format_patches(ticket, item['patches'], item.get('deps'), required) if 'git_base' in item: git_log = item.get('git_log') item['git_log_len'] = '?' if git_log is None else len(git_log) item['raw_base'] = item['base'] if compare_version(item['base'], base) < 0: item['base'] = "<span style='color: red'>%s</span>" % item['base'] if 'time' in item: item['log'] = log_name(info['id'], item) if 'git_commit_human' not in item: item['git_commit_human'] = "%s new commits" % len(item['log']) for x in ('commit', 'base', 'merge'): field = 'git_%s_human' % x item[field] = format_git_describe(item.get(field, None)) yield item def normalize_plugin(plugin): while len(plugin) < 3: plugin.append(None) return plugin def sort_fields(items): return sorted(items, key=(lambda x: (x[0] != 'title', x))) return render_template("ticket.html", reports=preprocess_reports(info['reports']), ticket=ticket, info=format_info(info), status=get_ticket_status(info, base=base)[2], normalize_plugin=normalize_plugin, sort_fields=sort_fields)
def render_ticket(ticket): """ reports on a given ticket possible options: ?force and ?kick ?force will refresh the info in the patchbot-server database ?kick will tell the patchbot-clients to retry the ticket ?base to select reports according to their base """ latest = latest_base() if 'base' in request.args: chosen_base = request.args.get('base') else: chosen_base = 'all' if ticket != 0 else 'develop' if chosen_base == 'latest' or chosen_base == 'develop': chosen_base = latest try: info = scrape(ticket, db=db, force='force' in request.args) except: info = tickets.find_one({'id': ticket}) if info is None: return "No such ticket." if 'kick' in request.args: info['retry'] = True db.save_ticket(info) if 'reports' in info: info['reports'].sort(lambda a, b: -cmp(a['time'], b['time'])) else: info['reports'] = [] base_reports = base_reports_by_machine_and_base() old_reports = list(info['reports']) prune_pending(info) if old_reports != info['reports']: db.save_ticket(info) 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 format_git_describe(res): if res: if '-' in res: tag, commits = res.split('-')[:2] return "%s + %s commits" % (tag, commits) elif 'commits' in res: # old style return res else: return res + " + 0 commits" else: return '?' def preprocess_reports(all): for item in all: base_of_this_report = item['base'] base_report = base_reports.get(item['base'] + "/" + "/".join(item['machine']), base_reports.get(item['base'])) if base_report: item['base_log'] = quote(log_name(0, base_report)) if 'git_base' in item: git_log = item.get('git_log') item['git_log_len'] = '?' if git_log is None else len(git_log) item['raw_base'] = item['base'] if compare_version(item['base'], latest) < 0: item['base'] = "<span style='color: red'>%s</span>" % item['base'] if 'time' in item: item['log'] = log_name(info['id'], item) if 'git_commit_human' not in item: item['git_commit_human'] = "%s new commits" % len(item['log']) for x in ('commit', 'base', 'merge'): field = 'git_%s_human' % x item[field] = format_git_describe(item.get(field, None)) if chosen_base == 'all' or chosen_base == base_of_this_report: yield item def normalize_plugin(plugin): while len(plugin) < 3: plugin.append(None) return plugin def sort_fields(items): return sorted(items, key=(lambda x: (x[0] != 'title', x))) status_data = get_ticket_status(info, base=latest)[1] # single status return render_template("ticket.html", reports=preprocess_reports(info['reports']), ticket=ticket, info=format_info(info), status=status_data, normalize_plugin=normalize_plugin, sort_fields=sort_fields)