def generate_user_class_html(user_class): a = Airium() a('<!DOCTYPE html>') with a.html(lang="zh-Hans"): with a.head(): a.meta(charset="utf-8") a.title(_t=user_class.name) with a.body(): with a.div(id='subject-filter'): with a.label(): a.input(checked='checked', onchange='changeSubjectFilterAll(this.checked)', type='checkbox') a("全选") for key in index_to_subject_name: with a.label(): a.input(checked='checked', name='category', onchange='onSubjectCheckboxChange()', type='checkbox', value=key) a(index_to_subject_name[key]) with a.div(id='user-login'): a.label(for_='user-id', _t='用户名:') a.input(id='user-id', type='text') a.input(onclick='login(document.getElementById("user-id").value)', type='submit', value='登录') with a.ul(): for record in reversed(user_class.lesson_schedules): if not 'title' in record: continue with a.li(klass='lesson-schedule', **{'data-subject': record['numberSubject']}): a.p(klass='lesson-schedule-title', _t=record['title']) if not 'file_resources' in record: continue with a.ul(): for resource in record['file_resources']: if not 'fileURI' in resource: continue with a.li(klass='resource', **{'data-guid': resource['guid']}): with a.a(href=resource['fileURI']): a(resource['title']) if resource['ext'] in pdf_convertable_exts: a.br() with a.i(): with a.a(href=resource['fileURI'].replace(resource['ext'], 'pdf')): a('PDF') a.br() a.button(onclick='getAnswerSheet(this)', _t='答题卡') with a.script(): with Path('site/scripts/api.js').open(mode='r') as f: a(f.read()) with a.script(): with Path('site/scripts/user-class-page-script.js').open(mode='r') as f: a(f.read()) return str(a)
def generate_html(): a = Airium() a('<!DOCTYPE html>') with a.html(): with a.head(): a.title(_t="Speech Evaluation") a.meta(name="viewport", content="width=device-width, initial-scale=1.0") a.link( href= "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css", rel="stylesheet", integrity= "sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6", crossorigin="anonymous") with a.body(): with a.div(klass="container pb-5 pt-5"): a.h1(_t="Emotional Speech Evaluation", klass="text-center text-success display-1 pt-5 pb-5") a.p(_t= "Thank you for your time and welcome to the subjective evaluation of our emotional speech samples!", klass="pt-5") a.p(_t= """First, you will need to answer 5 questions about yourself to make us know you more. Then you will hear overall 80 audio samples, for each of which you are invited to answer 5 questions. If you are uncertain about an answer listen to the audio sample multiple times. """) a.p(_t= """It is highly recommended to wear headphones during the evaluation. """) with a.p(): a.span( _t= """After you click ‘Submit’, all your answers will be recorded, and a CSV file will be downloaded. Please send the CSV file to """) a.a(href= "mailto:[email protected]?subject=Emotional Speech Evalution", _t="*****@*****.**", target="_blank", rel="noopener noreferrer") a.span(_t=". Thanks for your help!") a.p(_t= "Note: Please answer all questions. ‘Submit’ button will bring you back to the unfinished questions." ) a.p(_t= "When answering questions related to emotions please consider the following definitions:" ) with a.ul(): with a.li(): a.span(_t="Please select ") a.strong(_t="‘Neutral’") a.span( _t= " if you think the speaker does not express a particular emotion." ) with a.li(): a.span(_t="Please select ") a.strong(_t="‘Anger’") a.span( _t= " if you think the speaker is mad or furious about something." ) with a.li(): a.span(_t="Please select ") a.strong(_t="‘Amused’") a.span( _t= " if you think the speaker finds something funny or interesting." ) with a.li(): a.span(_t="Please select ") a.strong(_t="‘Disgust’") a.span( _t= " if you think the speaker feels nauseating or disgusted." ) with a.li(): a.span(_t="Please select ") a.strong(_t="‘Sleepy’") a.span( _t= " if you think the speaker is tired or exhausted.") with a.form(klass="pt-5 pb-5", id="evaluation-form", action="#", onsubmit="return submitForm();"): with a.div(klass="form-group col-md-4"): a.label(_t="Name", for_="name-input") a.input(id="name-input", klass="form-control", type="text", placeholder="Jane Smith", required=True) with a.div(klass="form-group col-md-8"): for index, question in enumerate( SELF_EVALUATION_QUESTIONS): with a.div(klass="card mt-5"): with a.div(klass="card-body"): a.p(_t=question, klass="pb-3") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"self-evaluation-{index}-1", name=f"self-evaluation-{index}", klass="custom-control-input", value=1, required=True) a.label( _t="1 — Strongly disagree", klass="custom-control-label", for_=f"self-evaluation-{index}-1") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"self-evaluation-{index}-2", name=f"self-evaluation-{index}", klass="custom-control-input", value=2) a.label( _t="2 — Disagree", klass="custom-control-label", for_=f"self-evaluation-{index}-2") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"self-evaluation-{index}-3", name=f"self-evaluation-{index}", klass="custom-control-input", value=3) a.label( _t="3 — Neutral", klass="custom-control-label", name=f"self-evaluation-{index}", for_=f"self-evaluation-{index}-3") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"self-evaluation-{index}-4", name=f"self-evaluation-{index}", klass="custom-control-input", value=4) a.label( _t="4 — Agree", klass="custom-control-label", for_=f"self-evaluation-{index}-4") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"self-evaluation-{index}-5", name=f"self-evaluation-{index}", klass="custom-control-input", value=5) a.label( _t="5 — Strongly agree", klass="custom-control-label", for_=f"self-evaluation-{index}-5") a.h4(_t="Emotional Speech Evalution", klass="mt-5 pt-5 text-success") for index, file in enumerate(get_file_list()): if index % 2 == 1: color_scheme = "bg-secondary bg-gradient text-white" else: color_scheme = "bg-light bg-gradient" with a.div(klass=f"card mt-5 {color_scheme}"): with a.div(klass="card-body"): with a.div(klass="row"): with a.div( klass="col-lg-4 align-self-center" ): with a.div(klass="text-center"): a.h6(_t=f"Sample {index + 1}") a.audio(controls=True, src=f"samples/{file}", klass='mb-5 mt-5') with a.div(klass="col-lg-8"): with a.p(klass="pb-1"): a.strong(_t="What emotion") a.span( _t= " do you think of the voice expressed?" ) with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-1-1-{file}", name=f"tts-evaluation-1-{file}", klass="custom-control-input", value=1, required=True) a.label( _t="1 — Neutral", klass="custom-control-label", for_= f"tts-evaluation-1-1-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-1-2-{file}", name=f"tts-evaluation-1-{file}", klass="custom-control-input", value=2) a.label( _t="2 — Amused", klass="custom-control-label", for_= f"tts-evaluation-1-2-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-1-3-{file}", name=f"tts-evaluation-1-{file}", klass="custom-control-input", value=3) a.label( _t="3 — Anger", klass="custom-control-label", for_= f"tts-evaluation-1-3-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-1-4-{file}", name=f"tts-evaluation-1-{file}", klass="custom-control-input", value=4) a.label( _t="4 — Disgust", klass="custom-control-label", for_= f"tts-evaluation-1-4-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-1-5-{file}", name=f"tts-evaluation-1-{file}", klass="custom-control-input", value=5) a.label( _t="5 — Sleepy", klass="custom-control-label", for_= f"tts-evaluation-1-5-{file}") with a.p(klass="pb-1 pt-5"): a.span(_t="If ") a.strong(_t="NOT neutral") a.span( _t=", what do you think of the " ) a.strong(_t="intensity") a.span( _t= " of the emotion expressed? (If neutral, please skip this question)" ) with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-2-1-{file}", name=f"tts-evaluation-2-{file}", klass="custom-control-input", value=1, required=True) a.label( _t="1 — Very weak", klass="custom-control-label", for_= f"tts-evaluation-2-1-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-2-2-{file}", name=f"tts-evaluation-2-{file}", klass="custom-control-input", value=2) a.label( _t="2 — Weak", klass="custom-control-label", for_= f"tts-evaluation-2-2-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-2-3-{file}", name=f"tts-evaluation-2-{file}", klass="custom-control-input", value=3, checked=True) a.label( _t="3 — Moderate", klass="custom-control-label", for_= f"tts-evaluation-2-3-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-2-4-{file}", name=f"tts-evaluation-2-{file}", klass="custom-control-input", value=4) a.label( _t="4 — Strong", klass="custom-control-label", for_= f"tts-evaluation-2-4-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-2-5-{file}", name=f"tts-evaluation-2-{file}", klass="custom-control-input", value=5) a.label( _t="5 — Very strong", klass="custom-control-label", for_= f"tts-evaluation-2-5-{file}") with a.p(klass="pb-1 pt-5"): a.strong(_t="How close to human") a.span( _t= " would you rate the voice speaking?" ) with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-3-1-{file}", name=f"tts-evaluation-3-{file}", klass="custom-control-input", value=1, required=True) a.label( _t="1 — Not at all", klass="custom-control-label", for_= f"tts-evaluation-3-1-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-3-2-{file}", name=f"tts-evaluation-3-{file}", klass="custom-control-input", value=2) a.label( _t="2 — A little bit close", klass="custom-control-label", for_= f"tts-evaluation-3-2-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-3-3-{file}", name=f"tts-evaluation-3-{file}", klass="custom-control-input", value=3) a.label( _t="3 — Close", klass="custom-control-label", for_= f"tts-evaluation-3-3-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-3-4-{file}", name=f"tts-evaluation-3-{file}", klass="custom-control-input", value=4) a.label( _t="4 — Very close", klass="custom-control-label", for_= f"tts-evaluation-3-4-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-3-5-{file}", name=f"tts-evaluation-3-{file}", klass="custom-control-input", value=5) a.label( _t="5 — Extremely close", klass="custom-control-label", for_= f"tts-evaluation-3-5-{file}") with a.p(klass="pb-1 pt-5"): a.span( _t="Do you think the voice is " ) a.strong( _t="clear and understandable") a.span(_t="?") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-4-1-{file}", name=f"tts-evaluation-4-{file}", klass="custom-control-input", value=1, required=True) a.label( _t="1 — Strongly disagree", klass="custom-control-label", for_= f"tts-evaluation-4-1-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-4-2-{file}", name=f"tts-evaluation-4-{file}", klass="custom-control-input", value=2) a.label( _t="2 — Disagree", klass="custom-control-label", for_= f"tts-evaluation-4-2-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-4-3-{file}", name=f"tts-evaluation-4-{file}", klass="custom-control-input", value=3) a.label( _t="3 — Neutral", klass="custom-control-label", for_= f"tts-evaluation-4-3-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-4-4-{file}", name=f"tts-evaluation-4-{file}", klass="custom-control-input", value=4) a.label( _t="4 — Agree", klass="custom-control-label", for_= f"tts-evaluation-4-4-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-4-5-{file}", name=f"tts-evaluation-4-{file}", klass="custom-control-input", value=5) a.label( _t="5 — Strongly agree", klass="custom-control-label", for_= f"tts-evaluation-4-5-{file}") with a.p(klass="pb-1 pt-5"): a.span(_t="How much do you ") a.strong(_t="like") a.span(_t=" the voice speaking?") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-5-1-{file}", name=f"tts-evaluation-5-{file}", klass="custom-control-input", value=1, required=True) a.label( _t="1 — Not at all", klass="custom-control-label", for_= f"tts-evaluation-5-1-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-5-2-{file}", name=f"tts-evaluation-5-{file}", klass="custom-control-input", value=2) a.label( _t="2 — Hardly", klass="custom-control-label", for_= f"tts-evaluation-5-2-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-5-3-{file}", name=f"tts-evaluation-5-{file}", klass="custom-control-input", value=3) a.label( _t="3 — Moderately", klass="custom-control-label", for_= f"tts-evaluation-5-3-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-5-4-{file}", name=f"tts-evaluation-5-{file}", klass="custom-control-input", value=4) a.label( _t="4 — Greatly", klass="custom-control-label", for_= f"tts-evaluation-5-4-{file}") with a.div( klass= "custom-control custom-radio form-check-inline" ): a.input( type="radio", id=f"tts-evaluation-5-5-{file}", name=f"tts-evaluation-5-{file}", klass="custom-control-input", value=5) a.label( _t="5 — Extremely", klass="custom-control-label", for_= f"tts-evaluation-5-5-{file}") with a.div(klass="from-group mt-5"): a.label( _for="open-comments", _t= "Please leave your general opinion about the speeches here. We are also happy to hear your valuable suggestions. Thanks!" ) a.textarea(klass="form-control", id="open-comments", name="open-comments", placeholder="(Optional)", rows="3") a.button(_t="Submit", type="submit", klass="btn btn-primary mt-5") with a.p(klass="mt-3"): a.span(_t="Please send the generated CSV file to ") a.a(href= "mailto:[email protected]?subject=Emotional Speech Evalution", _t="*****@*****.**", target="_blank", rel="noopener noreferrer") a.span( _t= ". Your e-mail address will not be collected or linked with the data. Thanks for your help!" ) with a.script(): a(f''' function clearForm() {{ document.getElementById("evaluation-form").reset(); }} function buildCsvRow(fileName, questionResponses) {{ return `${{fileName}};${{questionResponses[0]}};${{questionResponses[1]}};${{questionResponses[2]}};${{questionResponses[3]}};${{questionResponses[4]}}\\n` }} function getQuestionResponse(input_name) {{ return $(`input[name="${{input_name}}"]:checked`).val(); }} function getSelfEvaluationResponses() {{ return [{",".join([f"getQuestionResponse('self-evaluation-{index}')" for index in range(5)])}]; }} function getTtsEvaluationResponsesForFile(file_name) {{ return [{",".join([f"getQuestionResponse(`tts-evaluation-{index}-${{file_name}}`)" for index in range(1, 6)])}]; }} function getOpenComments() {{ let comments = $(`textarea[name="open-comments"]`).val(); if ("" === comments) {{ return "(Optional)\\n"; }} else {{ return comments.replace(/\\r?\\n|\\r/g, " ") + "\\n"; }} }} function submitForm() {{ let name = $("#name-input").val(); let files = [{",".join([f"'{file}'" for file in get_file_list()])}]; let csv = "data:text/csv;charset=utf-8,"; csv += "filename;q1;q2;q3;q4;q5\\n"; csv += buildCsvRow("self_evaluation", getSelfEvaluationResponses()); for (let i = 0; i < files.length; i++) {{ csv += buildCsvRow(files[i], getTtsEvaluationResponsesForFile(files[i])); }} csv += getOpenComments(); let encodedUri = encodeURI(csv); let downloadLink = document.createElement("a"); downloadLink.setAttribute("download", `${{name}}_results.csv`); downloadLink.setAttribute("href", encodedUri); document.body.appendChild(downloadLink); downloadLink.click(); downloadLink.remove(); return false; }} ''') a.script( src= "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js", integrity= "sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf", crossorigin="anonymous") a.script( src="https://code.jquery.com/jquery-3.6.0.min.js", integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=", crossorigin="anonymous") return str(a)
def create_index_page(out_dir: str, out_name: str, gen_files: List[str]) -> None: """ Generates index page. """ template = Airium() logging.info("Generating: %s", out_name) with template.html(): with template.head(): template.title(_t="Enso Reference") template.link(href="style.css", rel="stylesheet") template.link(href="favicon.ico", rel="icon") template.style(_t="ul { padding-inline-start: 15px; }") template.style( _t="""ul, .section ul { list-style: none; padding: 0; margin: 0; word-wrap: initial; } ul li { padding: 5px 10px; } .section ul { display: none; } .section input:checked ~ ul { display: block; } .section input[type=checkbox] { display: none; } .section { position: relative; padding-left: 20px !important; } .section label:after { content: "+"; position: absolute; top: 0; left: 0; padding: 0; text-align: center; font-size: 17px; color: cornflowerblue; transition: all 0.3s; } .section input:checked ~ label:after { color: cadetblue; transform: rotate(45deg); } @media only screen and (max-width: 1100px) { #tree { width: 30% !important; } } """ ) template.script( _t="""function set_frame_content(file) { document.getElementById("frame").src = file }""" ) with template.body(style="background-color: #333"): template.h2( style="""text-align: center; padding: 15px; margin: 0; color: #fafafa""", _t="Enso Reference", ) with template.div( style="background-color: #fafafa; display: flex; height: 100%" ): with template.div( id="tree", style="""background-color: #efefef; border-radius: 14px; width: 20%; margin: 15px; padding-left: 20px; overflow: scroll; height: 90%;""", ): grouped_file_names = group_by_prefix(gen_files) create_html_tree(template, "", grouped_file_names, gen_files) template.iframe( frameborder="0", height="100%", id="frame", src="Base-Main.html", width="100%", target="_blank", ) html_file = open(out_dir + "/" + out_name, "w") html_file.write(str(template)) html_file.close()
def generate_html(): a = Airium() a('<!DOCTYPE html>') with a.html(): with a.head(): a.title(_t="TTS Demo Files") a.meta(name="viewport", content="width=device-width, initial-scale=1.0") a.link( href= "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css", rel="stylesheet", integrity= "sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6", crossorigin="anonymous") with a.body(): with a.div(klass="container pb-5 pt-5"): a.h1(_t="Emotional TTS Demo Files", klass="text-center display-1 pt-5 pb-5") a.h5( _t="21/04/19 : Reproduced VAW-GAN based emotion converter", klass="pt-5 pb-3") a.h5( _t= "21/06/01-A: Added phoneme embeddings to the encoder of VAW-GAN", klass="pt-5 pb-3") a.h5( _t="21/06/01-B: Tested CMU-MOSEI with the vanilla VAW-GAN", klass="pt-5 pb-3") a.h5( _t= "21/06/22 : Tested VAW-GAN with forced alignment on word-level", klass="pt-5 pb-3") a.h5( _t= "21/07/06 : Tested VAW-GAN with forced alignment on word-level with MFCC Nonspeech Masking", klass="pt-5 pb-3") a.h5( _t= "21/08/24-A: Tested VAW-GAN with pyworld.harvest() in WORLD", klass="pt-5 pb-3") a.h5( _t= "21/08/24-B: Tested VAW-GAN with synthesised neutral speech as the training set", klass="pt-5 pb-3") for folder, files_by_file_name in get_file_list().items(): a.h3(_t= f"Samples from {convert_folder_name_to_date(folder)}", klass="text-center display-6 pt-5") for original_file_name, files_by_model in files_by_file_name.items( ): a.h4(_t=original_file_name, klass="pt-5 pb-5 text-success") for model, files in files_by_model.items(): if 'neu' == model: with a.div( klass="row row-cols-1 row-cols-md-2 g-4" ): with a.div(klass="col"): with a.div(klass="card"): with a.div( klass= "card-body text-center"): a.h5( _t= extract_emotion_from_file_name( files[0]), klass="card-title") a.audio(controls=True, src=os.path.join( 'samples', folder, files[0])) else: if len(files) > 0: a.h5(_t=f"Samples Generated with {model}", klass="pt-5 pb-3") with a.div( klass= "row row-cols-1 row-cols-md-2 g-4" ): for file in files: with a.div(klass="col"): with a.div(klass="card"): with a.div( klass= "card-body text-center" ): a.h5( _t= extract_emotion_from_file_name( file), klass="card-title") a.audio( controls=True, src=os.path.join( 'samples', folder, file)) a.script( src= "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js", integrity= "sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf", crossorigin="anonymous") return str(a)
def form_html_plot(): #initilize figure object fig = go.Figure() zulip_data = get_zulip_data(config.name) git_data = get_git_data(config.name) jitsiClasses_data = get_jitsiClasses_data(config.email) jitsiSession_data = get_jitsiSession_data(config.email) fig.add_trace( go.Bar(name='Zulip Activity', x=list(zulip_data[0].keys()), y=list(zulip_data[0].values()), text=list(zulip_data[0].values()), textposition='auto')) fig.add_trace( go.Bar(name='GitLab Activity', x=list(git_data[0].keys()), y=list(git_data[0].values()), text=list(git_data[0].values()), textposition='auto')) fig.add_trace( go.Bar(name='JitsiClasses Activity', x=list(jitsiClasses_data[0].keys()), y=list(jitsiClasses_data[0].values()), text=list(jitsiClasses_data[0].values()), textposition='auto')) fig.add_trace( go.Bar(name='JitsiSession Activity', x=list(jitsiSession_data[0].keys()), y=list(jitsiSession_data[0].values()), text=list(jitsiSession_data[0].values()), textposition='auto')) fig.update_layout( title=f'Activity in MIEM Services. Name - {config.name}', xaxis_title='Time', yaxis_title='Amount', barmode='group') fig.update_xaxes(dtick="M1", tickformat="%b-%Y") #Form html file a = Airium() a('<!DOCTYPE html>') with a.html(): with a.head(): with a.html(lang='en'): a.meta(charset='utf-8') a.title(_t=config.name) a.link(href='style.css', rel='stylesheet', type='text/css') a.script(src='https://cdn.plot.ly/plotly-latest.min.js') a.font('Courier New, monospace') #a.style() with a.body(): a.append( plotly.offline.plot(fig, include_plotlyjs=False, output_type='div')) with a.font(size='3', face="Courier New, monospace", color='#2a3f5f'): with a.table(align='center', style='border-spacing: 100px 0px'): with a.tr(klass='header_row'): a.th(_t='Name of the service') a.th(_t='Total action amount') a.th(_t='Profile existence') with a.tr(): a.td(_t='Zulip', align='center') a.td(_t=zulip_data[1], align='center') a.td(_t=zulip_data[2], align='center') with a.tr(): a.td(_t='GitLab', align='center') a.td(_t=git_data[1], align='center') a.td(_t=git_data[2], align='center') with a.tr(): a.td(_t='JitsiClasses', align='center') a.td(_t=jitsiClasses_data[1], align='center') a.td(_t='-', align='center') # can use _t or text with a.tr(): a.td(_t='JitsiSession', align='center') a.td(_t=jitsiSession_data[1], align='center') a.td(_t='-', align='center') with a.h3(klass='main_header', align='center'): a(f"Activity grade: {cult_grade(zulip_data, git_data,jitsiClasses_data,jitsiSession_data)}" ) with a.div(align='center'): a(f"Данные актуальны на {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" ) html = str(a) with open(config.html_path, 'w') as f: f.write(str(html))