def formatLog(file): doc, tag, text = yattag.Doc().tagtext() try: with open(file, 'r') as f: loghtml = f.read() err = loghtml.count("Error:") warn = loghtml.count("Warn:") info = loghtml.count("Info:") short = "Error: {}, Warnings: {}, Information: {}".format( err, warn, info) def log(doc, tag, text): with tag('div', klass='log'): doc.asis(loghtml) doc.asis( listItem(keyval("Log", short), log, status="ok" if err == 0 else "fail")) except FileNotFoundError as e: doc.asis( listItem(keyval("Log", "Logfile missing"), str(e), status="fail")) return doc.getvalue()
def make_html(services): doc, tag, text = yattag.Doc().tagtext() doc.asis("<!doctype html>") with tag("head"): with tag("title"): text("HTMLRemote") doc.stag("link", href="default.css", rel="stylesheet", type="text/css") doc.stag("meta", charset="utf-8") # prevent zoom on mobile devices, thus making it easier to press # buttons multiple times without accidentally triggering a zoom doc.stag("meta", name="viewport", content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0") with tag("script", type="text/javascript", src="script.js"): pass for _, service in services.items(): service.html(doc) with tag("iframe", name="frame"): pass return doc.getvalue()
def testImages(testimg, refimg, diffimg, maskimg): doc, tag, text = yattag.Doc().tagtext() with tag('div', klass="zoomset"): with tag('div', klass="slider"): with tag('div', klass="imgtestlabel"): text("Test") with tag('div', klass="imgtestlabel"): text("Reference") with tag('div', klass="imgtestlabel"): text("Difference * 10") with tag('div', klass="imgtestlabel"): text("Mask") with tag('div', klass="slider"): with tag('div', klass="zoom"): doc.asis(image(testimg, alt="test image", klass="test")) with tag('div', klass="zoom"): doc.asis(image(refimg, alt="reference image", klass="test")) with tag('div', klass="zoom"): doc.asis(image(diffimg, alt="difference image", klass="diff")) with tag('div', klass="zoom"): doc.asis(image(maskimg, alt="mask image", klass="diff")) return doc.getvalue()
def sparkLine(self, series, klass, normalRange=True, valueRange=True): doc, tag, text = yattag.Doc().tagtext() data = self.db.getSeries(self.module, self.name, series) xmax = self.created.timestamp() xmin = xmax - 60 * 60 * 24 * self.history_days if xmin < data.created.timestamp(): xmin = data.created.timestamp() mean, std = stats([x.value for x in data.measurements]) values = [x for x in data.measurements if x.created.timestamp() > xmin] minval = min((x.value for x in values)) maxval = max((x.value for x in values)) datastr = ", ".join( (str(x.created.timestamp()) + ":" + str(x.value) for x in values)) opts = { "sparkChartRangeMinX": str(xmin), "sparkChartRangeMaxX": str(xmax) } if valueRange: opts.update({ "sparkChartRangeMin": str(min(values[-1].value, max(mean - 3 * std, minval))), "sparkChartRangeMax": str(max(values[-1].value, min(mean + 3 * std, maxval))) }) if normalRange: opts.update({ "sparkNormalRangeMin": str(mean - std), "sparkNormalRangeMax": str(mean + std) }) with tag('span', klass=klass, **opts): doc.asis("<!-- " + datastr + " -->") return doc.getvalue()
def handle_streets(relations: helpers.Relations, request_uri: str) -> yattag.Doc: """Expected request_uri: e.g. /osm/streets/ormezo/view-query.""" tokens = request_uri.split("/") relation_name = tokens[-2] action = tokens[-1] relation = relations.get_relation(relation_name) osmrelation = relation.get_config().get_osmrelation() doc = yattag.Doc() doc.asis(get_toolbar(relations, "streets", relation_name, osmrelation).getvalue()) if action == "view-query": with doc.tag("pre"): doc.text(relation.get_osm_streets_query()) elif action == "view-result": with relation.get_files().get_osm_streets_stream("r") as sock: table = util.tsv_to_list(sock) doc.asis(util.html_table_from_list(table).getvalue()) elif action == "update-result": query = relation.get_osm_streets_query() try: relation.get_files().write_osm_streets(overpass_query.overpass_query(query)) streets = relation.get_config().should_check_missing_streets() if streets != "only": doc.text(_("Update successful: ")) link = "/osm/missing-housenumbers/" + relation_name + "/view-result" doc.asis(util.gen_link(link, _("View missing house numbers")).getvalue()) else: doc.text(_("Update successful.")) except urllib.error.HTTPError as http_error: doc.asis(util.handle_overpass_error(http_error).getvalue()) date = get_streets_last_modified(relation) doc.asis(get_footer(date).getvalue()) return doc
def handle_missing_streets(relations: helpers.Relations, request_uri: str) -> yattag.Doc: """Expected request_uri: e.g. /osm/missing-streets/ujbuda/view-[result|query].""" tokens = request_uri.split("/") relation_name = tokens[-2] action = tokens[-1] relation = relations.get_relation(relation_name) osmrelation = relation.get_config().get_osmrelation() doc = yattag.Doc() doc.asis(get_toolbar(relations, "missing-streets", relation_name, osmrelation).getvalue()) if action == "view-result": doc.asis(missing_relations_view_result(relations, request_uri).getvalue()) elif action == "view-query": with doc.tag("pre"): with relation.get_files().get_ref_streets_stream("r") as sock: doc.text(sock.read()) elif action == "update-result": doc.asis(missing_streets_update(relations, relation_name).getvalue()) date = ref_streets_last_modified(relation) doc.asis(get_footer(date).getvalue()) return doc
def post_page(post: "Post"): doc, tag, text, line = ttl = yattag.Doc().ttl() with base_page(*ttl): header(*ttl) with tag("main", klass="main"): with tag("article", klass="post"): with tag("header", klass="post__header"): line("h2", post.title, klass="post__heading") line( "time", post.date.strftime("%B %d, %Y"), time=post.date.isoformat(), klass="post__heading__time", ) with tag("main", klass="post__main"): doc.asis(post.html) with tag("footer", klass="post__footer"): doc.stag("hr") text("Feedback? ") line("a", "Email me", href=f"mailto:{EMAIL}", klass="post__footer__email") return doc.getvalue()
def images(self, imgs, testdir): doc, tag, text = yattag.Doc().tagtext() def path(type, img): return os.path.relpath(toPath(testdir, type, img), self.basedir) def imgstatus(key): failedImgs = safeget(self.report, 'failures', 'image_tests', failure={}) return "fail" if key in failedImgs.keys() else "ok" with tag('ol'): for img in imgs: doc.asis( listItem(self.imageShort(img), testImages(path("imgtest", img["image"]), path("imgref", img["image"]), path("imgdiff", img["image"]), path("imgmask", img["image"])), status=imgstatus(img['image']), hide=False)) return doc.getvalue()
def format_array_html(array, hfunc=None): doc, tag, text, line = yattag.Doc().ttl() def rec(array, depth, i): class_ = 'depth{}'.format(depth) if not isinstance(array, np.ndarray): with tag('table', klass=class_): if hfunc: with tag('tr'): line('th', hfunc(i), klass=class_) with tag('tr', klass=class_): with tag('td', klass=class_): text(str(array)) else: with tag('table', klass=class_): with tag('tr', klass=class_): for j in range(len(array)): with tag('td', klass=class_): rec(array[j], depth + 1, i + (j, )) return doc return rec(array, 0, ()).getvalue()
def fill_header_function(function: str, relation_name: str, items: List[yattag.Doc]) -> None: """Fills items with function-specific links in the header. Returns a title.""" if function == "missing-housenumbers": doc = yattag.Doc() with doc.tag("a", href="/osm/missing-housenumbers/" + relation_name + "/update-result"): doc.text(_("Update from reference")) doc.text(" " + _("(may take seconds)")) items.append(doc) doc = yattag.Doc() with doc.tag("a", href="https://overpass-turbo.eu/"): doc.text(_("Overpass turbo")) items.append(doc) elif function == "missing-streets": doc = yattag.Doc() with doc.tag("a", href="/osm/missing-streets/" + relation_name + "/update-result"): doc.text(_("Update from reference")) items.append(doc) elif function == "street-housenumbers": doc = yattag.Doc() with doc.tag("a", href="/osm/street-housenumbers/" + relation_name + "/update-result"): doc.text(_("Call Overpass to update")) doc.text(" " + _("(may take seconds)")) items.append(doc) doc = yattag.Doc() with doc.tag("a", href="/osm/street-housenumbers/" + relation_name + "/view-query"): doc.text(_("View query")) items.append(doc) elif function == "streets": doc = yattag.Doc() with doc.tag("a", href="/osm/streets/" + relation_name + "/update-result"): doc.text(_("Call Overpass to update")) doc.text(" " + _("(may take seconds)")) items.append(doc) doc = yattag.Doc() with doc.tag("a", href="/osm/streets/" + relation_name + "/view-query"): doc.text(_("View query")) items.append(doc)
def plotting(id): doc, tag, text = yattag.Doc().tagtext() doc.stag('div', klass='flot-plots', id=id) return doc.getvalue()
def generate_gv_image(s): g = s.g s.gv("digraph frame" + str(s.step) + "{ ") #splines=ortho; #gv("pack=true") log('frames.. ' + '[' + str(s.step) + ']') root_frame = None #current_result = None rrr = list(g.subjects(RDF.type, kbdbg.frame)) last_frame = None for i, frame in enumerate(rrr): if g.value(frame, kbdbg.is_finished, default=False): continue f, text = s.get_frame_gv(i, frame) s.gv(f + text) #if last_frame: # arrow(last_frame, f, color='yellow', weight=100) parent = g.value(frame, kbdbg.has_parent) if parent: # and not g.value(parent, kbdbg.is_finished, default=False): s.arrow(gv_escape(parent), f, color='yellow', weight=10000000) else: root_frame = f last_frame = f #if i == 0 and current_result: # arrow(result_node, f) log('bnodes.. ' + '[' + str(s.step) + ']') if s.step == 51: print('eeee') for bnode in g.subjects(RDF.type, kbdbg.bnode): parent = g.value(bnode, kbdbg.has_parent) if g.value(parent, kbdbg.is_finished, default=False): continue (doc, tag, text) = yattag.Doc().tagtext() with tag("table", border=0, cellspacing=0): #for i in Collection(g, bnode): with tag('tr'): with tag('td', border=1): text((shorten(bnode.n3()))) items = None for i in g.objects(bnode, kbdbg.has_items): items = i # find the latest ones if not items: continue for i in Collection(g, items): with tag('tr'): name = g.value(i, kbdbg.has_name) pn = gv_escape(name) with tag("td", border=1, port=pn): text(shorten(name)) text(' = ') text(shorten(g.value(i, kbdbg.has_value))) #with tag("td", border=1): # text(shorten(g.value(i, kbdbg.has_value))) s.gv( gv_escape(bnode) + ' [shape=none, cellborder=2, label=<' + doc.getvalue() + '>]') s.arrow(gv_escape(parent), gv_escape(bnode), color='yellow', weight=100) last_bindings = get_last_bindings(s.step) log('bindings...' + '[' + str(s.step) + ']') new_last_bindings = [] for binding in g.subjects(RDF.type, kbdbg.binding): weight = 1 source_uri = g.value(binding, kbdbg.has_source) target_uri = g.value(binding, kbdbg.has_target) if g.value(source_uri, kbdbg.is_bnode, default=False) and g.value( target_uri, kbdbg.is_bnode, default=False): weight = 0 if g.value(binding, kbdbg.was_unbound) == rdflib.Literal(True): if (binding.n3() in last_bindings): s.comment("just unbound binding") s.arrow(s.gv_endpoint(source_uri), s.gv_endpoint(target_uri), color='orange', weight=weight, binding=True) continue if g.value(binding, kbdbg.failed) == rdflib.Literal(True): #if (binding.n3() in last_bindings): s.comment("just failed binding") s.arrow(s.gv_endpoint(source_uri), s.gv_endpoint(target_uri), color='red', weight=weight, binding=True) continue s.comment("binding " + binding.n3()) s.arrow(s.gv_endpoint(source_uri), s.gv_endpoint(target_uri), color=('black' if (binding.n3() in last_bindings) else 'purple'), weight=weight, binding=True) new_last_bindings.append(binding.n3()) put_last_bindings(s.step, new_last_bindings) del new_last_bindings log('results..' + '[' + str(s.step) + ']') last_result = root_frame for i, result_uri in enumerate(g.subjects(RDF.type, kbdbg.result)): result_node = gv_escape(result_uri) r = result_node + ' [cellborder=2, shape=none, label=<' (doc, tag, text) = yattag.Doc().tagtext() with tag("table"): with tag('tr'): with tag("td"): text('RESULT' + str(i) + ' ') emit_terms(s.g, tag, text, s.g.value(result_uri, RDF.value), 'result') r += doc.getvalue() + '>]' s.gv(r) false = rdflib.Literal(False) #if g.value(result_uri, kbdbg.was_unbound, default = false) == false: #current_result = result_node #arrow_width = 2 #else: #arrow_width = 1 if last_result: s.arrow(last_result, result_node, color='yellow', weight=100) last_result = result_node s.gv("}") log('}..' + '[' + str(s.step) + ']')
def testUnChoix(self): io_gift = StringIO(u""" ::Pourquoi représenter avec des nombres ?:: Pourquoi faut-il <strong>représenter</strong> les textes, images, sons, etc, *par* des nombres dans un ordinateur ? { ~C'est un choix <strong>industriel</strong>.#Non, les industriels n'avaient pas le choix. ~Les ordinateurs ont été inventés par des mathématiciens.#Non, les mathématiciens savent manipuler autre chose que des nombres, et les ordinateurs sont le fruit de l'interaction entre de nombreuses sciences. =Tout ordinateur est fondamentalement une machine qui calcule avec des nombres.#Oui, comme un ordinateur ne manipule que des nombres, tout doit être représenté sous forme de nombres être manipulé par un ordinateur. ####Un ordinateur ne manipule que des nombres, tout doit donc être représenté sous forme de nombres pour qu'il puisse le manipuler. } """) questions = pygift.parseFile(io_gift) io_gift.close() d = yattag.Doc() with d.tag('html'): with d.tag('head'): d.stag('meta', charset="utf-8") with d.tag('h2'): d.text(str(questions[0].answers.__class__)) for q in questions: q.toHTML(d, True) for q in questions: q.toHTML(d, False) #Vérifie qu'une seule question a bien été créée self.assertEqual(len(questions), 1, "More than one Question for 'Test un choix'") # TEST HTML soup = BeautifulSoup(d.getvalue(), 'html.parser') for i, form in enumerate(soup.find_all('form')): self.assertEqual(form.h3['class'][0], u'questiontitle', " Not h3 or not good class for h3") self.assertEqual(str(form.h3.contents[0]), "Pourquoi représenter avec des nombres ?") for j, div in enumerate(form.find_all('div')): if j == 0: self.assertEqual(div['class'][0], u'questiontext', "Not div or not good class for 1rst div") self.assertEqual( str(div.contents[0]), u"<p>Pourquoi faut-il <strong>représenter</strong> les textes, images, sons, etc, <em>par</em> des nombres dans un ordinateur ?</p>" ) if (j == 1): if (i == 0): self.assertEqual(div['class'][0], u'groupedAnswerFeedback') # print(div.contents[0]) self.assertEqual( str(div.contents[0]), u"""<ul class="multichoice"><li class="wrong_answer"><p>C'est un choix <strong>industriel</strong>.</p> ⇝ <p>Non, les industriels n'avaient pas le choix.</p></li><li class="wrong_answer"><p>Les ordinateurs ont été inventés par des mathématiciens.</p> ⇝ <p>Non, les mathématiciens savent manipuler autre chose que des nombres, et les ordinateurs sont le fruit de l'interaction entre de nombreuses sciences.</p></li><li class="right_answer"><p>Tout ordinateur est fondamentalement une machine qui calcule avec des<br/> nombres.</p> ⇝ <p>Oui, comme un ordinateur ne manipule que des nombres,<br/> tout doit être représenté sous forme de nombres être manipulé par un ordinateur.</p></li></ul>""" ) elif (i == 1): self.assertEqual(div['class'][0], u'groupedAnswer') if (j == 2): self.assertEqual(div['class'][0], u'global_feedback') self.assertEqual(str(div.contents[0]), "<b><em>Feedback:</em></b>") self.assertEqual( str(div.contents[2]), "<p>Un ordinateur ne manipule que des nombres, tout doit donc être représenté sous forme de nombres pour qu'il puisse le manipuler.</p>" ) self.assertEqual(form.ul['class'][0], u'multichoice') nb_li = len(form.find_all('li')) self.assertEqual(nb_li, 3) for j, li in enumerate(soup.find_all('li')): if j == 0: self.assertEqual( str(li.contents[0]), "<p>C'est un choix <strong>industriel</strong>.</p>") if j == 1: self.assertEqual( str(li.contents[0]), "<p>Les ordinateurs ont été inventés par des mathématiciens.</p>" ) if j == 2: self.assertEqual( str(li.contents[0]), "<p>Tout ordinateur est fondamentalement une machine qui calcule avec des<br/>\nnombres.</p>" ) print("[GiftParsingHTMLTestCase]-- check_single_answer OK --")
def testNumerical(self): d = yattag.Doc() with d.tag('html'): with d.tag('head'): d.stag('meta', charset="utf-8") #NUMERICAL ANSWER io_num = StringIO(""" ::Num1:: When was Ulysses S. Grant born?{#1822:5} ::Num2:: What is the value of pi (to 3 decimal places)? {#3.141..3.142}. ::Num3:: When was Ulysses S. Grant born? {# =1822:0 =%50%1822:2 } ::Num4:: 1 2 ou 3 ? {#2} } """) questions = pygift.parseFile(io_num) io_num.close() for q in questions: with d.tag('h2'): d.text(str(questions[0].answers.__class__)) q.toHTML(d, True) for q in questions: q.toHTML(d, False) soup = BeautifulSoup(d.getvalue(), 'html.parser') for i, form in enumerate(soup.find_all('form')): self.assertEqual(form.h3['class'][0], u'questiontitle', " Not h3 or not good class for h3") if i < 4: for j, div in enumerate(form.find_all('div')): if j == 0: self.assertEqual(div['class'][0], u'questiontext') if i == 0: self.assertEqual( str(div.contents[0]), '<p>When was Ulysses S. Grant born?</p>') if i == 1: self.assertEqual( str(div.contents[0]), '<p>What is the value of pi (to 3 decimal places)?</p>' ) if i == 2: self.assertEqual( str(div.contents[0]), '<p>When was Ulysses S. Grant born?</p>') if j == 1: self.assertEqual(div['class'][0], u'answerFeedback') else: for j, span in enumerate(form.find_all('span')): if j == 0: self.assertEqual(span['class'][0], u'questionTextInline') if j == 1: self.assertEqual(span['class'][0], u'questionAnswersInline') self.assertEqual(span.input['type'], u'number') print("[GiftParsingHTMLTestCase]-- check_numerical OK --")
def testTrueFalse(self): """ """ # INITIALISATION d = yattag.Doc() with d.tag('html'): with d.tag('head'): d.stag('meta', charset="utf-8") # AVEC UNE RÉPONSE SIMPLE io_tf = StringIO(""" Le soleil se lève à l'Ouest.{F#Non!#Oui le soleil se lève à l'Est} """) questions = pygift.parseFile(io_tf) io_tf.close() with d.tag('h2'): d.text(str(questions[0].answers.__class__)) for q in questions: q.toHTML(d, True) for q in questions: q.toHTML(d, False) self.assertEqual(len(questions), 1, "More than one Question for 'TestTrueFalse'") soup = BeautifulSoup(d.getvalue(), 'html.parser') for i, form in enumerate(soup.find_all('form')): self.assertEqual(form.h3['class'][0], u'questiontitle', " Not h3 or not good class for h3") for j, div in enumerate(form.find_all('div')): if j == 0: self.assertEqual(div['class'][0], u'questiontext', "Not div or not good class for 1rst div") if i == 0: if j == 1: self.assertEqual( div['class'][0], u'answerFeedback', "Not div or not good class for 2sd div") self.assertEqual(div.contents[0], u'False') if j == 2: self.assertEqual( div['class'][0], u'correct_answer', "Not div or not good class for 3rd div") self.assertEqual( str(div.contents[0]), "<p>Oui le soleil se lève à l'Est</p>") if j == 3: self.assertEqual(div['class'][0], u'wrong_answer') self.assertEqual(str(div.contents[0]), "<p>Non!</p>") if i == 1: self.assertIsNotNone(form.ul) for j, li in enumerate(form.find_all('li')): if j == 0: self.assertEqual(li.contents[0]['type'], u'radio') self.assertEqual(li.contents[0]['value'], u'True') self.assertEqual(li.contents[1], _(u'True')) if j == 1: self.assertEqual(li.contents[0]['type'], u'radio') self.assertEqual(li.contents[0]['value'], u'False') self.assertEqual(li.contents[1], _(u'False')) print("[GiftParsingHTMLTestCase]-- check_truefalse OK --")
def generate_report(self): doc = yattag.Doc() # Type of cfn log return cfn log file def get_output_file(region, stack_name, resource_type): extension = '.txt' if resource_type == 'cfnlog': location = "{}-{}-{}{}".format(stack_name, region, 'cfnlogs', extension) return str(location) elif resource_type == 'resource_log': location = "{}-{}-{}{}".format(stack_name, region, 'resources', extension) return str(location) def get_teststate(stackname, region): rstatus = None status_css = None try: cfn_client = self._boto_client.get('cloudformation', region) test_query = cfn_client.describe_stacks(StackName=stackname) for result in test_query['Stacks']: rstatus = result.get('StackStatus') if rstatus == 'CREATE_COMPLETE': status_css = 'class=test-green' elif rstatus == 'CREATE_FAILED': status_css = 'class=test-red' self.taskcat.one_or_more_tests_failed = True if self.taskcat.retain_if_failed and ( self.taskcat.run_cleanup == True): self.taskcat.run_cleanup = False else: status_css = 'class=test-red' except TaskCatException: raise except Exception as e: print(PrintMsg.ERROR + "Error describing stack named [%s] " % stackname) print(PrintMsg.DEBUG + str(e)) rstatus = 'MANUALLY_DELETED' status_css = 'class=test-orange' return rstatus, status_css tag = doc.tag text = doc.text logo = 'taskcat' repo_link = 'https://github.com/aws-quickstart/taskcat' css_url = 'https://raw.githubusercontent.com/aws-quickstart/taskcat/master/assets/css/taskcat_reporting.css' output_css = requests.get(css_url).text doc_link = 'http://taskcat.io' with tag('html'): with tag('head'): doc.stag('meta', charset='utf-8') doc.stag('meta', name="viewport", content="width=device-width") with tag('style', type='text/css'): text(output_css) with tag('title'): text('TaskCat Report') with tag('body'): tested_on = time.strftime('%A - %b,%d,%Y @ %H:%M:%S') with tag('table', 'class=header-table-fill'): with tag('tbody'): with tag('th', 'colspan=2'): with tag('tr'): with tag('td'): with tag('a', href=repo_link): text('GitHub Repo: ') text(repo_link) doc.stag('br') with tag('a', href=doc_link): text('Documentation: ') text(doc_link) doc.stag('br') text('Tested on: ') text(tested_on) with tag('td', 'class=taskcat-logo'): with tag('h3'): text(logo) doc.stag('p') with tag('table', 'class=table-fill'): with tag('tbody'): with tag('thread'): with tag('tr'): with tag('th', 'class=text-center', 'width=25%'): text('Test Name') with tag('th', 'class=text-left', 'width=10%'): text('Tested Region') with tag('th', 'class=text-left', 'width=30%'): text('Stack Name') with tag('th', 'class=text-left', 'width=20%'): text('Tested Results') with tag('th', 'class=text-left', 'width=15%'): text('Test Logs') for test in self.test_data: with tag('tr', 'class= test-footer'): with tag('td', 'colspan=5'): text('') testname = test.get_test_name() print(PrintMsg.INFO + "(Generating Reports)") print(PrintMsg.INFO + " - Processing {}".format(testname)) for stack in test.get_test_stacks(): print("Reporting on {}".format( str(stack['StackId']))) stack_id = CommonTools( stack['StackId']).parse_stack_info() status, css = get_teststate( stack_id['stack_name'], stack_id['region']) with tag('tr'): with tag('td', 'class=test-info'): with tag('h3'): text(testname) with tag('td', 'class=text-left'): text(stack_id['region']) with tag('td', 'class=text-left'): text(stack_id['stack_name']) with tag('td', css): text(str(status)) with tag('td', 'class=text-left'): clog = get_output_file( stack_id['region'], stack_id['stack_name'], 'cfnlog') # rlog = get_output_file( # state['region'], # state['stack_name'], # 'resource_log') # with tag('a', href=clog): text('View Logs ') # with tag('a', href=rlog): # text('Resource Logs ') with tag('tr', 'class= test-footer'): with tag('td', 'colspan=5'): vtag = 'Generated by {} {}'.format( 'taskcat', self.version) text(vtag) doc.stag('p') print('\n') html_output = yattag.indent(doc.getvalue(), indentation=' ', newline='\r\n', indent_text=True) file = open(self.dashboard_filename, 'w') file.write(html_output) file.close() return html_output
def __init__(self, basedir, reports, database, header=None, footer=None): self.doc, tag, text = yattag.Doc().tagtext() self.db = database self.basedir = basedir self.created = datetime.datetime.now() self.scriptDirname = "_scripts" self.scripts = [ "jquery-2.2.0.min.js", "jquery.sparkline.min.js", "jquery.zoom.js", "list.min.js", "jquery.flot.js", "jquery.flot.time.js", "jquery.flot.selection.js", "jquery.flot.stack.js", "jquery.flot.tooltip.min.js", "clipboard.min.js", "main.js" ] self.postScripts = ["make-list.js", "make-flot.js"] self.doc.asis("<!DOCTYPE html>") self.doc.stag("meta", charset="utf-8") with tag('html'): with tag('head'): self.doc.stag('link', rel='stylesheet', href="report.css") for script in self.scripts: with tag('script', language="javascript", src=self.scriptDirname + "/" + script): text("") with tag('body'): if header != None: self.doc.asis(header) with tag('div', id='reportlist', klass='report'): with tag("div"): with tag('div', klass='titleimg'): self.doc.stag('img', src="_images/inviwo.png") with tag('div', klass='title'): text("Inviwo Regressions") self.doc.stag('input', klass='search', placeholder="Search") with tag('div', klass='subtitle'): with tag('div', klass="cell testdate"): text(self.created.strftime('%Y-%m-%d %H:%M:%S')) with tag('div', klass="cell"): with tag('a', klass='version', href="report.html"): text("latest") oldreports = glob.glob(self.basedir + "/report-*.html") oldreports.sort() oldreports.reverse() for i, old in enumerate(oldreports[:10]): prev = os.path.relpath(old, self.basedir) with tag('a', klass='version', href=prev): text("-" + str(i + 1)) with tag('div', klass='summary'): self.doc.stag('div', style="width:800px;height:150px", id='flot-summary') with tag("div", klass="head"): with tag("div", klass="cell testmodule"): with tag('button', ('data-sort', 'testmodule'), klass='sort'): text("Module") with tag("div", klass="cell testname"): with tag('button', ('data-sort', 'testname'), klass='sort'): text("Name") with tag("div", klass="cell testfailures"): with tag('button', ('data-sort', 'testfailures'), klass='sort'): text("Failures") with tag("div", klass="cell testruntime"): with tag('button', ('data-sort', 'testruntime'), klass='sort'): text("Run Time") with tag("div", klass="cell testdate"): with tag('button', ('data-sort', 'testdate'), klass='sort'): text("Last Run") with tag('ul', klass='list'): for name, report in reports.items(): tr = TestRun(self, report) self.doc.asis(tr.getvalue()) if footer != None: self.doc.asis(footer) with tag('script', language="javascript", src=self.scriptDirname + "/plotdata.js"): text("") for script in self.postScripts: with tag('script', language="javascript", src=self.scriptDirname + "/" + script): text("")
def main(): # menksoft_pua_cp_ints = [*range(0xE234, 0xE497 + 1)] with (mongoltoli_data_dir / "xunifont_rulewords_mon.js").open() as f: data = "".join(["{\n"] + f.readlines()[4:-1] + ["}"]) phonetic_pua_to_folded_mapping = make_phonetic_pua_to_folded_mapping() shaper = Shaper(project_dir / "products" / "DummyStateless-Regular.otf") case_count = 0 failure_count = 0 doc, tag, text = yattag.Doc().tagtext() cp_to_name = { chr(character.cp): character_id for character_id, character in Mong.characters.items() } with tag("html"): with tag("head"): doc.stag("link", rel="stylesheet", href="style.css") with tag("table"): with tag("thead"): with tag("tr"): for content in [ "rule", "string", "expectation", "graphically folded", "UTN", "diffing" ]: with tag("th"): text(content) for rule in json.loads(data)["rulelist"]: rule_id = rule["ruleindex"] for case in rule["rulewords"]: string = case["word"] if any(i in NON_HUDUM_CODE_POINTS for i in string): continue case_count += 1 string_annotation = " ".join( cp_to_name.get(i, f"[{i}]") for i in string) expectation = case["shape"] graphically_folded_expectation = "".join( fold_phonetic_pua(cp, phonetic_pua_to_folded_mapping) for cp in expectation).strip().translate( FURTHER_FOLDING) utn_result = "".join( convert_glyph_name_to_graphical_pua(i) for i in shaper.shape_text_to_glyph_names( string, features={"ss02": True})).strip( ).translate(FURTHER_FOLDING) diffing = "" if graphically_folded_expectation != utn_result: failure_count += 1 diffing = f"!{failure_count}" attributes = [("class", "diff")] if diffing else [] with tag("tr", *attributes): with tag("td"): text(rule_id) with tag("td"): text(string) doc.stag("br") text(string_annotation) for content in [ expectation, graphically_folded_expectation, utn_result, diffing ]: with tag("td"): text(content) for cp_int, count in unknown_cps.most_common(): print(count, f"U+{cp_int:04X}", unicodedata.name(chr(cp_int), "тАФ"), end=", ") print() print(f"{failure_count} differences out of {case_count} test cases.") (project_dir / "tests" / "index.html").write_text( yattag.indent(doc.getvalue()))
def scanParse(nmapOutput, fileName): log = open(fileName, 'wb') doc,tag,text = yattag.Doc().tagtext() doc.asis('<!DOCTYPE html>') with tag('html', lang ='en')
def result2html(self, targets, ip_list): """ Description: Converts Enumerate output to human-readable form :param targets: List containing TargetInfo Objects :return: Bootstrap-based HTML5 page of results """ password_policy_items = [ ["Password Min Length is", "MIN_PASSWORD_LENGTH"], [ "Passwords Stored in Plaintext", "DOMAIN_PASSWORD_STORE_CLEARTEXT" ], [ "No need for weekly password changes", "DOMAIN_REFUSE_PASSWORD_CHANGE" ], [ "Has Admin been locked out from remote logons", "DOMAIN_PASSWORD_LOCKOUT_ADMINS" ], ["Password Must be Complex", "DOMAIN_PASSWORD_COMPLEX"], [ "Password Cannot be changed without logging on", "DOMAIN_PASSWORD_NO_ANON_CHANGE" ], [ "No logons that exchange passwords via plaintext", "DOMAIN_PASSWORD_NO_CLEAR_CHANGE" ] ] self.result2html_dbg.debug("Starting Result2Html...", color=Format.color_info) doc, tag, text = yattag.Doc().tagtext() self.result2html_dbg.debug("Beginning html formatting", color=Format.color_info) doc.asis('<!DOCTYPE html>') with tag('html', lang="en"): with tag('head'): doc.asis('<meta charset="utf-8">') doc.asis( '<meta name="viewport" content="width=device-width, initial-scale=1">' ) doc.asis( '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">' ) with tag( 'script', src= "https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js" ): pass with tag( 'script', src= "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" ): pass with tag('body'): with tag('div', klass="container"): # Table for current IP for IP in ip_list: # Read Ips from list so that they are in order # Basic Info with tag("h3", klass=".text-primary"): text("%s Basic Info" % IP) with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text(IP) with tag('th'): text("Info") self.result2html_dbg.debug( "ICMP, MAC & Adapter") # Table rows with tag('tbody'): with tag('tr'): with tag('td'): text("Responds to ICMP") with tag('td'): text("True" if targets[IP]. RESPONDS_ICMP else "False") with tag('tr'): with tag('td'): text("MAC Address") with tag('td'): text(targets[IP]. MAC_ADDRESS if targets[IP]. MAC_ADDRESS else "None") with tag('tr'): with tag('td'): text("Adapter name") with tag('td'): text(targets[IP]. ADAPTER_NAME if targets[IP]. ADAPTER_NAME else "None") # Route self.result2html_dbg.debug( "Formatting route to target") if targets[IP].ROUTE: with tag("h3", klass=".text-primary"): text("Route to %s" % IP) with tag("h5"): text( "'*' is used to signify a failed jump") with tag("h5"): text( "Return path populate where applicable" ) with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("HOP #") with tag('th'): text("IP/Domain Path Out") with tag('th'): text( "IP/Domain Other Return Path(s)" ) # Table rows with tag('tbody'): for index, value in enumerate( targets[IP].ROUTE[0]): with tag('tr'): with tag('td'): text(1 + index) # hop with tag('td'): text(value) # ip with tag('td'): if targets[IP].ROUTE[ 1]: routeout = "" for ip in targets[ IP].ROUTE[1][ index]: routeout += "%s, " % ip text(routeout[:-2]) else: text("*") # OS Info self.result2html_dbg.debug("Formatting OS INFO") if targets[IP].OS_INFO: with tag("h3", klass=".text-primary"): text("OS info for %s" % IP) with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Suspected OS ") with tag('tbody'): # Table rows # TODO check that not list of suspected OS rather than list of list of suspected OS if targets[IP].OS_INFO: for suspected_os in targets[ IP].OS_INFO: with tag('tr'): with tag('td'): text(suspected_os) else: with tag('tr'): with tag('td'): text("No results") # SOFTWARE INFO self.result2html_dbg.debug( "Formatting Software INFO") if targets[IP].SOFTWARE_INFO: with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Software Info") with tag('tbody'): with tag('tr'): with tag('td'): text( "Not currently implemented :(" ) # WORKGROUP self.result2html_dbg.debug( "Workgroup not implemented") if targets[IP].WORKGROUP: with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Workgroup Info") with tag('tbody'): with tag('tr'): with tag('td'): text( "Not currently implemented :(" ) # Domain Groups self.result2html_dbg.debug( "Formatting Domain groups ") if targets[IP].DOMAIN_GROUPS: with tag("h3", klass=".text-primary"): text("Domain Groups for %s" % IP) with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Groups") with tag('th'): text("RID") with tag('tbody'): for item in targets[IP].DOMAIN_GROUPS: with tag('tr'): with tag('td'): text(item[0]) with tag('td'): text(item[1]) # Domain Users self.result2html_dbg.debug( "Formatting Domain users") if targets[IP].DOMAIN_USERS: with tag("h3", klass=".text-primary"): text("Domain Users for %s" % IP) with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Username") with tag('th'): text("RID") with tag('tbody'): for item in targets[IP].DOMAIN_USERS: with tag('tr'): with tag('td'): text(item[0]) with tag('td'): text(item[1]) # SESSIONS self.result2html_dbg.debug("Formatting Sessions") if targets[IP].SESSIONS: with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Session Info") with tag('tbody'): with tag('tr'): with tag('td'): text( "Not currently implemented :(" ) # NBT STAT self.result2html_dbg.debug("Formatting NBT STAT") with tag("h3", klass=".text-primary"): text("%s NBTSTAT" % IP) if targets[IP].NBT_STAT: with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("NBT STAT Info") with tag('tbody'): for NBT_INFO in targets[IP].NBT_STAT: with tag('tr'): with tag('td'): text(NBT_INFO) # SHARE INFO self.result2html_dbg.debug("Formatting Shares") if targets[IP].SHARE_INFO: with tag("h3", klass=".text-primary"): text("%s's Shares" % IP) with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Sharename") with tag('th'): text("Type") with tag('th'): text("Comment") with tag('tbody'): for x in range( len(targets[IP].SHARE_INFO)): with tag('tr'): with tag('td'): text(targets[IP]. SHARE_INFO[0][x]) with tag('td'): text(targets[IP]. SHARE_INFO[1][x]) with tag('td'): text(targets[IP]. SHARE_INFO[2][x]) # Local INFO self.result2html_dbg.debug("Formatting Local") if targets[IP].LOCAL_USERS and targets[ IP].LOCAL_GROUPS: with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Local Info") with tag('tbody'): with tag('tr'): with tag('td'): text( "Not currently implemented :(" ) # PASSWD_POLICY self.result2html_dbg.debug( "Formatting Password Policy") if targets[IP].PASSWD_POLICY: with tag("h3", klass=".text-primary"): text("%s Password Policy" % IP) with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Flag Name") with tag('th'): text("Policy Flag Desc") with tag('th'): text("State") with tag('tbody'): for x in range( len(targets[IP].PASSWD_POLICY) ): with tag('tr'): with tag('td'): text(password_policy_items[ x][1]) with tag('td'): text(password_policy_items[ x][0]) with tag('td'): text( str(targets[IP]. PASSWD_POLICY[x])) # PRINTER_INFO self.result2html_dbg.debug( "Formatting Printer Info") if targets[IP].PRINTER_INFO: with tag('table', klass="table table-condensed"): # Table headings with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Printer Info") with tag('tbody'): with tag('tr'): with tag('td'): text( "Not currently implemented :(" ) # PORTS self.result2html_dbg.debug("Formatting Ports") if targets[IP].PORTS: with tag("h3", klass=".text-primary"): text("Port scan of %s" % IP) with tag('table', klass="table table-condensed"): # Table headings # Port Service Version State with tag('thead', klass=".thead-dark"): with tag('tr'): with tag('th'): text("Port") with tag('th'): text("Service") with tag('th'): text("Version") with tag('th'): text("State") with tag('tbody'): for this_port in targets[IP].PORTS: with tag('tr'): port, service, version, state = this_port with tag('td'): text(port) with tag('td'): text(service) with tag('td'): text(version) with tag('td'): text(state) self.result2html_dbg.debug("Html generation success", color=Format.color_success) return doc.getvalue()
def testSimpleText(self): io_gift = StringIO(""" ::Le numérique concerne tout le monde:: **Quels étudiants sont concernés par le numérique ?** Le numérique concerne évidemment les étudiants en informatique et plus généralement les étudiants des filières scientifiques. Mais vous qui êtes inscrits dans une université de sciences humaines et sociales, êtes-vous concernés ? Choisissez au moins 3 des domaines suivants et faites des recherches pour voir en quoi ils sont impactés par le numérique : les médias, la santé, l'histoire, la sociologie, la linguistique, les arts, la culture, l'enseignement, l'archéologie. Faites une synthèse en quelques lignes de vos recherches en précisant les domaines auxquels vous vous êtes intéressés. Indiquez les liens des sites sur lesquels vous avez trouvé ces informations. La liste est non exhaustive et vous pouvez vous intéresser à d'autres domaines. {#### # Le numérique concerne tout le monde Ces recherches ont dû vous convaincre, si c'était nécessaire, que le numérique **n'est pas réservé** aux informaticiens, il concerne tout le monde, toutes les disciplines. S'agissant plus particulièrement des **sciences humaines**, la prise en compte du numérique a fait évoluer les champs disciplinaires pour faire apparaître ce qu'on appelle les **humanités numériques** ( *digital humanities* en anglais). Voici quelques exemples que nous vous proposons, n'hésitez pas à proposer d'autres exemples dans le forum de discussion : * Dans les **médias** : nouveau sous-métier de journalisme : les **data-journalistes** * [data-visualisation](http://www.lemonde.fr/data-visualisation/) * [journalisme de données](http://fr.wikipedia.org/wiki/Journalisme_de_données) * Dans la **santé** : (imagerie, dossier numérique du patient, ...) * [simulation](https://interstices.info/jcms/c_21525/simulation-de-loperation-de-la-cataracte) * En **histoire, sociologie, linguistique** : *fouille de données* * [fouille de données](http://www.youtube.com/watch?feature=player_embedded&v=tp4y-_VoXdA) * En **art et culture** : * [Le Fresnoy](http://www.lefresnoy.net/fr/Le-Fresnoy/presentation) * Dans l'**enseignement** : (outils numérique d'accompagnement scolaire, MOOC,...): * [FUN](https://www.france-universite-numerique-mooc.fr/cours/) * En fouille archéologique : une réalisation prestigieuse réalisée à Lille3 : * [vase qui parle](http://bsa.biblio.univ-lille3.fr/blog/2013/09/exposition-le-vase-qui-parle-au-palais-des-beaux-arts-de-lille/) } """) questions = pygift.parseFile(io_gift) io_gift.close() d = yattag.Doc() with d.tag('html'): with d.tag('head'): d.stag('meta', charset="utf-8") with d.tag('h2'): d.text(str(questions[0].answers.__class__)) for q in questions: q.toHTML(d, True) for q in questions: q.toHTML(d, False) self.assertEqual(len(questions), 1, "More than one Question for 'TestSimpleText'") # TEST HTML soup = BeautifulSoup(d.getvalue(), 'html.parser') for i, form in enumerate(soup.find_all('form')): self.assertEqual(form.h3['class'][0], u'questiontitle', " Not h3 or not good class for h3") self.assertEqual(str(form.h3.contents[0]), u'Le numérique concerne tout le monde') if i == 1: self.assertIsNotNone(form.textarea) self.assertTrue(form.textarea['placeholder'], _(u'Your answer here')) for j, div in enumerate(form.find_all('div')): if j == 0: self.assertEqual(div['class'][0], u'questiontext', "Not div or not good class for 1rst div") if (j == 1): self.assertEqual(div['class'][0], u'global_feedback') self.assertEqual(str(div.contents[0]), "<b><em>Feedback:</em></b>") self.assertEqual( str(div.contents[2]), "<h1>Le numérique concerne tout le monde</h1>") self.assertEqual( str(div.contents[4]), """<p>Ces recherches ont dû vous convaincre, si c'était nécessaire, que le numérique <strong>n'est pas réservé</strong> aux informaticiens, il concerne tout le monde, toutes les disciplines.<br/> S'agissant plus particulièrement des <strong>sciences humaines</strong>, la prise en compte du numérique a fait évoluer les champs disciplinaires pour faire apparaître ce qu'on appelle les <strong>humanités numériques</strong> ( <em>digital humanities</em> en anglais).<br/> Voici quelques exemples que nous vous proposons, n'hésitez pas à proposer d'autres exemples dans le forum de discussion :<br/> <em> Dans les <strong>médias</strong> : nouveau sous-métier de journalisme : les <strong>data-journalistes</strong><br/> * <a href="http://www.lemonde.fr/data-visualisation/">data-visualisation</a><br/> * <a href="http://fr.wikipedia.org/wiki/Journalisme_de_données">journalisme de données</a><br/> </em> Dans la <strong>santé</strong> : (imagerie, dossier numérique du patient, ...)<br/> * <a href="https://interstices.info/jcms/c_21525/simulation-de-loperation-de-la-cataracte">simulation</a><br/> <em> En <strong>histoire, sociologie, linguistique</strong> : </em>fouille de données<em><br/> * <a href="http://www.youtube.com/watch?feature=player_embedded&v=tp4y-_VoXdA">fouille de données</a><br/> </em> En <strong>art et culture</strong> :<br/> * <a href="http://www.lefresnoy.net/fr/Le-Fresnoy/presentation">Le Fresnoy</a><br/> <em> Dans l'<strong>enseignement</strong> : (outils numérique d'accompagnement scolaire, MOOC,...):<br/> * <a href="https://www.france-universite-numerique-mooc.fr/cours/">FUN</a><br/> </em> En fouille archéologique : une réalisation prestigieuse réalisée à Lille3 :<br/> * <a href="http://bsa.biblio.univ-lille3.fr/blog/2013/09/exposition-le-vase-qui-parle-au-palais-des-beaux-arts-de-lille/">vase qui parle</a></p>""" ) print("[GiftParsingHTMLTestCase]-- check_text1 OK --")
# full size TeX translator using Eijkhout's manual @ doc/ # using http://www.yattag.org/ html template generator import yattag doc, tag, text, line = yattag.Doc().ttl() import os, sys, re with tag('html'): with tag('head'): with tag('style', media="all", type="text/css"): # https://stackoverflow.com/questions/3341485/how-to-make-a-html-page-in-a4-paper-size-pages text(''' @page { /* e-book optimized for mobile phone reading */ size: 118.8mm 68.2mm; margin: 2mm 2mm 2mm 2mm; } ''') with tag('body'): text('Hello') open('html.html', 'w').write(yattag.indent(doc.getvalue()))
def testAnswerArea(self): #INITIALISATION d = yattag.Doc() with d.tag('html'): with d.tag('head'): d.stag('meta', charset="utf-8") # AVEC UNE RÉPONSE SIMPLE io_simple = StringIO(""" ::first paret of text of Q2:: //comment in Q2 second part of text of Q2 My Question{ =2 =Q2 =Question2 } other part """) questions = pygift.parseFile(io_simple) io_simple.close() with d.tag('h2'): d.text(str(questions[0].answers.__class__)) for q in questions: q.toHTML(d, True) for q in questions: q.toHTML(d, False) self.assertEqual(len(questions), 1, "More than one Question for 'TestAnswerArea 1'") soup = BeautifulSoup(d.getvalue(), 'html.parser') for i, form in enumerate(soup.find_all('form')): self.assertEqual(form.h3['class'][0], u'questiontitle', " Not h3 or not good class for h3") if i == 0: for j, div in enumerate(form.find_all('div')): if j == 0: self.assertEqual(div['class'][0], u'questiontext') self.assertEqual( str(div.contents[0]), '<p>second part of text of Q2<br/>\nMy Question</p>' ) if j == 2: self.assertEqual(div['class'][0], 'groupedAnswerFeedback') self.assertEqual( str(div.contents[0]), '<ul><li class="right_answer">2</li><li class="right_answer">Q2</li><li class="right_answer">Question2</li></ul>' ) if i == 1: for j, span in enumerate(form.find_all('span')): if j == 0: self.assertEqual(span['class'][0], u'questionTextInline') self.assertEqual( str(span.contents[0]), '<p>second part of text of Q2<br/>\nMy Question</p>' ) if j == 1: self.assertEqual(span['class'][0], u'questionAnswersInline') self.assertEqual(span.input['type'], u'text') print("[GiftParsingHTMLTestCase]-- check_answer_area OK --")
def css_link(): # Template version available. doc = yattag.Doc() doc.stag('link', rel='stylesheet', type='text/css', href='/main.css') return doc.getvalue()
def testMatch(self): d = yattag.Doc() with d.tag('html'): with d.tag('head'): d.stag('meta', charset="utf-8") io_match = StringIO(""" ::Match:: Match the following countries with their corresponding capitals. { =Canada -> Ottawa =Italy -> Rome =Japan -> Tokyo =India -> New Delhi } """) questions = pygift.parseFile(io_match) io_match.close() with d.tag('h2'): d.text(str(questions[0].answers.__class__)) for q in questions: q.toHTML(d, True) for q in questions: q.toHTML(d, False) soup = BeautifulSoup(d.getvalue(), 'html.parser') for i, form in enumerate(soup.find_all('form')): self.assertEqual(form.h3['class'][0], u'questiontitle', " Not h3 or not good class for h3") if i == 0: for j, div in enumerate(form.find_all('div')): if j == 0: self.assertEqual(div['class'][0], u'questiontext') if j == 2: self.assertEqual(div['class'][0], u'groupedAnswerFeedback') self.assertEqual( str(div.contents), u'<ul><li class="right_answer">Canada ⇝ Ottawa</li><li class="right_answer">Italy ⇝ Rome</li><li class="right_answer">Japan ⇝ Tokyo</li><li class="right_answer">India ⇝ New Delhi</li></ul>' ) if i == 1: self.assertIsNotNone(form.table) for j, tr in enumerate(soup.find_all('tr')): # WARNING : check options for p, td in enumerate(tr.find_all('td')): if p == 0: if j == 0: self.assertEqual(tr.td.contents[0], u'Canada ') if j == 1: self.assertEqual(tr.td.contents[0], u'Italy ') if j == 2: self.assertEqual(tr.td.contents[0], u'Japan ') if j == 3: self.assertEqual(tr.td.contents[0], u'India ') if p == 1: self.assertIsNotNone(td.select) self.assertIsNotNone(td.find('select')['name']) self.assertEqual( len(td.find('select').find_all('option')), 4) print("[GiftParsingHTMLTestCase]-- check_match OK --")
def test_html(self) -> None: """Tests HTML coloring.""" doc = yattag.Doc() util.format_even_odd(["2*", "4"], doc) self.assertEqual(doc.getvalue(), '<span style="color: blue;">2</span>, 4')
for p in pages: book = "" name = p.split('.')[0] with open(name + '.tmp', 'r') as f: newlines = 0 paragraph = "" for line in f: line = line.strip() if len(line) == 0: newlines += 1 else: paragraph += line + '\n' if newlines == 2: doc,tag,text = yattag.Doc().tagtext() with tag('p'): text(paragraph) book += doc.getvalue() newlines = 0 paragraph = "" if newlines != 2: doc,tag,text = yattag.Doc().tagtext() with tag('p'): text(paragraph) book += doc.getvalue() aux = str(book) book = ""
def test_html_multi_odd(self) -> None: """Tests HTML output with multiple odd numbers.""" doc = yattag.Doc() util.format_even_odd(["1", "3"], doc) self.assertEqual(doc.getvalue(), "1, 3")
def recipe_as_html(recipe, display_opts, order_link=None, condense_ingredients=False, fancy=True, convert_to=None): """ use yattag lib to build an html blob contained in a div for the recipe""" doc, tag, text, line = yattag.Doc().ttl() glassware = { "cocktail": "/static/glassware/coupe.svg", "martini": "/static/glassware/martini.svg", "highball": "/static/glassware/highball.svg", "collins": "/static/glassware/collins.svg", "hurricane": "/static/glassware/highball.svg", "rocks": "/static/glassware/rocks.svg", "copper mug": "/static/glassware/mule_mug.svg", "tiki": "/static/glassware/rocks.svg", "flute": "/static/glassware/flute.svg", "glencairn": "/static/glassware/glencairn.svg", "mug": "/static/glassware/irish_coffee_mug.svg", "white wine": "/static/glassware/white_wine_kentfield.svg", "red wine": "/static/glassware/red_wine_kentfield.svg", "shooter": "/static/glassware/shooter.svg", "shot": "/static/glassware/shot.svg", } if convert_to: recipe.convert(convert_to) main_tag = 'div' extra_kwargs = {"klass": "card card-body h-100"} if fancy: extra_kwargs['klass'] += " shadow-sm" if order_link: main_tag = 'a' extra_kwargs['href'] = order_link with tag(main_tag, id=recipe.name, **extra_kwargs): # embed glass image in name line name_line = [] recipe_name = recipe.name if display_opts.origin and 'schubar original' in recipe.origin.lower(): recipe_name += sup('*') # attempt hack for keeping text aligned right of image when wrapping if fancy: name_line.append( '<div class="clearfix" style="position:relative;">') name_line.append( '<img src={} style="height:2.2em; float:left;">'.format( glassware.get(recipe.glass))) name_line.append( close(recipe_name, 'span', style="position:absolute;bottom:0;")) else: name_line.append(close(recipe_name, 'span')) if display_opts.prices and recipe.max_cost: price = util.calculate_price(recipe.max_cost, display_opts.markup) price = '&{};{}{}'.format('nbsp' if fancy else 'mdash', sup('$'), price) if fancy: name_line.append(close(price, 'p', style="float:right")) else: name_line.append(price) if fancy: name_line.append("</div><!-- recipe name text -->") name_line = close( ''.join(name_line), 'h4', class_="card-title", style="margin-left:-0.35em;") # tweak to the left else: name_line = close(''.join(name_line), 'h3') doc.asis(name_line) if display_opts.prep_line: doc.asis(small_br(recipe.prep_line(extended=True, caps=False))) if display_opts.info and recipe.info: doc.asis(small_br(em(recipe.info))) if condense_ingredients: ingredients = ', '.join([ str(ingredient.specifier) for ingredient in recipe.ingredients if isinstance(ingredient, QuantizedIngredient) ]) doc.asis(ingredients + '<br>') else: with tag('ul', id='ingredients'): for item in recipe.ingredients: line('li', item.str(), type="none") if display_opts.variants: if condense_ingredients: # also need these to not be indented for variant in recipe.variants: doc.asis(small(em(variant))) else: with tag('ul', id='variants'): for variant in recipe.variants: with tag('small'): with tag('li', type="none"): line('em', variant) if display_opts.examples and recipe.examples: # and recipe.name != 'The Cocktail': # special display for recipe with examples # TODO pull out bitters into supplimental list if display_opts.prices: for e in sorted(recipe.examples, key=lambda x: x.cost): markup = 1.1 + display_opts.markup if recipe.name == "A Dram" else display_opts.markup fields = { 'cost': util.calculate_price(e.cost, markup), 'abv': e.abv, 'kinds': e.kinds } doc.asis( small_br("${cost:>3.0f} | {abv:.1f}% | {kinds}".format( **fields))) else: for e in recipe.examples: doc.asis( small_br( "${cost:.2f} | {abv:.2f}% | {std_drinks:.2f} | {kinds}" .format(**e._asdict()))) return str(doc.getvalue())
def image(path, **opts): doc, tag, text = yattag.Doc().tagtext() doc.stag('img', src=path, **opts) return doc.getvalue()