def delete_confirmed(): form = pandokia.pcgi.form test_run = form.getfirst("test_run") project = form.getfirst('project', '*') context = form.getfirst('context', '*') custom = form.getfirst('custom', '*') host = form.getfirst('host', '*') where_str, where_dict = pdk_db.where_dict([('test_run', test_run), ('project', project), ('context', context), ('custom', custom), ('host', host)]) sys.stdout.write(common.cgi_header_html) sys.stdout.write(common.page_header()) if pandokia.cleaner.check_valuable(test_run): print("valuable test run - There should not be a link that comes here") return my_run_prefix = 'user_' + common.current_user() admin = common.current_user() in common.cfg.admin_user_list if not (admin or test_run.startswith(my_run_prefix)): print("You (%s) can't do that" % common.current_user()) else: print("Deleteing...") sys.stdout.flush() # make a dummy record, so we know that we can never delete the # last record created. pandokia.cleaner.block_last_record() # delete_run is chatty, so we <pre> around it print("<pre>") print("working...") sys.stdout.flush() cleaner.delete_by_query(where_str, where_dict) if project == '*' and context == '*' and host == '*': print("delete from index") pdk_db.execute("DELETE FROM distinct_test_run WHERE test_run = :1", (test_run, )) pdk_db.commit() print("done.") print("</pre>") sys.stdout.flush()
def delete_confirmed(): form = pandokia.pcgi.form test_run = form.getfirst("test_run") project = form.getfirst('project', '*') context = form.getfirst('context', '*') custom = form.getfirst('custom', '*') host = form.getfirst('host', '*') where_str, where_dict = pdk_db.where_dict( [('test_run', test_run), ('project', project), ('context', context), ('custom', custom), ('host', host)]) sys.stdout.write(common.cgi_header_html) sys.stdout.write(common.page_header()) if pandokia.cleaner.check_valuable(test_run): print("valuable test run - There should not be a link that comes here") return my_run_prefix = 'user_' + common.current_user() admin = common.current_user() in common.cfg.admin_user_list if not (admin or test_run.startswith(my_run_prefix)): print("You (%s) can't do that" % common.current_user()) else: print("Deleteing...") sys.stdout.flush() # make a dummy record, so we know that we can never delete the # last record created. pandokia.cleaner.block_last_record() # delete_run is chatty, so we <pre> around it print("<pre>") print("working...") sys.stdout.flush() cleaner.delete_by_query(where_str, where_dict) if project == '*' and context == '*' and host == '*': print("delete from index") pdk_db.execute( "DELETE FROM distinct_test_run WHERE test_run = :1", (test_run,)) pdk_db.commit() print("done.") print("</pre>") sys.stdout.flush()
def run(): if cfg.debug: cgitb.enable() if cfg.server_maintenance: sys.stdout.write( "content-type: text/html\n\n\nWeb page unavailable because of pandokia server maintenance<p>\n\n" ) if isinstance(cfg.server_maintenance, basestring): sys.stdout.write("%s\n" % cfg.server_maintenance) sys.exit(0) ###### # # check authentication # #--#--# CGI if not common.check_auth(): # If authentication fails, I'm not concerned about giving # a particularly useful message. sys.stdout.write( "content-type: text/html\n\n\nAUTHENTICATION FAILED\n\n") sys.exit(0) ###### # # various forms of links to ourself # # cginame is the name of the cgi, for use in generating html links to ourself. # This is NOT the full URL -- it is only the path on this host. We cannot # know the host name part of the URL (e.g. if the web connection is coming # through an ssh tunnel). # #--#--# CGI global cginame cginame = os.getenv("SCRIPT_NAME") ###### # # fetch the cgi parameters # global form form = cgi.FieldStorage(keep_blank_values=1) ###### # # output_format is the output format requested; each query type must # either know what to do for each possible format # possible values are: # 'html' (MUST be default) # 'csv' global output_format if 'format' in form: output_format = form['format'].value else: output_format = "html" ###### # # if we don't have a query field, show the top-level menu and we are done. # #--#--# CGI if not form.has_key("query"): import re sys.stdout.write("Content-type: text/html\n\n") f = os.path.dirname(os.path.abspath(__file__)) + '/top_level.html' header = common.page_header() f = open(f, "r") x = f.read() f.close() if common.current_user() in common.cfg.admin_user_list: x = re.sub("ADMINLINK", '<br> <a href=CGINAME?query=admin>Admin</a> <br>', x) else: x = re.sub("ADMINLINK", '', x) x = re.sub("CGINAME", cginame, x) x = re.sub("PAGEHEADER", header, x) sys.stdout.write(x) sys.exit(0) ###### # # if we get here, we are processing a query. # # There various modules to implement the known query types. #--#--# CGI query = form["query"].value if query == "treewalk": import pandokia.pcgi_treewalk as x x.treewalk() sys.exit(0) if query == "qid_op": import pandokia.pcgi_qid_op as x x.run() sys.exit(0) if query == 'qid_list': import pandokia.pcgi_qid_op as x x.qid_list() sys.exit(0) if query == "treewalk.linkout": import pandokia.pcgi_treewalk as x x.linkout() sys.exit(0) if query == "summary": import pandokia.pcgi_summary as x x.run() sys.exit(0) if query == "detail": import pandokia.pcgi_detail as x x.run() sys.exit(0) if query == "test_history": import pandokia.pcgi_detail as x x.test_history() sys.exit(0) if query.startswith("day_report."): import pandokia.pcgi_day_report as x if query == "day_report.1": x.rpt1() if query == "day_report.2": x.rpt2() if query == "day_report.3": x.rpt3() sys.exit(0) if query.startswith("delete_run."): import pandokia.pcgi_delete as x if query == "delete_run.ays": x.delete_are_you_sure() if query == "delete_run.conf": x.delete_confirmed() sys.exit(0) if query == 'flagok': import pandokia.pcgi_flagok as x x.flagok() sys.exit(0) if query == 'action': import pandokia.pcgi_action as x x.run() sys.exit(0) if query == 'prefs': import pandokia.pcgi_preferences as x x.run() sys.exit(0) if query == 'killproc': print "content-type: text/html" print "" pid = form['pid'].value sig = form['sig'].value if common.current_user() in common.cfg.admin_user_list: os.kill(int(pid), int(sig)) print "done" sys.exit(0) if query == 'hostinfo': import pandokia.pcgi_misc as x x.hostinfo() sys.exit(0) if query == 'set_hostinfo': import pandokia.pcgi_misc as x x.set_hostinfo() sys.exit(0) if query == 'magic_html_log': import pandokia.pcgi_detail as x x.magic_html_log() sys.exit(0) if query == 'expected': import pandokia.pcgi_misc as x x.expected() sys.exit(0) if query == 'new': import pandokia.pcgi_reports as x x.cluster_report() sys.exit(0) if query == 'latest': import pandokia.pcgi_misc as x x.latest() sys.exit(0) error_1201() # # You can't get here by following links, so you must have typed in the # url directly. In that case, you are messing with us and you get no # friendly response. if cfg.debug or (common.current_user() in common.cfg.admin_user_list): print "YOU ARE ADMIN, DEBUG FOLLOWS" for x in form: if isinstance(form[x], list): for y in form[x]: print x, y, "<br>" else: print x, form[x], "<br>"
def run(): if cfg.debug: cgitb.enable() if cfg.server_maintenance: sys.stdout.write( "content-type: text/html\n\n\nWeb page unavailable because of pandokia server maintenance<p>\n\n") if isinstance(cfg.server_maintenance, str): sys.stdout.write("%s\n" % cfg.server_maintenance) sys.exit(0) ###### # # check authentication # #--#--# CGI if not common.check_auth(): # If authentication fails, I'm not concerned about giving # a particularly useful message. sys.stdout.write( "content-type: text/html\n\n\nAUTHENTICATION FAILED\n\n") sys.exit(0) ###### # # various forms of links to ourself # # cginame is the name of the cgi, for use in generating html links to ourself. # This is NOT the full URL -- it is only the path on this host. We cannot # know the host name part of the URL (e.g. if the web connection is coming # through an ssh tunnel). # #--#--# CGI global cginame cginame = os.getenv("SCRIPT_NAME") ###### # # fetch the cgi parameters # global form form = cgi.FieldStorage(keep_blank_values=1) ###### # # output_format is the output format requested; each query type must # either know what to do for each possible format # possible values are: # 'html' (MUST be default) # 'csv' global output_format if 'format' in form: output_format = form.getvalue('format') else: output_format = "html" ###### # # if we don't have a query field, show the top-level menu and we are done. # #--#--# CGI if "query" not in form: import re sys.stdout.write("Content-type: text/html\n\n") f = os.path.dirname(os.path.abspath(__file__)) + '/top_level.html' header = common.page_header() f = open(f, "r") x = f.read() f.close() if common.current_user() in common.cfg.admin_user_list: x = re.sub( "ADMINLINK", '<br> <a href=CGINAME?query=admin>Admin</a> <br>', x) else: x = re.sub("ADMINLINK", '', x) x = re.sub("CGINAME", cginame, x) x = re.sub("PAGEHEADER", header, x) sys.stdout.write(x) sys.exit(0) ###### # # if we get here, we are processing a query. # # There various modules to implement the known query types. #--#--# CGI query = form.getvalue("query") if query == "treewalk": import pandokia.pcgi_treewalk as x x.treewalk() sys.exit(0) if query == "qid_op": import pandokia.pcgi_qid_op as x x.run() sys.exit(0) if query == 'qid_list': import pandokia.pcgi_qid_op as x x.qid_list() sys.exit(0) if query == "treewalk.linkout": import pandokia.pcgi_treewalk as x x.linkout() sys.exit(0) if query == "summary": import pandokia.pcgi_summary as x x.run() sys.exit(0) if query == "detail": import pandokia.pcgi_detail as x x.run() sys.exit(0) if query == "test_history": import pandokia.pcgi_detail as x x.test_history() sys.exit(0) if query.startswith("day_report."): import pandokia.pcgi_day_report as x if query == "day_report.1": x.rpt1() if query == "day_report.2": x.rpt2() if query == "day_report.3": x.rpt3() sys.exit(0) if query.startswith("delete_run."): import pandokia.pcgi_delete as x if query == "delete_run.ays": x.delete_are_you_sure() if query == "delete_run.conf": x.delete_confirmed() sys.exit(0) if query == 'flagok': import pandokia.pcgi_flagok as x x.flagok() sys.exit(0) if query == 'action': import pandokia.pcgi_action as x x.run() sys.exit(0) if query == 'prefs': import pandokia.pcgi_preferences as x x.run() sys.exit(0) if query == 'killproc': print("content-type: text/html") print("") pid = form.getvalue('pid') sig = form.getvalue('sig') if common.current_user() in common.cfg.admin_user_list: os.kill(int(pid), int(sig)) print("done") sys.exit(0) if query == 'hostinfo': import pandokia.pcgi_misc as x x.hostinfo() sys.exit(0) if query == 'set_hostinfo': import pandokia.pcgi_misc as x x.set_hostinfo() sys.exit(0) if query == 'magic_html_log': import pandokia.pcgi_detail as x x.magic_html_log() sys.exit(0) if query == 'expected': import pandokia.pcgi_misc as x x.expected() sys.exit(0) if query == 'new': import pandokia.pcgi_reports as x x. cluster_report() sys.exit(0) if query == 'latest': import pandokia.pcgi_misc as x x.latest() sys.exit(0) error_1201() # # You can't get here by following links, so you must have typed in the # url directly. In that case, you are messing with us and you get no # friendly response. if cfg.debug or (common.current_user() in common.cfg.admin_user_list): print("YOU ARE ADMIN, DEBUG FOLLOWS") for x in form: if isinstance(form[x], list): for y in form[x]: print("%s %s<br>" % (x, y)) else: print("%s %s<br>" % (x, form.getvalue(x)))
def gen_daily_table(test_run, projects, query_context, query_host, valuable=0, chronic=False): # chronic is true if we should do the chronic column, false otherwise # convert special names, e.g. daily_latest to the name of the latest daily_* test_run = common.find_test_run(test_run) # show_delete = not valuable if show_delete: my_run_prefix = 'user_' + common.current_user() if test_run.startswith(my_run_prefix): del_text = '(del)' else: if common.current_user() in common.cfg.admin_user_list: del_text = '<font color=gray>(del)</font>' else: show_delete = False # this is the skeleton of the cgi queries for various links query = {"test_run": test_run} # This is a single table for all projects, because we want the # pass/fail/error columns to be aligned from one to the next # table = text_table.text_table() # The texttable object doesn't understand colspans, but we hack a # colspan into it anyway. Thee result is ugly if you have borders. table.set_html_table_attributes("cellpadding=2 ") status_types = common.cfg.statuses row = 0 table.define_column("host") table.define_column("context") table.define_column("os") table.define_column("total") for x in status_types: table.define_column(x) if chronic: table.define_column("chronic") table.define_column("del") table.define_column("note") n_cols = 3 + len(status_types) + 2 # # # # # # # # # # # loop across hosts prev_project = None all_sum = {'total': 0, 'chronic': 0} for status in status_types: all_sum[status] = 0 hc_where, hc_where_dict = pdk_db.where_dict([('test_run', test_run), ('project', projects), ('context', query_context), ('host', query_host)]) c = pdk_db.execute( "SELECT DISTINCT project, host, context FROM result_scalar %s ORDER BY project, host, context " % hc_where, hc_where_dict) if chronic: chronic_str = "AND ( chronic = '0' or chronic IS NULL )" else: chronic_str = "" # now we forget the list of projects that came in and construct a # list of projects that we actually saw. projects = [] for project, host, context in c: ## make a new project section of the table if project != prev_project: projects.append(project) table.set_value(row, 0, "") prev_project = project # values common to all the links we will write in this pass through the loop query["project"] = project query["host"] = "%" # this link text is common to all the links for this project link = common.selflink(query_dict=query, linkmode="treewalk") # the heading for a project subsection of the table project_text = cgi.escape(project) project_text = '<hr><big><strong><b><a name="%s" href="%s">%s</a></b></strong></big>' % ( project_text, link, project_text) table.set_value(row, 0, text=project, html=project_text) table.set_html_cell_attributes(row, 0, "colspan=%d" % n_cols) row += 1 # the column headings for this project's part of the table insert_col_headings(table, row, link, chronic) row += 1 # This will be the sum of all the tests in a particular project. # It comes just under the headers for the project, but we don't # know the values until the end. project_sum = {'total': 0, 'chronic': 0} for status in status_types: project_sum[status] = 0 project_sum_row = row # delete entire project from the test run if show_delete: table.set_value(row, 'del', html=del_text, link=delete_link( { 'test_run': test_run, 'project': project }, show_delete)) row += 1 prev_host = None # a new host/contest line query["host"] = host link = common.selflink(query_dict=query, linkmode="treewalk") if host != prev_host: table.set_value(row, 0, text=host, link=link) prev_host = host query['context'] = context link = common.selflink(query_dict=query, linkmode="treewalk") del query['context'] table.set_value(row, 1, text=context, link=link) # delete entire project from the test run if show_delete: table.set_value(row, 'del', html=del_text, link=delete_link( { 'test_run': test_run, 'project': project, 'host': host, 'context': context }, show_delete)) # show the host info hinfo = pandokia.common.hostinfo(host) table.set_value(row, 2, text=hinfo[1], link=common.selflink(query_dict={'host': host}, linkmode='hostinfo')) total_results = 0 missing_count = 0 for status in status_types: # use "or chronic is null" until we update the database for the new schema. c1 = pdk_db.execute( "SELECT COUNT(*) FROM result_scalar WHERE test_run = :1 AND project = :2 AND host = :3 AND status = :4 AND context = :5 %s" % (chronic_str, ), (test_run, project, host, status, context)) (x, ) = c1.fetchone() total_results += x project_sum[status] += x all_sum[status] += x if x == 0: table.set_value(row, status, text='0') else: table.set_value(row, status, text=str(x), link=link + "&status=" + status) table.set_html_cell_attributes(row, status, 'align="right"') if status == 'M': missing_count = x if chronic: c1 = pdk_db.execute( "SELECT COUNT(*) FROM result_scalar WHERE test_run = :1 AND project = :2 AND host = :3 AND context = :5 AND chronic = '1'", (test_run, project, host, status, context)) (x, ) = c1.fetchone() total_results += x project_sum['chronic'] += x all_sum['chronic'] += x table.set_value(row, 'chronic', text=str(x), link=link + "&chronic=1") table.set_html_cell_attributes(row, 'chronic', 'align="right"') project_sum['total'] += total_results all_sum['total'] += total_results if 0 and 'M' in status_types: # not sure how to deal with this in the presence of chronic problem tests if missing_count != 0: if missing_count == total_results: # if it equals the total, then everything is missing; we make a note of that table.set_value(row, 'note', 'all missing') else: # only some of them are missing table.set_value(row, 'note', 'some missing') table.set_value(row, 'total', text=str(total_results), link=link) table.set_html_cell_attributes(row, 'total', 'align="right"') row = row + 1 for status in status_types: table.set_value(project_sum_row, status, project_sum[status]) table.set_html_cell_attributes( project_sum_row, status, 'align="right" style="font-weight:bold"') table.set_value(project_sum_row, 'total', project_sum['total']) table.set_html_cell_attributes( project_sum_row, 'total', 'align="right" style="font-weight:bold"') # insert this blank line between projects - keeps the headings away from the previous row table.set_value(row, 0, "") # insert a total for everything table.set_value(row, 0, html='<hr>') table.set_html_cell_attributes(row, 0, "colspan=%d" % n_cols) row = row + 1 insert_col_headings(table, row, None, chronic) row = row + 1 total_row = row query['host'] = '*' query['project'] = projects query['host'] = query_host query['context'] = query_context table.set_value(total_row, 'total', text=str(all_sum['total']), link=common.selflink(query_dict=query, linkmode="treewalk")) table.set_html_cell_attributes(row, 'total', 'align="right"') for status in status_types: query['status'] = status table.set_value(total_row, status, all_sum[status], link=common.selflink(query_dict=query, linkmode="treewalk")) table.set_html_cell_attributes(total_row, status, 'align="right"') return (table, projects)
def rpt1(): form = pandokia.pcgi.form if form.has_key("test_run"): test_run = form["test_run"].value else: test_run = '*' if test_run == '-me': test_run = 'user_' + common.current_user() + '_*' my_run_prefix = 'user_' + common.current_user() admin = common.current_user() in common.cfg.admin_user_list # c = db.execute("SELECT DISTINCT test_run FROM result_scalar WHERE test_run GLOB ? ORDER BY test_run DESC ",( test_run,)) where_str, where_dict = pdk_db.where_dict([('test_run', test_run)]) sql = "SELECT test_run, valuable, record_count, note, min_time, max_time FROM distinct_test_run %s ORDER BY test_run DESC " % where_str c = pdk_db.execute(sql, where_dict) table = text_table.text_table() table.set_html_table_attributes("border=1") table.define_column('addval', showname='') table.define_column('run', showname='test_run') table.define_column('tree', showname='') table.define_column('del', showname='') table.define_column('min', showname='start') table.define_column('max', showname='end') table.define_column('tdiff', showname='duration') table.define_column('count', showname='records') table.define_column('note', showname='note') # query parameters for various links # link to day_report # link to tree walk of test run tquery = {'project': '*', 'host': '*'} # link to declare a run as valuable vquery = {'valuable_run': 1} # link to update the count in a test run cquery = {} row = 0 for x, val, record_count, note, min_time, max_time in c: if x is None: continue tquery["test_run"] = x vquery["test_run"] = x cquery["count_run"] = x # mark as valuable: # https://ssb.stsci.edu/pandokia/c41.cgi?query=action&test_run=daily_2011-08-24&valuable_run=1 table.set_value(row, 'addval', html='<a href="%s">!</a> ' % common.selflink(vquery, "action")) table.set_value(row, 'run', text=x, link=common.selflink(tquery, "day_report.2")) table.set_value(row, 'tree', text='(tree display)', link=common.selflink(tquery, "treewalk")) if val == '0': if x.startswith(my_run_prefix): table.set_value(row, 'del', text='(delete)', link=common.selflink(tquery, "delete_run.ays")) else: table.set_value(row, 'del', text='(delete)', html='<font color=gray>(delete)</font>', link=common.selflink(tquery, "delete_run.ays")) else: table.set_value(row, 'del', text='(valuable)') if note is None: table.set_value(row, 'note', text='') else: table.set_value(row, 'note', text=note) if min_time is not None and max_time is not None: table.set_value(row, 'tdiff', str(lib.time_diff(max_time, min_time))) min_time = str(min_time).split('.')[0] max_time = str(max_time).split('.')[0] t1 = min_time.split() t2 = max_time.split() if len(t2) > 1 and len(t1) > 1 and t1[0] == t2[0] and len(t2) > 1: max_time = t2[1] table.set_value(row, 'min', text=min_time) table.set_value(row, 'max', text=max_time) else: if min_time is not None: min_time = str(min_time).split('.')[0] table.set_value(row, 'min', text=min_time) if max_time is not None: max_time = str(max_time).split('.')[0] table.set_value(row, 'max', text=max_time) table.set_value(row, 'tdiff', '') # update the count field # https://ssb.stsci.edu/pandokia/c41.cgi?query=action&count_run=daily_2011-08-24 update_count = common.selflink(cquery, 'action') if record_count is None or record_count <= 0: record_count = ' ' table.set_value(row, 'count', html=str(record_count), link=update_count) row = row + 1 if pandokia.pcgi.output_format == 'html': sys.stdout.write(common.cgi_header_html) sys.stdout.write(common.page_header()) sys.stdout.write('<h2>%s</h2>' % cgi.escape(test_run)) sys.stdout.write(table.get_html(headings=1)) sys.stdout.write( "<br>Click on the ! to mark a test run as too valuable to delete\n" ) sys.stdout.write( "<br>Click on record count to check the count and update it\n") sys.stdout.write("""<style> table { border-collapse: collapse; } table, th, td { border: 2px solid black; padding: 3px; } </style> """) elif pandokia.pcgi.output_format == 'csv': sys.stdout.write(common.cgi_header_csv) sys.stdout.write(table.get_csv()) sys.stdout.flush() return
def gen_daily_table( test_run, projects, query_context, query_host, valuable=0, chronic=False): # chronic is true if we should do the chronic column, false otherwise # convert special names, e.g. daily_latest to the name of the latest # daily_* test_run = common.find_test_run(test_run) # show_delete = not valuable if show_delete: my_run_prefix = 'user_' + common.current_user() if test_run.startswith(my_run_prefix): del_text = '(del)' else: if common.current_user() in common.cfg.admin_user_list: del_text = '<font color=gray>(del)</font>' else: show_delete = False # this is the skeleton of the cgi queries for various links query = {"test_run": test_run} # This is a single table for all projects, because we want the # pass/fail/error columns to be aligned from one to the next # table = text_table.text_table() # The texttable object doesn't understand colspans, but we hack a # colspan into it anyway. Thee result is ugly if you have borders. table.set_html_table_attributes("cellpadding=2 ") status_types = common.cfg.statuses row = 0 table.define_column("host") table.define_column("context") table.define_column("os") table.define_column("total") for x in status_types: table.define_column(x) if chronic: table.define_column("chronic") table.define_column("del") table.define_column("note") n_cols = 3 + len(status_types) + 2 # # # # # # # # # # # loop across hosts prev_project = None all_sum = {'total': 0, 'chronic': 0} for status in status_types: all_sum[status] = 0 hc_where, hc_where_dict = pdk_db.where_dict( [('test_run', test_run), ('project', projects), ('context', query_context), ('host', query_host)]) c = pdk_db.execute( "SELECT DISTINCT project, host, context FROM result_scalar %s ORDER BY project, host, context " % hc_where, hc_where_dict) if chronic: chronic_str = "AND ( chronic = '0' or chronic IS NULL )" else: chronic_str = "" # now we forget the list of projects that came in and construct a # list of projects that we actually saw. projects = [] for project, host, context in c: # make a new project section of the table if project != prev_project: projects.append(project) table.set_value(row, 0, "") prev_project = project # values common to all the links we will write in this pass through # the loop query["project"] = project query["host"] = "%" # this link text is common to all the links for this project link = common.selflink(query_dict=query, linkmode="treewalk") # the heading for a project subsection of the table project_text = cgi.escape(project) project_text = '<hr><big><strong><b><a name="%s" href="%s">%s</a></b></strong></big>' % ( project_text, link, project_text) table.set_value(row, 0, text=project, html=project_text) table.set_html_cell_attributes(row, 0, "colspan=%d" % n_cols) row += 1 # the column headings for this project's part of the table insert_col_headings(table, row, link, chronic) row += 1 # This will be the sum of all the tests in a particular project. # It comes just under the headers for the project, but we don't # know the values until the end. project_sum = {'total': 0, 'chronic': 0} for status in status_types: project_sum[status] = 0 project_sum_row = row # delete entire project from the test run if show_delete: table.set_value(row, 'del', html=del_text, link=delete_link( {'test_run': test_run, 'project': project}, show_delete)) row += 1 prev_host = None # a new host/contest line query["host"] = host link = common.selflink(query_dict=query, linkmode="treewalk") if host != prev_host: table.set_value(row, 0, text=host, link=link) prev_host = host query['context'] = context link = common.selflink(query_dict=query, linkmode="treewalk") del query['context'] table.set_value(row, 1, text=context, link=link) # delete entire project from the test run if show_delete: table.set_value(row, 'del', html=del_text, link=delete_link({'test_run': test_run, 'project': project, 'host': host, 'context': context}, show_delete)) # show the host info hinfo = pandokia.common.hostinfo(host) table.set_value( row, 2, text=hinfo[1], link=common.selflink( query_dict={ 'host': host}, linkmode='hostinfo')) total_results = 0 missing_count = 0 for status in status_types: # use "or chronic is null" until we update the database for the new # schema. c1 = pdk_db.execute( "SELECT COUNT(*) FROM result_scalar WHERE test_run = :1 AND project = :2 AND host = :3 AND status = :4 AND context = :5 %s" % (chronic_str, ), (test_run, project, host, status, context)) (x,) = c1.fetchone() total_results += x project_sum[status] += x all_sum[status] += x if x == 0: table.set_value(row, status, text='0') else: table.set_value( row, status, text=str(x), link=link + "&status=" + status) table.set_html_cell_attributes(row, status, 'align="right"') if status == 'M': missing_count = x if chronic: c1 = pdk_db.execute( "SELECT COUNT(*) FROM result_scalar WHERE test_run = :1 AND project = :2 AND host = :3 AND context = :5 AND chronic = '1'", (test_run, project, host, status, context)) (x,) = c1.fetchone() total_results += x project_sum['chronic'] += x all_sum['chronic'] += x table.set_value( row, 'chronic', text=str(x), link=link + "&chronic=1") table.set_html_cell_attributes(row, 'chronic', 'align="right"') project_sum['total'] += total_results all_sum['total'] += total_results if 0 and 'M' in status_types: # not sure how to deal with this in the presence of chronic problem # tests if missing_count != 0: if missing_count == total_results: # if it equals the total, then everything is missing; we # make a note of that table.set_value(row, 'note', 'all missing') else: # only some of them are missing table.set_value(row, 'note', 'some missing') table.set_value(row, 'total', text=str(total_results), link=link) table.set_html_cell_attributes(row, 'total', 'align="right"') row = row + 1 for status in status_types: table.set_value(project_sum_row, status, project_sum[status]) table.set_html_cell_attributes( project_sum_row, status, 'align="right" style="font-weight:bold"') table.set_value(project_sum_row, 'total', project_sum['total']) table.set_html_cell_attributes( project_sum_row, 'total', 'align="right" style="font-weight:bold"') # insert this blank line between projects - keeps the headings away # from the previous row table.set_value(row, 0, "") # insert a total for everything table.set_value(row, 0, html='<hr>') table.set_html_cell_attributes(row, 0, "colspan=%d" % n_cols) row = row + 1 insert_col_headings(table, row, None, chronic) row = row + 1 total_row = row query['host'] = '*' query['project'] = projects query['host'] = query_host query['context'] = query_context table.set_value(total_row, 'total', text=str(all_sum['total']), link=common.selflink(query_dict=query, linkmode="treewalk") ) table.set_html_cell_attributes(row, 'total', 'align="right"') for status in status_types: query['status'] = status table.set_value( total_row, status, all_sum[status], link=common.selflink( query_dict=query, linkmode="treewalk")) table.set_html_cell_attributes(total_row, status, 'align="right"') return (table, projects)
def rpt1(): form = pandokia.pcgi.form if "test_run" in form: test_run = form.getvalue("test_run") else: test_run = '*' if test_run == '-me': test_run = 'user_' + common.current_user() + '_*' my_run_prefix = 'user_' + common.current_user() admin = common.current_user() in common.cfg.admin_user_list # c = db.execute("SELECT DISTINCT test_run FROM result_scalar WHERE test_run GLOB ? ORDER BY test_run DESC ",( test_run,)) where_str, where_dict = pdk_db.where_dict([('test_run', test_run)]) sql = "SELECT test_run, valuable, record_count, note, min_time, max_time FROM distinct_test_run %s ORDER BY test_run DESC " % where_str c = pdk_db.execute(sql, where_dict) table = text_table.text_table() table.set_html_table_attributes("border=1") table.define_column('addval', showname='') table.define_column('run', showname='test_run') table.define_column('tree', showname='') table.define_column('del', showname='') table.define_column('min', showname='start') table.define_column('max', showname='end') table.define_column('tdiff', showname='duration') table.define_column('count', showname='records') table.define_column('note', showname='note') # query parameters for various links # link to day_report # link to tree walk of test run tquery = {'project': '*', 'host': '*'} # link to declare a run as valuable vquery = {'valuable_run': 1} # link to update the count in a test run cquery = {} row = 0 for x, val, record_count, note, min_time, max_time in c: if x is None: continue tquery["test_run"] = x vquery["test_run"] = x cquery["count_run"] = x # mark as valuable: # https://ssb.stsci.edu/pandokia/c41.cgi?query=action&test_run=daily_2011-08-24&valuable_run=1 table.set_value( row, 'addval', html='<a href="%s">!</a> ' % common.selflink( vquery, "action")) table.set_value( row, 'run', text=x, link=common.selflink( tquery, "day_report.2")) table.set_value( row, 'tree', text='(tree display)', link=common.selflink( tquery, "treewalk")) if val == '0': if x.startswith(my_run_prefix): table.set_value( row, 'del', text='(delete)', link=common.selflink( tquery, "delete_run.ays")) else: table.set_value( row, 'del', text='(delete)', html='<font color=gray>(delete)</font>', link=common.selflink( tquery, "delete_run.ays")) else: table.set_value(row, 'del', text='(valuable)') if note is None: table.set_value(row, 'note', text='') else: table.set_value(row, 'note', text=note) if min_time is not None and max_time is not None: table.set_value( row, 'tdiff', str( lib.time_diff( max_time, min_time))) min_time = str(min_time).split('.')[0] max_time = str(max_time).split('.')[0] t1 = min_time.split() t2 = max_time.split() if len(t2) > 1 and len(t1) > 1 and t1[0] == t2[0] and len(t2) > 1: max_time = t2[1] table.set_value(row, 'min', text=min_time) table.set_value(row, 'max', text=max_time) else: if min_time is not None: min_time = str(min_time).split('.')[0] table.set_value(row, 'min', text=min_time) if max_time is not None: max_time = str(max_time).split('.')[0] table.set_value(row, 'max', text=max_time) table.set_value(row, 'tdiff', '') # update the count field # https://ssb.stsci.edu/pandokia/c41.cgi?query=action&count_run=daily_2011-08-24 update_count = common.selflink(cquery, 'action') if record_count is None or record_count <= 0: record_count = ' ' table.set_value( row, 'count', html=str(record_count), link=update_count) row = row + 1 if pandokia.pcgi.output_format == 'html': sys.stdout.write(common.cgi_header_html) sys.stdout.write(common.page_header()) sys.stdout.write('<h2>%s</h2>' % cgi.escape(test_run)) sys.stdout.write(table.get_html(headings=1)) sys.stdout.write( "<br>Click on the ! to mark a test run as too valuable to delete\n") sys.stdout.write( "<br>Click on record count to check the count and update it\n") sys.stdout.write("""<style> table { border-collapse: collapse; } table, th, td { border: 2px solid black; padding: 3px; } </style> """) elif pandokia.pcgi.output_format == 'csv': sys.stdout.write(common.cgi_header_csv) sys.stdout.write(table.get_csv()) sys.stdout.flush() return