def cv(): base = Path('cv') with (base / 'content' / 'data.toml').open() as toml, \ (base / 'style' / 'index.css').open() as css: data = loads(toml.read()) with html(lang='en') as document: with head(): meta(charset='utf-8') meta(name='description', content=f'{SHARED.info.person_name} (engineer|designer)') meta(name='keywords', content=','.join(SHARED.meta.keywords)) meta(name='author', content=f'{SHARED.info.person_name}') title(SHARED.info.person_name) style(raw(css.read())) with body(): with table(id='content') as content: with tr(): with td(id='image', colspan=4): img(src='img/header.png', alt='...') div('Curriculum Vitae') for row in chain( Basic(data['basic']).as_rows(), Skills(data['skills']).as_rows(), Experience(data['experience']).as_rows(), Education(data['education']).as_rows()): content.add(row) copyright = comment(f'Copyright (C) 2015 - {datetime.now().year} ' f'{SHARED.info.person_name}. ' 'All rights reserved.') return f'<!DOCTYPE html>{copyright}{document.render(pretty=False)}'
def site(): base = Path('website') with (base/'content'/'index.toml').open() as toml, \ (base/'style'/'index.css').open() as css: data = loads(toml.read()) with html(lang='en') as document: with head(): meta(charset='utf-8') meta(name='description', content=f'{SHARED.info.person_name} (engineer|designer)') meta(name='keywords', content=','.join(SHARED.meta.keywords)) meta(name='author', content=f'{SHARED.info.person_name}') title(SHARED.info.person_name) link(rel='shortcut icon', type='image/x-icon', href='favicon.ico') link(rel='icon', type='image/x-icon', href='favicon.ico') style(raw(css.read())) script(src='website/js/anim.js') script(src='website/js/index.js') with body(): _block('engineer', data['engineer']) _block('designer', data['designer']) with div(id='handler'): div(raw('«»')) script('main();', type='text/javascript') copyright = comment(f'Copyright (C) 2015 - {datetime.now().year} ' f'{SHARED.info.person_name}. ' 'All rights reserved.') return f'<!DOCTYPE html>{copyright}{document.render(pretty=False)}'
def _common_meta(document): with document: H.attr(lang=u'en') with document.head: H.meta(charset=u'utf-8') H.meta(name=u'generator', content=u'HTTPolice %s' % version) H.style(type=u'text/css').add_raw_string(css_code)
def dominate_final_page(): """ 第四頁:感謝頁, 目標:利用dominate寫出 enter_page 的 html並在 templates 資料夾中存成 index4.html 分為三個區塊 doc = dominate.document() with doc.head (包含css的style;meta確保中文可以運行在utf-8下) with doc.body (h1) 最後寫入文件中(在templates資料夾中存成index4.html) """ doc = dominate.document(title="thank_you_page") with doc.head: tags.meta(name='charset', content="utf-8") tags.style("""\ body { background-color: #F9F8F1; color: #2C232A; font-family: sans-serif; font-size: 14; text-align: center; } """) with doc.body: tags.h1('Thank You!') fn = 'templates/index4.html' with open(file=fn, mode='w', encoding='utf-8') as f: f.write(doc.render()) print(f)
def add_style(name, linked=False): if linked: link(rel='stylesheet', href='file://' + os.path.join(os.path.dirname(__file__), name)) else: style(read_resource(name))
def add_head_style(this_urlpath=""): """Adds <link> tags for style files, assuming <head> context.""" tags.meta(charset="utf-8") tags.meta(name="viewport", content="width=device-width, initial-scale=1.0") emoji = urls.link(this_urlpath, "NotoColorEmoji.ttf") tags.style(f""" @font-face {{ font-family: 'Noto Color Emoji'; src: local('Noto Color Emoji'), url({emoji}) format("truetype");' }} """) tags.link( rel="icon", type="image/png", sizes="32x32", href=urls.link(this_urlpath, "favicon-32x32.png"), ) tags.link( rel="icon", type="image/png", sizes="16x16", href=urls.link(this_urlpath, "favicon-16x16.png"), ) tags.link( rel="stylesheet", type="text/css", href=urls.link(this_urlpath, "style.css"), ) tags.script(src=urls.link(this_urlpath, "video.js")) tags.script(src="https://kit.fontawesome.com/7e1cde4d00.js", crossorigin="anonymous")
def __init__(self, title, css='splendor'): self.doc = dominate.document(title=title) self.has_widgets = False self.has_tables = False with self.doc.head: link(rel='stylesheet', href=Journal.css[css], type='text/css') # bokeh css/js link_href, js_src = bu.get_bokeh_src() link(rel='stylesheet', href=link_href, type="text/css") script(type='text/javascript', src=js_src) # css to center the bokeh plots style(""" div.bk-grid { margin: auto; width: 50%; } div.bk-plot-layout { margin: auto; width: 50%; } div.bk-root { margin: auto; width: 50%; } div.bk-canvas-wrapper { margin: auto; width: 50%; } """)
def user_summary_for(rtype, storages, output_path: Path): ustats = {} def reg(user, query, stats): if user not in ustats: ustats[user] = {} ustats[user][query] = stats with ProcessPoolExecutor() as pp: digests = pp.map(get_digest, [s.path for s in storages]) for s, digest in zip(storages, digests): everything = flatten([ch for ch in digest.changes.values()]) for user, items in group_by_key(everything, key=lambda x: x.user).items(): reg(user, s.name, len(items)) now = datetime.now() doc = dominate.document( title= f'axol tags summary for {[s.name for s in storages]}, rendered at {fdate(now)}' ) with doc.head: T.style(STYLE) raw_script(JS) # TODO necessary? # TODO FIXME can't inline due to some utf shit sortable_js = Path(__file__).absolute().parent / 'js' / 'sorttable.js' T.script(src=str(sortable_js)) ft = FormatTrait.for_(rtype) with doc.body: with T.table(cls='sortable'): emitted_head = False for user, stats in sorted(ustats.items(), key=lambda x: (-len(x[1]), x)): if not emitted_head: with T.thead(): T.td('user') for q, _ in stats.items(): T.td(q) emitted_head = True with T.tr(): T.td(ft.user_link(user)) for q, st in stats.items(): with T.td(sorttable_customkey=str(st)): # TODO I guess unclear which tag to choose though. T.a( q, href=f'summary/{q}.html' ) # TODO link to source in index? or on pinboard maybe # TODO also project onto user's tags straight away T.sup( str(st) if st < 5 else T.b( T.font(str(st), color='red'))) # TODO css output_path.write_text(str(doc)) logger.info('Dumped user summary to %s', output_path)
def prepare_page(): page = dominate.document(title='parsePic') with page.head: style(""" img { max-width: 1600px; max-height: 800px; } """) return page
def make_html(pixdir, route_name, results): title = "Pictures from %s" % route_name document = dominate.document(title=title) with document.head: meta(charset="UTF-8") style(""" table { page-break-inside:auto; border-spacing:3px; padding:3px; } table { margin-left:auto; margin-right:auto; } table, td, th, tr { border:1px solid green; } th { background-color: green; color: white; } th.tiny { width:3%; } th.narrow { width:47%; } th.wide { width:50%; } tr { page-break-inside:avoid; page-break-after:auto; } tr.center { margin-left:auto; margin-right:auto; } tr.alt { background-color: #f0f0f0; } caption { background-color: #c0c040; font-size: 16px; \ font-family: "Courier New"; } body { font-size: 16px; } @media print { body { font-size: 8px; font-family: "Courier New" } caption { font-size: 10px } a { text-decoration: none; font-style: italic; font-weight: bold} th { background-color: white; color: black; } } """) with document.body: with table(): caption(route_name) tr(th("Name"), th("Description"), th("Imagefile")) for time, filename, gc, tp in results: pathname = os.path.join(pixdir, filename) gcname, gcdesc = map(str, gc[1:]) gclink = "http://coord.info/%s" % quote(gcname) with tr(): td(a(gcname, href=gclink)) td(gcdesc) td(a(filename, href=quote(pathname))) print >> open("make_html.html", "w"), document
def build_html(parsed_tokens, css_style): with document(title="Code") as doc: style(css_style) for token in parsed_tokens: if token.type == line_break: br() else: lines = token.content.split('\n') for j in range(len(lines)): if j != 0: br() span(lines[j], cls=token.type) return doc.render(pretty=False)
def dominate_enter_page(): """ 第三頁:確認資訊頁面,對應到 @app.route('/jump') 及其函數 registerpage_run [if request.method == 'POST'] 目標:利用dominate寫出 enter_page 的 html並在 templates 資料夾中存成 index3.html 分為三個區塊 doc = dominate.document() with doc.head (包含css的style;meta確保中文可以運行在utf-8下) with doc.body (包含 6 information: name/ password/ student_id/ telephone_number/ school_bike_license/ bike_lock_number and a button confirm) 最後寫入文件中(在templates資料夾中存成index3.html) """ doc = dominate.document(title="entered") with doc.head: tags.meta(name='charset', content="utf-8") tags.style("""\ body { background-color: #F9F8F1; color: #2C232A; font-family: sans-serif; font-size: 14; text-align: center; } """) with doc.body: tags.h1('welcome' + str(name_list_temp[0])) tags.h2('please confirm your information') with tags.section(cls='information check'): with tags.div(cls='name', style="text-align: center"): tags.label('your name is ' + str(name_list_temp[0])) with tags.div(cls='password', style="text-align: center"): tags.label('your password is ' + str(password_temp[0])) with tags.div(cls='student_id', style="text-align: center"): tags.label('your student id is ' + str(student_id_temp[0])) with tags.div(cls='telephone', style="text-align: center"): tags.label('your telephone number is ' + str(telephone_number_temp[0])) with tags.div(cls='license', style="text-align: center"): tags.label('the status of your bike_lice ' + str(school_bike_license_temp[0])) with tags.div(cls='lock_number', style="text-align: center"): tags.label('your bike lock number is ' + str(bike_lock_number_temp[0])) with tags.div(cls='button', style="margin:0 auto; width:250px;"): tags.input(type='button', value='confirm', style="width:120px; background-color:pink;", onclick="location.href='http://127.0.0.1:5000/entered'") fn = 'templates/index3.html' with open(file=fn, mode='w', encoding='utf-8') as f: f.write(doc.render()) print(f)
def __init__(self, web_dir, title=None, refresh=0, overwrite=True, base_url='~/www', inverted=False): """Initialize the HTML classes Parameters: web_dir (str) -- a directory that stores the webpage. HTML file will be created at <web_dir>/index.html; images will be saved at <web_dir/images/ title (str) -- the webpage name refresh (int) -- how often the website refresh itself; if 0; no refreshing """ if title is None: title = web_dir.split('/')[-1] self.title = title self._url = web_dir self.web_dir = web_dir if base_url is not None: self.web_dir = os.path.expanduser(base_url) + self.web_dir self.img_dir = os.path.join(self.web_dir, 'images') self.image_dir = self.img_dir self.video_dir = os.path.join(self.web_dir, 'videos') self.overwrite = overwrite if not os.path.exists(self.web_dir): os.makedirs(self.web_dir) if not os.path.exists(self.img_dir): os.makedirs(self.img_dir) if not os.path.exists(self.video_dir): os.makedirs(self.video_dir) self.doc = dominate.document(title=title) with self.doc.head: link(rel='stylesheet', href='/css/main.css') css = """ table { border-collapse: collapse; border: 1px solid #ccc; margin: auto !important; table-layout: fixed; margin-bottom: 10px; } th, span { font-family: monospace; } td { word-wrap: break-word; padding: 5px; } caption { text-align: center; font-weight: 600; } h1, h2, h3 { text-align: center; font-weight: normal; } html, body { font-size: 18px; } """ if inverted: css += """ html, body { background-color: #111; color: #eee; } """ style(css) meta(charset='utf-8') if refresh > 0: with self.doc.head: meta(http_equiv="refresh", content=str(refresh))
def dominate_homepage(): """ 第一頁:歡迎頁面,對應到 @app.route('/') 及其函數 homepage_run() 目標:利用dominate寫出homepage的html並在templates資料夾中存成index1.html 分為三個區塊 doc = dominate.document() with doc.head (包含css的style;meta確保中文可以運行在utf-8下) with doc.body (包含welcome words and a button) 最後寫入文件中(在templates資料夾中存成index1.html) """ doc = dominate.document(title='homepage') with doc.head: tags.meta(name='charset', content="utf-8") tags.style("""\ body { background-color: #F9F8F1; color: #2C232A; font-family: sans-serif; font-size: 30; text-align: center; } section{ width: 300px; height: 300px; position: absolute; top: 50%; left: 50%; overflow: auto; text-align: center; margin-left:-150px; margin-top:-150px; } """) with doc.body: with tags.section(): with tags.div(cls='headline', style='font-size: 30;'): tags.h1('Find Your Bike') tags.input(type='button', value='click me', onclick="location.href='http://127.0.0.1:5000/jump'", style="width:120px; background-color:pink; font-size: 14;") fn = 'templates/index1.html' with open(file=fn, mode='w', encoding='utf-8') as f: f.write(doc.render()) print(f)
def dominate_wrong_information_page(): """ 第五頁:資料庫連接錯誤頁面,對應到 @app.route('/entered') 及其函數 eneter_success() 目標:利用dominate寫出homepage的html並在templates資料夾中存成index5.html 分為三個區塊 doc = dominate.document() with doc.head (包含css的style;meta確保中文可以運行在utf-8下) with doc.body (包含 words and a button) 最後寫入文件中(在templates資料夾中存成index5.html) """ doc = dominate.document(title='error_page') with doc.head: tags.meta(name='charset', content="utf-8") tags.style("""\ body { background-color: #F9F8F1; color: #2C232A; font-family: sans-serif; font-size: 30; text-align: center; } section{ width: 300px; height: 300px; position: absolute; top: 50%; left: 50%; overflow: auto; text-align: center; margin-left:-150px; margin-top:-150px; } """) with doc.body: with tags.section(): with tags.div(cls='headline', style='font-size: 30;'): tags.h2("wrong information! please try again") tags.input(type='button', value='return back', onclick="location.href='http://127.0.0.1:5000/'", style="width:120px; background-color:pink; font-size: 14;") fn = 'templates/index6.html' with open(file=fn, mode='w', encoding='utf-8') as f: f.write(doc.render()) print(f)
def write_index(storages, output_dir: Path): now = datetime.now() doc = dominate.document( title= f'axol index for {[s.name for s in storages]}, rendered at {fdate(now)}' ) # TODO don't need this anymore? rss = True if rss: outlines = [] for storage in storages: name = storage.name htmlUrl = 'https://whatever' url = f'https://unstable.beepb00p.xyz/atom/{name}.xml' outlines.append( f'<outline title="{name}" text="{name}" xmlUrl="{url}" htmlUrl="{htmlUrl}"></outline>' ) outliness = "\n".join(outlines) XML = f""" <?xml version="1.0" encoding="UTF-8"?> <opml version="2.0"> <body> <outline text="All"> {outliness} </outline> </body> </opml> """ (output_dir / 'rendered' / 'atom' / 'feeds.opml').write_text(XML) with doc.head: T.style(STYLE) with doc.body: with T.table(): for storage in storages: with T.tr(): T.td(storage.name) T.td(T.a('summary', href=f'summary/{storage.name}.html')) T.td(T.a('history', href=f'rendered/{storage.name}.html')) T.div(T.b(T.a('pinboard users summary', href=f'pinboard_users.html'))) T.div(T.b(T.a('reddit users summary', href=f'reddit_users.html'))) T.div(T.b(T.a('github users summary', href=f'github_users.html'))) T.div(T.b(T.a('twitter users summary', href=f'twitter_users.html'))) # TODO 'last updated'? (output_dir / 'index.html').write_text(str(doc))
def dump_html_standalone(snippets, fname, webpage_style, include_banner, include_vernums, html_assets, html_classes): from dominate import tags, document from dominate.util import raw from . import GENERATOR from .core import SerAPI from .html import gen_banner, wrap_classes, ASSETS from .pygments import HTML_FORMATTER doc = document(title=fname) doc.head.add(tags.meta(charset="utf-8")) doc.head.add(tags.meta(name="generator", content=GENERATOR)) doc.set_attribute("class", "alectryon-standalone") for css in ASSETS.ALECTRYON_CSS: doc.head.add(tags.link(rel="stylesheet", href=css)) for link in (ASSETS.IBM_PLEX_CDN, ASSETS.FIRA_CODE_CDN): doc.head.add(raw(link)) for js in ASSETS.ALECTRYON_JS: doc.head.add(tags.script(src=js)) html_assets.extend(ASSETS.ALECTRYON_CSS) html_assets.extend(ASSETS.ALECTRYON_JS) pygments_css = HTML_FORMATTER.get_style_defs('.highlight') doc.head.add(tags.style(pygments_css, type="text/css")) cls = wrap_classes(webpage_style, *html_classes) root = doc.body.add(tags.article(cls=cls)) if include_banner: root.add(raw(gen_banner(SerAPI.version_info(), include_vernums))) for snippet in snippets: root.add(snippet) return doc.render(pretty=False)
def get_html_str(self, list_pocket_items: List[PocketItem]) -> str: """Generate the HTML code of the report page Args: list_pocket_items (List[PocketItem]): Returns: str: The complete HTML code of the generated report as a string """ with self.doc.head: tags.style( ".defaultfontfamily {font-family: Lucida Sans Unicode,Lucida Grande,sans-serif;}", type="text/css", ) for item in list_pocket_items: self._add_item(item) return self.doc.render()
def render_summary(repo: Path, digest: Changes[Any], rendered: Path) -> Path: rtype = get_result_type(repo) # TODO ?? # ODO just get trait for type?? Cumulative = CumulativeBase.for_(rtype) NOW = datetime.now() name = repo.stem everything = flatten([ch for ch in digest.changes.values()]) before = len(everything) grouped = group_by_key(everything, key=Cumulative.cumkey) print(f'before: {before}, after: {len(grouped)}') cumulatives = list(map(Cumulative, grouped.values())) cumulatives = list(sorted(cumulatives, key=Cumulative.sortkey)) doc = dominate.document( title=f'axol results for {name}, rendered at {fdate(NOW)}') with doc.head: T.style(STYLE) raw_script(JS) with doc: T.h3("This is axol search summary") T.div( "You can use 'hide' function in JS (chrome debugger) to hide certain tags/subreddits/users" ) T.h4("Sources summary") # TODO wrap in div? with T.div(): Cumulative.sources_summary(everything) for cc in cumulatives: T.div(cc.format(), cls='item') rendered.mkdir(exist_ok=True, parents=True) sf = rendered.joinpath(name + '.html') with sf.open('w') as fo: fo.write(str(doc)) return sf
def page_a(): global widgets init_widgets() # Create a dominate document, see https://github.com/Knio/dominate widgets.dominate_document() with widgets.dom_doc.body: # add css elements here... style(raw("""body {background-color:powderblue;}""")) args, _redirect_page_metrics = widgets.process_req(request) if not args: return _redirect_page_metrics app.logger.info("{} : args {}".format(PAGE_URL, args)) # redirect to another page based on widget data... _redirect = redirect_lookup_table(args.get("sel_nexturl", None)) if _redirect: return redirect(_redirect) widgets.get("sel_nexturl").value = '99' doc_layout = layout(sizing_mode='scale_width') doc_layout.children.append( row(Div(text="""<h1>pywrapBokeh</h1><h2>Page A</h2>"""), Paragraph(text="""Play with all these widgets."""))) source = AjaxDataSource( data=dict(x=[], y=[]), adapter=CustomJS(code="return cb_data.response"), data_url="http://127.0.0.1:6800{}".format(PAGE_URL_GET_DATA), polling_interval=1000, mode='append') fig = figure(title="Streaming Example") fig.line('x', 'y', source=source) doc_layout.children.append(fig) doc_layout.children.append(row(widgets.get("sel_nexturl"))) return widgets.render(doc_layout)
def html(self): """ Method to get the `dominate` HTML of the page. This HTML needs to be rendered. Returns: dominate.document: HTML document corresponding to the page. """ doc = dominate.document(title=self.title) # Add favicon if self.favicon is not None: with doc.head: link(rel='icon', href=self.favicon) # Add external files (Skin) if self.skin is not None: with doc.head: for ref in self.skin.libs: # Libs link(rel='stylesheet', crossorigin='anonymous', href=ref) for ref in self.skin.fonts: # Fonts link(rel='stylesheet', type='text/css', href=ref) if self.skin.rules != "": style(raw(self.skin.rules)) # Add Widgets HTML to the page main_div = div(cls="container") for w in self.widgets: main_div.add(w.html()) main_div.add(br()) doc.add(main_div) # Add Javascript code to the page js_str = "\n\n".join([a.js() for a in self.ajax()]) if js_str != '': doc.add(script(src=JQUERY_CDN)) doc.add(script(raw(js_str + "\n\n" + COMMON_JS))) return doc
def parse(target='', source='', payload=''): try: with open(f'{lib_dir}/style.css') as s: styles = s.read() except FileNotFoundError: styles = create_css() doc = dominate.document(title=f'YAT') with doc.head: style(styles) # link(rel='stylesheet', href=f'{lib_dir}/style.css') with doc: container = body(cls='body').add(div(cls='def_box')) try: payload[0]['translations'][0]['backTranslations'] query, dict_ = parse_dict(payload) dict_html(container, query, dict_, source, target) return doc except (KeyError): trans_html(container, payload, source) return doc
def dominate_error_page(): """ 第五頁:資料庫連接錯誤頁面,對應到 @app.route('/entered') 及其函數 eneter_success() 目標:利用dominate寫出homepage的html並在templates資料夾中存成index5.html 分為三個區塊 doc = dominate.document() with doc.head (包含css的style;meta確保中文可以運行在utf-8下) with doc.body (包含 words and a button) 最後寫入文件中(在templates資料夾中存成index5.html) """ doc = dominate.document(title='error_page') with doc.head: tags.meta(name='charset', content="utf-8") tags.style("""\ body { background-color: #F9F8F1; color: #2C232A; font-family: sans-serif; font-size: 30; text-align: center; } """) with doc.body: with tags.section(): with tags.div(cls='headline', style='font-size: 30;'): tags.h1('Register failed! You have registered before!') tags.input(type='button', value='return back', onclick="location.href='http://127.0.0.1:5000/'", style="width:120px; background-color:pink; font-size: 14;") fn = 'templates/index5.html' with open(file=fn, mode='w', encoding='utf-8') as f: f.write(doc.render()) print(f)
def document(title, actual_hash=None, index=False): doc = dominate.document(title=title) style = t.style() style.add_raw_string(STYLE) script = t.script() script.add_raw_string(SCRIPT) doc.head.add(style, script) if actual_hash is not None: doc.body["data-actual-hash"] = actual_hash if index: doc.body["data-index"] = True return doc
def make_page(app, uri): doc = dominate.document() inline = False doc.head += tags.script(util.include(root / 'domx' / 'domx.js')) doc.head += tags.style(util.include(root / 'domx' / 'domx.css')) page = app(doc) try: # router for p in uri.path.split('/'): if p == '': continue if p == '_domx': inline = True continue page = getattr(page, p) except AttributeError: raise ValueError(404) # render page tags.pre(repr(page)) with doc: page() # dxify def walk(node): for i in node.children: if not isinstance(i, tags.dom_tag): continue if not isinstance(i, x): walk(i) continue # it's a x() marker # todo onsubmit, etc for different types node['onclick'] = "dx.replace('{}', '{}');".format( i['target'], '/_domx' + i['get'], ) node.children.remove(i) walk(doc.body) if inline: return doc.body.children[0] else: return doc
t.meta(charset="utf-8") t.style("""\ span, a { font-family: monospace; color: black; text-decoration: none; margin: 0; } a { color: darkblue; } .entry a:target { display: block; background-color: navy; } #memorymap a:target { color: red; } span.leadin { margin-right: 1rem; } dl { border-left: 1px solid grey; padding-left: 0.4rem; } dt { font-weight: bold } div. """)
def getHTML(title, info=None, body=None, style=None, state=None, theme=None, icon=None): """Provide HTML object :param str title: short name of the notification, e.g.: server error :param str info: some short description if needed, e.g.: It looks like the server is not responding :param body: it can be string or dominate tag object, e.g.: from dominate import tags as dom return getHTML('server error', body=dom.pre(dom.code(result['Message'])) :param str style: additional css style if needed, e.g.: '.card{color:red;}' :param int state: response state code, if needed, e.g.: 404 :param str theme: message color theme, the same that in bootstrap 5, e.g.: 'warning' :param str icon: awesome icon name, e.g.: 'users' :return: str -- HTML document """ html = document("DIRAC - %s" % title) # select the color to the state code if state in [400, 401, 403, 404]: theme = theme or "warning" elif state in [500]: theme = theme or "danger" elif state in [200]: theme = theme or "success" # select the icon to the theme if theme in ["warning", "warn"]: theme = "warning" icon = icon or "exclamation-triangle" elif theme == "info": icon = icon or "info" elif theme == "success": icon = icon or "check" elif theme in ["error", "danger"]: theme = "danger" icon = icon or "times" else: theme = theme or "secondary" icon = icon or "flask" # If body is text wrap it with tags if body and isinstance(body, six.string_types): body = dom.pre( dom.code(traceback.format_exc() if body == "traceback" else body), cls="mt-5") try: diracLogo = collectMetadata(ignoreErrors=True).get("logoURL", "") except Exception: diracLogo = "" # Create head with html.head: # Meta tags dom.meta(charset="utf-8") dom.meta(name="viewport", content="width=device-width, initial-scale=1") # Favicon dom.link(rel="shortcut icon", href="/static/core/img/icons/system/favicon.ico", type="image/x-icon") # Provide awesome icons # https://fontawesome.com/v4.7/license/ dom.script( src= "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js" ) # Enable bootstrap 5 # https://getbootstrap.com/docs/5.0/getting-started/introduction/ # https://getbootstrap.com/docs/5.0/about/license/ dom.link( rel="stylesheet", integrity= "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC", href= "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css", crossorigin="anonymous", ) dom.script( src= "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js", integrity= "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM", crossorigin="anonymous", ) # Provide additional css style = ".card{transition:.3s;}.card:hover{transform:scale(1.03);}" + ( style or "") dom.style(style) # Create body with html: # Background image dom.i( cls="position-absolute bottom-0 start-0 translate-middle-x m-5 fa " "fa-%s text-%s" % (icon, theme), style="font-size:40vw;z-index:-1;", ) # A4 page with align center with dom.div( cls= "row vh-100 vw-100 justify-content-md-center align-items-center m-0" ): with dom.div(cls="container", style="max-width:600px;") as page: # Main panel with dom.div(cls="row align-items-center"): # Logo dom.div(dom.img(src=diracLogo, cls="card-img px-2"), cls="col-md-6 my-3") # Information card with dom.div(cls="col-md-6 my-3"): # Show response state number if state and state != 200: dom.div(dom.h1( state, cls="text-center badge bg-%s text-wrap" % theme), cls="row py-2") # Message title with dom.div(cls="row"): dom.div(dom.i(cls="fa fa-%s text-%s" % (icon, theme)), cls="col-auto") dom.div(title, cls="col-auto ps-0 pb-2 fw-bold") # Description if info: dom.small(dom.i(cls="fa fa-info text-info")) dom.small(info, cls="ps-1") # Add content if body: page.add(body) return html.render()
def test_main(): global widgets init_widgets() # Create a dominate document, see https://github.com/Knio/dominate widgets.dominate_document() with widgets.dom_doc.body: # add css elements here... style(raw("""body {background-color:powderblue;}""")) args, _redirect_page_metrics = widgets.process_req(request) if not args: return _redirect_page_metrics app.logger.info("{} : args {}".format(PAGE_URL, args)) # redirect to another page based on widget data... _redirect = redirect_lookup_table(args.get("sel_nexturl", None)) if _redirect: widgets.get("sel_nexturl").value = None # TODO: make a widget set value method? # TODO: or make a init function for all the widgets, and re-init them? return redirect(_redirect) # reset page to initial values, if there are no parms # the widgets have state, so update if required if not args: widgets.get("sel_nexturl").value = '' # reset next url select widgets.get("s_age").value = 25 widgets.get("s_amp").value = 1 text_age = "Please tell me how old you are..." else: text_age = "Wow, you are {} years old!".format( widgets.get("s_age").value) p_text_age = Paragraph(text=text_age, width=None, height=None) # set various widget attributes widgets.add_css( "dp_birthday", { 'input': { 'background-color': '#98FB98' }, 'label': { 'background-color': '#98FB98', 'font-size': '16px' } }) widgets.add_css( "s_age", {'label': { 'background-color': '#98FB98', 'font-size': '16px' }}) # make a graph, example at https://bokeh.pydata.org/en/latest/docs/user_guide/plotting.html amplitude = float(args.get("s_amp", 1.0)) x = arange(-2 * pi, 2 * pi, 0.1) y = amplitude * sin(x) y2 = linspace(0, 100, len(y)) p = figure(x_range=(-6.5, 6.5), y_range=(-2.0, 2.0), width=600, height=200) p.circle(x, y, color="red") p.extra_y_ranges = {"foo": Range1d(start=0, end=100)} p.circle(x, y2, color="blue", y_range_name="foo") p.add_layout(LinearAxis(y_range_name="foo"), 'left') doc_layout = layout(sizing_mode='scale_width') doc_layout.children.append( row(Div(text="""<h1>pywrapBokeh</h1>"""), Paragraph(text="""Play with all these widgets."""))) doc_layout.children.append(column(widgets.get("s_age"), p_text_age)) doc_layout.children.append( row(widgets.get("dp_birthday"), widgets.get("msel_fruit"), widgets.get("ds_birthday"))) doc_layout.children.append(column(widgets.get("s_amp"), p)) doc_layout.children.append( row(widgets.get("b_test"), widgets.get("toggle_1"), widgets.get("dropdn_1"))) doc_layout.children.append( row(widgets.get("sel_nexturl"), widgets.get("cbbg_music"), widgets.get("cbg_music"))) doc_layout.children.append( row(widgets.get("rbg_music"), widgets.get("rg_music"), widgets.get("rslider_amp"))) return widgets.render(doc_layout)
def process(): # doc = dominate.document(DOCNAME) h = html(name=DOCNAME) with h: # _head = head() _head = head() with _head: s = style() s.add("\nh3, h4 {text-align:center;}") s.add("\nth {background-color:yellow;}") s.add("\ntr, td, th {text-align:center;}") s.add("\ntd.left {text-align:left;}") s.add("\n") b = body() b.add(h3(DOCNAME)) b.add(h4(asctime())) b.add(hr()) t = table(border="1", cellpadding="3", cellspacing="3") b.add(t) r = tr() t.add(r) r.add(th("Code")) r.add(th("Waypoint")) r.add(th("Image")) r.add(th("Note")) f = open(FILENAME, "r") for index, line in enumerate(f.readlines()): if index == 0: continue code, waypoint_name, url = line.split('\t') r = tr() t.add(r) r.add(td(code)) r.add(td(a(waypoint_name, href=url))) if code in IMAGES: link = IMAGES[code] if isinstance(link, type([])): images = table() for link in link: r2 = tr() r2.add(td(a(link, href=link))) images.add(r2) else: images = a(link, href=link) else: images = "" r.add(td(images)) if code in NOTES: note = NOTES[code] else: note = "TBD" r.add(td(note, cls="left")) outfile = open(OUTFILE, "wb") print >> outfile, h outfile.close() print "Output is in %s" % OUTFILE
def create_html_summary(n_genomes, n_clusters, n_big_clusters): doc = dominate.document(title='Genomes mapping summary') with doc.head: tags.style(""" body { background-color: #e1f5fe; font-family: sans-serif; font-size: 18px; } .container { width: 80%; margin: 0 auto; background-color: white; padding: 15px 30px; } span { font-weight: 600; } cite { border-left: solid black 3px; font-size: 12px; } .big_img { width: 100%; } """) with doc.body: with tags.div(cls='container'): tags.h1('Creating the total list of genes for {}'.format(ORGANISM)) tags.p( raw('Total list has <span>{} genomes</span>'.format(n_genomes) + ' and <span>{} clusters</span>.'.format(n_clusters))) tags.img(src='../plots/clusters_sizes.png', alt='clusters sizes') tags.p( raw('There are <span>{} clusters</span>'.format(n_big_clusters) + ' of <span>size > 5</span>.')) tags.img(src='../plots/n_clusters_by_threshold.png', alt='N clusters by threshold') tags.p( raw('Check the <i>results/</i> folder for files, which you can use for the following analysis:' )) with tags.ul(): tags.li( raw('<i><b>proteome.faa</b></i> — fasta file with all the protein coding genes from' + 'all the genomes. Gene names are concatenated with their genome ID. There is also' + 'some extra information in brackets. Example of the header:<br> ' + '<cite>>WP_000002298.1[genome:GCF_002741575.1_ASM274157v1_] MULTISPECIES: alpha-D-ribose' + ' 1-methylphosphonate 5-phosphate C-P-lyase [Enterobacteriaceae]' + ' [start:4548948] [end:4549793] [genome:GCF_002741575.1_ASM274157v1_]</cite>' )) tags.li( raw('<i><b>genes_info.tsv</b></i> — tab separated table with 2 columns: <b>gene</b> and' + ' <b>info</b>. Contains information for each gene in the proteome. Information' + ' is extracted from fasta header.')) tags.li( raw('<i><b>cluster_info.json</b></i> — contains counted information about the genes in' + ' each cluster. You can use it to take a look at what genes the cluster consists of' + ', and to set a name for the cluster. Here is the example of visualisation' + ' of this information for 1 cluster:')) tags.img(src='../images/cluster_names.png') tags.li( raw('<i><b>total_list.csv</b></i> — table with clusters in rows and genomes in columns. Number' + ' on the intersection means, how many genes from this cluster the genome contains.' )) with tags.li( raw('<i><b>clusters.csv</b></i> — data frame with following columns:' )): with tags.ol(): tags.li(raw('<i>cluster</i> — cluster of a sequence')) tags.li( raw('<i>representative</i> — boolean variable, which indicates, if the given' + ' sequence is representative')) tags.li( raw('<i>gene</i> — name of the sequence from fasta header with appended genome ID' )) tags.li( raw('<i>length</i> — length of the gene\'s sequence' )) tags.li( raw('<i>identity</i> — identity of a sequence to representative sequence' + ' of its cluster')) tags.li( raw('<i>name</i> — name of the sequence from fasta header without appended genome ID' )) tags.li( raw('<i>genome</i> — genome id from fasta header')) tags.li( raw('<i>info</i> — information about gene from its fasta header' )) tags.p( raw('Visualisation of the total list of genes. Each row represents a genome. Each column' + ' represents a cluster (only clusters with <b>size > 5</b> included).' + ' If the genome has the gene, there is a white dot on the intersection.' + ' Otherwise — a black dot.')) tags.img(src='../plots/genes_presence.png', alt='genes presence', cls='big_img') tags.p( raw('Clustering of genes. These illustrations are for you to take a look at the data.' + ' For higher quality illustrations, and the following analysis it is recommended to perform ' + 'these operations in <a href="https://software.broadinstitute.org/morpheus/">Morpheus tool</a>' + ' (also avialable as <a href="https://github.com/cmap/morpheus.R">R package</a>).' )) tags.img(src='../plots/genes_presence_clustering.png', alt='genes presence clustering') tags.p( raw('If you had any problems during the work of the program, or have any notes, please contact' + ' <a href="mailto:[email protected]">[email protected]</a>' )) with open('./results/summary.html', 'w') as f: f.write(str(doc))