def add_topics(nutshell_directory, template_task_sheet, topics): for topic_num in reversed(range(1, 4)): topic = topics[topic_num - 1] # Front page topic circles topic_name_circle_html = div(_class='topic') with topic_name_circle_html: h5(topic["title"], id="topicName-summary") add_to_output(template_task_sheet, "topicsContainer", str(topic_name_circle_html)) # Pages for topic template_topic_page = openfile( os.path.join(nutshell_directory, "TaskSheetContent", "PremadeContent", "Weekly Task Sheet Templates", "TopicPageTemplate.html")) add_to_output(template_task_sheet, "topicPages", str(template_topic_page)) replace_in_output(template_task_sheet, "h1", "topicName-detailed", topic["title"]) add_section(template_task_sheet, topic, "learn", "Sorry, no learning resources available yet.", list(reversed(topic["learn"]))) add_section(template_task_sheet, topic, "homework", "No homework for this topic, you're welcome!", list(reversed(topic["n5w"]["homework"]))) add_section(template_task_sheet, topic, "exercises", "Sorry, no extra resources for this topic yet.", list(reversed(topic["n5w"]["exercises"])))
def upload_form(self): with tags.form( id=self.config['upload_name'], onsubmit=self.config['onsubmit'], enctype='multipart/form-data', method=self.config['upload_method'], action=self.config['upload_route'], cls='card p-3 bg-light'): tags.h5('Upload an image', cls='card-title') with tags.div(cls='form-group row'): with tags.div(cls='col-12'): # This requires JavaScript to show the filename. # https://github.com/Johann-S/bs-custom-file-input # # 'style' is necessary to avoid overlapping in Safari and # Chrome on iOS: # https://github.com/twbs/bootstrap/issues/26933 with tags.div(cls='custom-file', style='overflow: hidden;'): tags.input( type='file', cls='custom-file-input p-1 rounded', id=self.config['upload_name'], name=self.config['upload_name']) tags.label( 'Choose file', fr=self.config['upload_name'], cls='custom-file-label bg-light') with tags.div(cls='form-group row'): with tags.div(cls='col-3'): with tags.button(type='submit', cls='btn btn-primary'): util.text('Submit')
def get_ballot_details_td(row) -> td: disagreed_contests = json.loads(row['disagreed_info']) details_td = td(colspan='2') details_tr = div(cls='row') details_td += details_tr contests_mismatch = disagreed_contests.get('contests_mismatch') audit_col = div(h5('Audit'), cls='col') cvr_col = div(h5('CVR'), cls='col') details_tr += audit_col, cvr_col if contests_mismatch: audit_col += [ div(c) for c in contests_mismatch['audit_contests'].split(',') ] cvr_col += [ div(c) for c in contests_mismatch['cvr_contests'].split(',') ] excluded_col = div(h5('Excluded'), cls='col') excluded_col += [ div(c) for c in contests_mismatch['excluded_contests'].split(',') ] details_td += div(excluded_col, cls='row') return details_td style_df = ROIS_MAP_DF.loc[ROIS_MAP_DF['style'] == int(row['style'])] contests = style_df['contest'].unique() for contest in contests: if contest in disagreed_contests: audit_col += get_contest_row( contest=contest, cmpcvr_details=disagreed_contests[contest]['audit'], style_df=style_df) cvr_col += get_contest_row( contest=contest, cmpcvr_details=disagreed_contests[contest]['cvr'], style_df=style_df) return details_td
def get_contest_details(contest) -> div: """Return 'div' element with info about 'contest' instance and it's options. :param contest: Contest instance from which 'div' tag should be build. """ contest_attributes = [ ('name from OCR', contest.name), ('name from fuzzy matching', contest.fuzzy_name), ('name from alias', contest.alias_name), ('referendum header', contest.additional_text), ('question', contest.question), ('Yes/No contest', contest.bipolar), ('on page', contest.page + 1), ('vote for', contest.vote_for), ] title = contest.alias_name or contest.fuzzy_name or contest.name contest_container = div(id=title, cls='py-1') contest_container.add(h4(title, cls='mt-2')) contest_div = div(cls='col pl-4') for contest_key, contest_value in contest_attributes: contest_div.add( StyleSummary.get_details_row(contest_key, str(contest_value))) options_div = div() contest_div.add(h5('Options', cls='mt-2')) for option in reversed(contest.options): options_div.add(StyleSummary.get_option_details(option)) contest_div.add(options_div) contest_container.add(contest_div) return contest_container
def build_discrepancy_reports( precinct: str, precinct_agreed_df: pd.DataFrame, precinct_disagreed_df: pd.DataFrame, precinct_marks_df: pd.DataFrame) -> dominate.document: version = utils.show_version() doc = dominate.document(title='Audit Engine version: ' + version) report_head(doc) with doc: with div(cls='container'): report_headline(version) div(a('< Back', href='#', onclick='window.history.back()')) h5(precinct) for contest in precinct_marks_df['contest'].unique().tolist(): contest_disagreed_df = precinct_disagreed_df.loc[ precinct_disagreed_df['contest'] == contest] h6(contest) mount_discrepancy_table(contest, contest_disagreed_df, precinct_marks_df) return doc
def generate_resource_html(template_task_sheet, topic, image_url, header_text, p_text, resource_link, resource_type, row=1): resource_html = div(_class="learning-resource-container") with resource_html.add(div(_class="learning-resource")): img(id="learningResourceIcon", src=image_url) with resource_html.add(div(_class="learning-resource-text-container")): h5(header_text, id="learningResourceName") div(_class="learning-resource-types", id="learningResourceTypes").add(p_text) button_html = a(h5("Go ➔"), target="_blank", _class="learning-resource-link button", href=resource_link, id="learningResourceLink") if resource_type == "exercises": add_to_output( template_task_sheet, resource_type + "-" + str(row) + "-resources-container margin-top", str(resource_html)) add_to_output( template_task_sheet, resource_type + "-" + str(row) + "-resources-buttons-container", str(button_html)) else: add_to_output(template_task_sheet, resource_type + "-resources-container", str(resource_html)) add_to_output(template_task_sheet, resource_type + "-resources-buttons-container", str(button_html)) if resource_type == "homework": replace_in_output(template_task_sheet, "span", "homework-paragraph", topic) return {"body": resource_html, "button": button_html}
def url_form(self): with tags.form( id=self.config['url_name'], onsubmit=self.config['onsubmit'], method=self.config['url_method'], action=self.config['url_route'], cls='card p-3 bg-light'): tags.h5('Load an image from a URL', cls='card-title') with tags.div(cls='form-group row'): with tags.div(cls='col-12'): tags.input( type='url', cls='form-control p-1 bg-light rounded', name=self.config['url_name'], placeholder='https://example.com/image.png') with tags.div(cls='form-group row'): with tags.div(cls='col-3'): with tags.button(type='submit', cls='btn btn-primary'): util.text('Submit')
def product(file_in): file, remote = file_in prod = Product(file) with div() as di: h4(f"{type(prod).__name__}") with ul(): with li(): b("Description: ") span(mydescription(prod)) with li(): b("Descriptor: ") span(mydescriptor(prod)) with li(): b("Free field: ") span(myfreefield(prod)) with li(): b("Level: ") span(prod.level) with li(): b("File cadence: ") span(myfilecadence(prod)) with li(): b("Download example: ") a(remote, href=remote) h5("PRIMARY Header") hdul = fits.open(file) header2table(hdul["PRIMARY"].header) for extname in ["DATA", "CONTROL", "ENERGIES", "IDB_VERSIONS"]: try: data = read_qtable(file, hdu=extname, hdul=hdul) h5(f"Extension: '{extname}'") # header2table(hdu[extname].header) data2table(data, prod.level) except KeyError: pass return ((prod.level, prod.type, di))
def render(r): ta = dt.textarea(src.read_text(), id="cool-textarea") render.preview.send(dt.div(dt.h5("hello"), ta)) return []
def create_html_string(COUNTERS, BALLOTLISTS, DISAGREED_INFO_DICT): """Creates a HTML string for generating the summary file. Accesses the following: COUNTERS['ballots_processed'] COUNTERS['styles_detected'] COUNTERS['matched_ballots'] COUNTERS['non_matched_ballots'] COUNTERS['blank_ballots'] list of ballot OVERVOTED_BALLOTS list of ballot DISAGREED_BALLOTS accesses ballot pdf files per precinct and ballot_id DISAGREE_INFO_DICT is keyed by ballot_id which provides dict of contests providing error information f"{config_dict['RESOURCES_PATH']}{config_dict['DISAGREEMENTS_PATHFRAG']}{ballot.ballotdict['precinct']}/{ballot.ballotdict['ballot_id']}.pdf") list STYLES style.style_num style.number style.build_from_count files style_summary = glob.glob(f"{config_dict['RESOURCES_PATH']}{config_dict['STYLES_PATHFRAG']}{style.code}.html")[0] list VOTES_RESULTS (results for each contest) result_contest['contest_name'] result_contest['selections'] result_contest['vote_for'] result_contest['question'] result_contest['total_ballots'] result_contest['total_votes'] result_contest['undervote'] result_contest['overvote'] """ script_abs_path = os.path.abspath('assets/copy_to_clipboard.js') version = utils.show_version() doc = dominate.document(title='Audit Engine version: ' + version) with doc.head: link( rel='stylesheet', href= 'https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css', integrity= "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T", crossorigin="anonymous", ) script(type='text/javascript', src=script_abs_path) with doc: with div(cls='container'): with div(cls='jumbotron'): h1('Audit Engine: {version} - vote records summary'.format( version=version)) build_time = datetime.datetime.now(datetime.timezone.utc) p(f'Summary built at: {build_time.strftime("%Y-%m-%d %H:%M:%S")}', cls='lead') with table(cls='table table-striped'): with tbody(): with tr(): th('Number of ballots processed') td(COUNTERS['ballots_processed']) with tr(): th('Number of different ballot types') td(COUNTERS['styles_detected']) with tr(): th('Number of ballots matching the CVR results') td(COUNTERS['matched_ballots']) with tr(): th('Number of ballots not matching the CVR results') td(COUNTERS['non_matched_ballots']) with tr(): th('Number of completely blank ballots') td(COUNTERS['blank_ballots']) with tr(): th('Number of overvotes') td(COUNTERS['overvoted_ballots']) with tr(): th('Number of disagreements') td(COUNTERS['disagreed_ballots']) with div(cls='my-4'): h2('Styles') with table(cls='table table-striped'): with thead(): with tr(): th('Style code', scope="col") th('Style number', scope="col") th('Based on number of ballots', scope="col") th('Built at', scope="col") with tbody(): for style in STYLES: with tr(): utc_time = datetime.datetime.utcfromtimestamp( style.timestamp) style_summary = glob.glob( f"{config_dict['RESOURCES_PATH']}{config_dict['STYLES_PATHFRAG']}{style.code}.html" )[0] td( a(style.style_num, href=os.path.realpath(style_summary), target="_blank")) td(style.number) td(style.build_from_count) td(f'{utc_time.strftime("%Y-%m-%d %H:%M:%S")}') # Tables with contests results: with div(cls='my-4'): h2('Contests results') for result_contest in VOTES_RESULTS: contest_name = result_contest['contest_name'] selections = result_contest['selections'] vote_for = result_contest['vote_for'] question = result_contest['question'] with div(cls='my-4'): h5(f'Contest results "{contest_name}" (vote for {vote_for}):' ) if question: h6(f'Question "{question}"') with table(cls='table table-striped'): with thead(): with tr(): th('#', scope="col") th('Candidate', scope="col") th('Votes', scope="col") th('%', scope="col") with tbody(): for index, candidate_name in enumerate( sort_option_names(selections.keys())): try: total_votes = result_contest['total_votes'] percent = round( (selections[candidate_name] / total_votes) * 100, 2) except ZeroDivisionError: percent = 0.0 with tr(): th(index + 1, scope="row") td(candidate_name) td(candidate_name) td(f'{percent}%') with table(cls='table table-striped'): with tbody(): with tr(): th('Total number of ballots') td(result_contest['total_ballots']) with tr(): th('Number of votes') td(result_contest['total_votes']) with tr(): th('Number of undervotes') td(result_contest['undervote']) with tr(): th('Number of overvotes') td(result_contest['overvote']) # Table with overvotes: with div(cls='my-4'): h2('Ballots with overvotes:') with table(cls='table table-striped'): with thead(): with tr(): th('#', scope="col") th('Precinct / Contest name', scope="col") th('Ballot file / Ballot and CVR status', scope="col") th('Overvotes / Contest validation status', scope="col") with tbody(): dirpath = DB.dirpath_from_dirname('overvotes') for index, ballot_id in enumerate( BALLOTLISTS['overvoted_ballots']): filepathlist = glob.glob( f"{dirpath}**/{ballot_id}i.pdf", recursive=True) if not filepathlist: continue filepath = filepathlist[0] with tr(): th(index + 1, scope="row") td('') with td(): ballot_image_filepath = os.path.abspath( filepath) a(ballot_id, href=ballot_image_filepath, target="_blank") td('') # overvotes_contests = list( # filter( # lambda x: (x.contest_ballot_status == STATUS_DICT['overvote']) or # (x.contest_cvr_status == STATUS_DICT['overvote']), ballot.ballotdict['contests'])) # for contest in overvotes_contests: # with tr(): # td() # td(contest.contest_name) # td(f"{contest.contest_ballot_status} / {contest.contest_cvr_status}") # td(contest.contest_validation if contest.contest_validation is not None else '') # Table with blank ballots: with div(cls='my-4'): h2('Blank Ballots:') with table(cls='table table-striped'): with thead(): with tr(): th('#', scope="col") th('Precinct / Contest name', scope="col") th('Ballot file / Ballot and CVR status', scope="col") th('Overvotes / Contest validation status', scope="col") with tbody(): dirpath = DB.dirpath_from_dirname('blank_ballots') for index, ballot_id in enumerate( BALLOTLISTS['blank_ballots']): filepathlist = glob.glob(f"f{dirpath}{ballot_id}i.pdf", recursive=True) if not filepathlist: continue filepath = filepathlist[0] with tr(): th(index + 1, scope="row") td('') with td(): ballot_image_filepath = os.path.abspath( filepath) a(ballot_id, href=ballot_image_filepath, target="_blank") td('') # Table with disagreements: with div(cls='my-4'): h2('Ballots with disagreements:') with table(cls='table table-striped'): with thead(): with tr(): th('#', scope="col") th('Ballot file', scope="col") th('Disagreement Details', scope="col") with tbody(): dirpath = DB.dirpath_from_dirname('disagreements') for index, ballot_id in enumerate( BALLOTLISTS['disagreed_ballots']): filepathlist = glob.glob( f"{dirpath}**/{ballot_id}i.pdf", recursive=True) if not filepathlist: continue filepath = filepathlist[0] with tr(): th(index + 1, scope="row") with td(): ballot_image_filepath = os.path.abspath( filepath) a(ballot_id, href=ballot_image_filepath, target="_blank") td( raw(f"<pre>{DISAGREED_INFO_DICT[ballot_id]}</PRE>" )) return doc