def main(): print "GitHub User:"******"GitHub Project:", PROJECT print "Target directory:", DOCDIR pages = fetch_pagenames(USER, PROJECT) if not pages: print "ERROR: Invalid user or project name." return 1 print "Pages:", ', '.join(pages) tpl = SimpleTemplate(TEMPLATE) for page in pages: fn = '%s/%s.html' % (DOCDIR, page.lower()) print "Fetching", page.title(), "-->", fn raw = '\n'.join(fetch_page(USER, PROJECT, page)) raw = re.sub(r'http://wiki.github.com/%s/%s/(\w+)' % (USER, PROJECT), './\\1.html', raw) if raw.strip(): try: fp = open(fn, 'w') fp.write(tpl.render(title=page.title(), html=raw, pages=pages)) fp.close() except IOError: print "ERROR: Could not save file (IOError)" else: print "ERROR: Empty page or download error." return 0
def tpl(file_name, **kwargs): with open(os.path.join(PATH, file_name + ".tpl")) as tpl_file: template = SimpleTemplate(tpl_file.read()) return template.render( **kwargs ) return ""
def _parse_html(self): source = self.source if detect_blogofile(source): heading, info, other_html = convert_blogofile(source) parts = parse_rst(heading) body_html = parts['docinfo'] + other_html self.add_title = True self.title = html_parser.unescape(parts['title']) self.add_disqus = True self.date = info['date'] self.tags = info['tags'] else: self.title = self._find_title_in_html(source) template = SimpleTemplate(source) body_html = template.render(blog=self.blog) self.add_disqus = False self.date = None self.tags = () self.add_title = False body_html = pygmentize_pre_blocks(body_html) body_html = body_html.replace('\n</pre>', '</pre>') self.add_mathjax = False self.body_html = body_html self.next_link = None self.previous_link = None
def all_albums(): sorted_albums = sorted( albums.keys(), key=lambda x: albums[x]['published'], reverse=True) template = SimpleTemplate(source=_get_template('list.html')) return template.render(albums=sorted_albums)
def test_dedentbug(self): ''' One-Line dednet blocks should not change indention ''' t = SimpleTemplate('%if x: a="if"\n%else: a="else"\n{{a}}') self.assertEqual(u"if", ''.join(t.render(x=True))) self.assertEqual(u"else", ''.join(t.render(x=False))) t = SimpleTemplate('%if x: a="if"\n%else: a="else"\n%end') self.assertRaises(NameError, t.render)
def json_render(template, *args, **kwargs): """ Simple JSON rendering function that renders a JSON-style template and returns a (JSON) dict. template: JSON-style rendering template. *args: Postitional arguments are dicts containing sets of rendering variables and values. **kwargs: Keyword arguments are single rendering variables and values. """ # Create a single dict containing all the provided rendering data render_data = {} for arg in args: render_data.update(arg) render_data.update(kwargs) # Encode strings and unicodes to take care of multi-line values. Otherwise # the rendered result contains illegal JSON data. for key, val in render_data.iteritems(): if isinstance(val, str): render_data[key] = val.encode('string_escape') if isinstance(val, unicode): render_data[key] = val.encode('unicode_escape') # Do the actual template rendering and convert to a dict tpl = SimpleTemplate(template, noescape=True) try: return json.loads(tpl.render(render_data)) except Exception: # pylint: disable=W0703 LOG.error('Bad JSON syntax:\n%s', tpl.render(render_data)) raise
def index(): name = request.query.get('name') a = int(request.query.get('a'), 10) b = int(request.query.get('b'), 10) tpl = SimpleTemplate('Hello {{name}}!<br/>\nsum={{sum}}\n') sum = a + b return tpl.render(name=name, sum=sum)
def render_tree(tree, ind=1): """ Render the tree into HTML using :attr:`TREE_TEMPLATE`. Private trees are ignored. Args: tree (obj): :class:`.Tree` instance. ind (int, default 1): Indentation. This function is called recursively. Returns: str: Rendered string. """ if not tree.is_public: return "" rendered_tree = SimpleTemplate(TREE_TEMPLATE).render( tree=tree, render_tree=render_tree, ind=ind, path_composer=path_composer, pub_cache=pub_cache, ) # keep nice indentation ind_txt = ind * " " return ind_txt + ("\n" + ind_txt).join(rendered_tree.splitlines())
def render(self): tpl = SimpleTemplate(name=InstantWebDataPublisher.TEMPLATES_DIR + InstantWebDataPublisher.BASE_TEMPLATE) wi_last_update = datetime.datetime.utcnow().replace(microsecond = 0) return tpl.render(ds_name=self.doc_url.split('/')[-1].split('.')[0], theader=sorted(self.table_header, key=lambda cell: cell[0]), trows=sorted(self.table_rows, key=lambda cell: cell[1]), aliases=self.matches, wi_last_update=str(wi_last_update) + ' (UTC)')
def test_detect_pep263(self): ''' PEP263 strings in code-lines change the template encoding on the fly ''' t = SimpleTemplate(touni('%#coding: iso8859_15\nöäü?@€').encode('utf8')) self.assertNotEqual(touni('öäü?@€'), t.render()) self.assertEqual(t.encoding, 'iso8859_15') t = SimpleTemplate(touni('%#coding: iso8859_15\nöäü?@€').encode('iso8859_15')) self.assertEqual(touni('öäü?@€'), t.render()) self.assertEqual(t.encoding, 'iso8859_15') self.assertEqual(2, len(t.code.splitlines()))
def assertRenders(self, source, result, syntax=None, *args, **vars): source = self.fix_ident(source) result = self.fix_ident(result) tpl = SimpleTemplate(source, syntax=syntax) try: tpl.co self.assertEqual(touni(result), tpl.render(*args, **vars)) except SyntaxError: self.fail('Syntax error in template:\n%s\n\nTemplate code:\n##########\n%s\n##########' % (traceback.format_exc(), tpl.code))
def write_end_of_section(scenario): all_ok = all(map(lambda x : x.passed, scenario.steps)) filter_passed = sum(map(lambda x : 1 if x.passed else 0, scenario.steps)) percentage_ok = (float(filter_passed) / len(scenario.steps) * 100.0) if scenario.steps else 100.0 time_total = timedelta_total_seconds(datetime.datetime.now() - world.time_before) if all_ok else None index_page = 'index%d.html' % world.idscenario tags = scenario.tags # we have to add the steps that haven't been included write_printscreen(world, world.full_printscreen) # we have to add en explanation "why" the scenario has failed if not all_ok: # we cannot rely on "passed" because it seems that the exception is sometimes attached to # another step failures = filter(lambda x : x.why, (scenario.background.steps if scenario.background else []) + scenario.steps) # Don't ask me why, Lettuce sometimes doesn't give any step when the failure heppens when executing the last step... # We don't want to crash a second time because the "real" error message would be hidden exception_failure = failures[0].why.exception if failures else None msg_error = unicode(exception_failure).encode('ascii', 'ignore') + ' (' + str(type(exception_failure)) + ')' write_errorscreen(world, msg_error) shoud_work = 'fails' not in scenario.tags if shoud_work != all_ok: world.failure_found = True # is this success/failure normal according to us? # (if tag @fails => a failure is normal, otherwise it's not normal) # We then have to update the "ok/ko" flag in the meta file # and color in red or not the line world.scenarios.append((all_ok, scenario.name, percentage_ok, time_total, index_page, tags)) path_html = os.path.join(OUTPUT_DIR, index_page) path_tpl = get_absolute_path(os.path.join(TEMPLATES_DIR, "scenario.tpl")) with open(path_tpl, 'r') as f: content = ''.join(f.xreadlines()) mytemplate = SimpleTemplate(content) _, filename = os.path.split(scenario.described_at.file) content = mytemplate.render(printscreens=world.printscreen_to_display, scenario=scenario, filename=filename) output_index_file = open(path_html, 'w') output_index_file.write(content.encode('ascii', 'ignore')) output_index_file.close() world.printscreen_to_display = [] world.idscenario += 1
def list_album(album): album_dict = albums[album] photos = [] for i in album_dict['photos']: photo = Photo() photo_path = '/picasa/%s/%s.jpg' % (album, i['name']) photo.image_url = '/photo/%s' % photo_path photo.thumb_url = '/photo/thumbnail/' + photo_path photo.title = '' photo.caption = i.get("summary", "") photos.append(photo) template = SimpleTemplate(source=_get_template('xml_template.xml')) return template.render(album_title=album, photos=photos)
def create_real_repport(total): path_tpl = get_absolute_path(os.path.join(TEMPLATES_DIR, "index.tpl")) import collections count_by_tag = collections.defaultdict(lambda : 0) for scenario in world.scenarios: for tag in scenario[5]: count_by_tag[tag] += 1 values = count_by_tag.items() values.sort(key=lambda x : x[1]) values.reverse() values = filter(lambda x : x[1] > 1, values) alltags = map(lambda x : x[0], values) total_time = 0 #FIXME: scenarios don't last the same amount of time total_percentage = 0.0 total_passed = 0 for scenario in world.scenarios: time = scenario[3] or 0 percentage = scenario[2] valid = scenario[0] total_time += time total_percentage += percentage total_passed += 1 if valid else 0 total_scenarios = len(world.scenarios) total_percentage = total_percentage / len(world.scenarios) if len(world.scenarios) else 0.0 with open(path_tpl, 'r') as f: content = ''.join(f.xreadlines()) mytemplate = SimpleTemplate(content) content = mytemplate.render(scenarios=world.scenarios, alltags=alltags, total_scenarios=total_scenarios, total_time=total_time, total_percentage=total_percentage, total_passed=total_passed, datetime=datetime) path_html = os.path.join(OUTPUT_DIR, "index.html") output_index_file = open(path_html, 'w') output_index_file.write(content) output_index_file.close()
def test_data(self): """ Templates: Data representation """ t = SimpleTemplate("<{{var}}>") self.assertEqual("<True>", "".join(t.render(var=True))) self.assertEqual("<False>", "".join(t.render(var=False))) self.assertEqual("<None>", "".join(t.render(var=None))) self.assertEqual("<0>", "".join(t.render(var=0))) self.assertEqual("<5>", "".join(t.render(var=5))) self.assertEqual("<b>", "".join(t.render(var="b"))) self.assertEqual("<1.0>", "".join(t.render(var=1.0))) self.assertEqual("<[1, 2]>", "".join(t.render(var=[1, 2])))
def test_inline(self): """ Templates: Inline statements """ t = SimpleTemplate('start {{var}} end') self.assertEqual('start True end', t.render(var=True)) self.assertEqual('start False end', t.render(var=False)) self.assertEqual('start None end', t.render(var=None)) self.assertEqual('start 0 end', t.render(var=0)) self.assertEqual('start 5 end', t.render(var=5)) self.assertEqual('start b end', t.render(var='b')) self.assertEqual('start 1.0 end', t.render(var=1.0)) self.assertEqual('start [1, 2] end', t.render(var=[1,2]))
def test_data(self): """ Templates: Data representation """ t = SimpleTemplate('<{{var}}>') self.assertEqual(u'<True>', t.render(var=True)) self.assertEqual(u'<False>', t.render(var=False)) self.assertEqual(u'<None>', t.render(var=None)) self.assertEqual(u'<0>', t.render(var=0)) self.assertEqual(u'<5>', t.render(var=5)) self.assertEqual(u'<b>', t.render(var='b')) self.assertEqual(u'<1.0>', t.render(var=1.0)) self.assertEqual(u'<[1, 2]>', t.render(var=[1,2]))
def render(paths, path): #previous = call(previous_post, paths, path) #previous_title = 'NONE' if previous is None else call(title_of, previous) body_html = body_of(path) template = SimpleTemplate(name='layout.html', lookup=['templates']) html = template.render( add_title='<h1' not in body_html, title=title_of(path), previous_link=None, next_link=None, body_html=body_html, needs_disqus=needs_disqus(path), needs_mathjax=r'\(' in body_html or r'\[' in body_html, ) # text = '<h1>{}</h1>\n<p>Date: {}</p>\n<p>Previous post: {}</p>\n{}'.format( # call(title_of, path), call(date_of, path), # previous_title, call(body_of, path)) # print('-' * 72) # print(text) return html
def test_noescape_setting(self): t = SimpleTemplate('<{{var}}>', noescape=True) self.assertEqual(u'<b>', t.render(var='b')) self.assertEqual(u'<<&>>', t.render(var='<&>')) t = SimpleTemplate('<{{!var}}>', noescape=True) self.assertEqual(u'<b>', t.render(var='b')) self.assertEqual(u'<<&>>', t.render(var='<&>'))
def test_blocks(self): """ Templates: Code blocks and loops """ t = SimpleTemplate("start\n%for i in l:\n{{i}} \n%end\nend") self.assertEqual(u'start\n1 \n2 \n3 \nend', t.render(l=[1,2,3])) self.assertEqual(u'start\nend', t.render(l=[])) t = SimpleTemplate("start\n%if i:\n{{i}} \n%end\nend") self.assertEqual(u'start\nTrue \nend', t.render(i=True)) self.assertEqual(u'start\nend', t.render(i=False))
def do_login(): if (request.query.page == "register"): username = request.forms.get('name') password = request.forms.get('pass') email = request.forms.get("email") tpl = SimpleTemplate(name = "./index.html") return tpl.render(reg = (username, password, email)) elif(request.query.page == "login"): if (User.is_login() == False): if(uCont.login(request.forms.get('name'), request.forms.get('pass'))): return template("./reg_ok") else: redirect("./index?page=login") else: return template("./reg_ok") elif (request.query.page == "article"): print("here") rate = request.forms.get("rating") id = request.query.id uCont.add_rate(id, rate) tpl = SimpleTemplate(name = "./index.html") return tpl.render()
def test_detect_pep263(self): ''' PEP263 strings in code-lines change the template encoding on the fly ''' t = SimpleTemplate( touni('%#coding: iso8859_15\nöäü?@€').encode('utf8')) self.assertNotEqual(touni('öäü?@€'), t.render()) self.assertEqual(t.encoding, 'iso8859_15') t = SimpleTemplate( touni('%#coding: iso8859_15\nöäü?@€').encode('iso8859_15')) self.assertEqual(touni('öäü?@€'), t.render()) self.assertEqual(t.encoding, 'iso8859_15') self.assertEqual(2, len(t.code.splitlines()))
class Template: def __init__(self,name,template=None): # If is the first argument which is optional if template is None: template = name name = None self.id = name self.template = SimpleTemplate(template) def internal_check(self): printName = self.id if self.id is None: printName = "Not Set" if self.template is None: raise ValueError('Template %s has no template set.' % printName) def use(self): return self.template.render(use=use,rpggen=Rpggen)
def test(): aCookie = request.get_cookie('wunderToken') aResponse = SimpleTemplate('Hello, it is {{aCookie}}}') try: # return aResponse return static_file('index2.html', root='/var/www/wunderCan') except Exception as e: log = [ "Date: " + arrow.utcnow().to('US/Pacific'), "Request: /hellow", "Exception: " + e ] if os.path.isfile('/var/www/wunderCan/exceptions.txt'): open('/var/www/wunderCan/exceptions.txt', 'a').writelines(log).close() else: open('/var/www/wunderCan/exceptions.txt', 'w').writelines(log).close() return static_file('index2.html', root='/var/www/wunderCan')
def to_html(self): #Each review always has a restaurant name template = "" template = "<b><a href='/restaurant/{{item['restaurant_name']}}'>{{item['restaurant_name']}}</a></b>" #Add address if there is one if 'address' in self.data: template += " at <b>{{item['address']}}</b>" ###ITEM TEXT FORMATTING### item_exists = 'restaurant_item' in self.data item_has_comments = 'item_comments' in self.data item_has_price = 'item_price' in self.data #text regarding the name of what you ate if item_exists: template += "<br> I had the {{item['restaurant_item']}}" if item_has_price: template += " for ${{item['item_price']}}" if item_has_comments: template += " and {{item['item_comments']}}" ###ITEM OVERALL FORMATTING### comment_exists = 'restaurant_rating_reason' in self.data rating_exists = 'restaurant_rating' in self.data if comment_exists or rating_exists: template += "<br> Overall: " if comment_exists: template += "{{item['restaurant_rating_reason']}}" if rating_exists: template += ", " if rating_exists: template += "{{item['restaurant_rating']}} of 5" if 'is_recommended' in self.data: template += "<br> I recommend this place!" #Each review always has a reviewer and time template += '''<br> <i>review by <a href="/users/{{item['user']}}">{{item['user']}}</a> on {{item['time']}}</i> ''' return SimpleTemplate(template).render(item=self.data)
def test_ignore_late_pep263(self): ''' PEP263 strings must appear within the first two lines ''' t = SimpleTemplate(touni('\n\n%#coding: iso8859_15\nöäü?@€').encode('utf8')) self.assertEqual(touni('\n\nöäü?@€'), t.render()) self.assertEqual(t.encoding, 'utf8')
def test_global_config(self): SimpleTemplate.global_config('meh', 1) t = SimpleTemplate('anything') self.assertEqual(touni('anything'), t.render())
def test_unicode_code(self): """ Templates: utf8 code in file""" with chdir(__file__): t = SimpleTemplate(name='./views/stpl_unicode.tpl', lookup=['.']) self.assertRenders(t, 'start ñç äöü end\n', var=touni('äöü'))
def test_ignore_pep263_in_textline(self): ''' PEP263 strings in text-lines have no effect ''' t = SimpleTemplate(touni('#coding: iso8859_15\nöäü?@€').encode('utf8')) self.assertEqual(touni('#coding: iso8859_15\nöäü?@€'), t.render()) self.assertEqual(t.encoding, 'utf8')
def test_commentonly(self): """ Templates: Commentd should behave like code-lines (e.g. flush text-lines) """ t = SimpleTemplate('...\n%#test\n...') self.failIfEqual('#test', t.code.splitlines()[0])
def assertRenders(self, tpl, to, *args, **vars): if isinstance(tpl, str): tpl = SimpleTemplate( tpl, lookup=[os.path.join(os.path.dirname(__file__), 'views')]) self.assertEqual(touni(to), tpl.render(*args, **vars))
def assertRenders(self, tpl, to, *args, **vars): if isinstance(tpl, str): tpl = SimpleTemplate(tpl) self.assertEqual(touni(to), tpl.render(*args, **vars))
def test_old_include_with_args(self): t1 = SimpleTemplate('%include foo x=y') t1.cache['foo'] = SimpleTemplate('foo{{x}}') self.assertEqual(t1.render(y='bar'), 'foobar')
from bottle import template, request, redirect, SimpleTemplate from controller import error, get_session, set_cookie from database import * import database, bottle import i18n as i18n_mod, imports __all__ = [ 'mview', 'lang', 'allow_auth', 'require_auth', 'require_cond', 'require_role', 'require_user' ] SimpleTemplate.global_config('from_pkg', 'hvsi') SimpleTemplate.defaults = imports.__dict__ SimpleTemplate.defaults['bottle'] = bottle SimpleTemplate.defaults['db'] = database SimpleTemplate.defaults['lang_count'] = len(i18n_mod.i18n.keys()) # decorator that automatically gives the "page" variable to templates def mview(view_name): def tview(func): def view_func(*args, **kwargs): val = lang(allow_auth(func))(*args, **kwargs) i18n_val = i18n_mod.i18n if val is not None and isinstance(val, dict) and 'page' not in val: val['page'] = view_name i18n_val = val.get('i18n', i18n_mod.i18n) try: del val['i18n'] except: pass if isinstance(val, dict): val['request'] = bottle.request
class StaticFileServer: MODULE_ROUTINGS = { 'general': 'modules/StaticFiles/static', 'interface': 'modules/LabelUI/static', 'reception': 'modules/Reception/static', 'dataAdmin': 'modules/DataAdministration/static', 'projectAdmin': 'modules/ProjectAdministration/static', 'statistics': 'modules/ProjectStatistics/static', 'aiController': 'modules/AIController/static' } def __init__(self, config, app, verbose_start=False): self.config = config self.app = app self.login_check = None self._initBottle() def loginCheck(self, project=None, admin=False, superuser=False, canCreateProjects=False, extend_session=False): return self.login_check(project, admin, superuser, canCreateProjects, extend_session) def addLoginCheckFun(self, loginCheckFun): self.login_check = loginCheckFun def _initBottle(self): @self.app.route('/version') def aide_version(): return AIDE_VERSION @self.app.route('/favicon.ico') def favicon(): return static_file('favicon.ico', root='modules/StaticFiles/static/img') with open(os.path.abspath( os.path.join( 'modules/StaticFiles/static/templates/about.html')), 'r', encoding='utf-8') as f: self.aboutPage = SimpleTemplate(f.read()) @self.app.route('/about') @self.app.route('/<project>/about') def about(project=None): return self.aboutPage.render(version=AIDE_VERSION) @self.app.get('/getBackdrops') def get_backdrops(): try: return { 'info': json.load( open( 'modules/StaticFiles/static/img/backdrops/backdrops.json', 'r')) } except: abort(500) @self.app.route('/static/<module>/<filename:re:.*>') def send_static(module, filename): return static_file(filename, self.MODULE_ROUTINGS[module]) #TODO: can be removed @self.app.route('/<project>/static/<module>/<filename:re:.*>') def send_static_proj(project, module, filename): return send_static(module, filename)
baseTemplate = SimpleTemplate(""" %from ptracker_lib.helpers import acdebug %acdebug("Rendering %s", curr_url) <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> % if src != "main": <meta name="robots" content="noindex, nofollow"> <meta name="googlebot" content="noindex, nofollow"> % end <!-- Include Twitter Bootstrap and jQuery: --> <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/bootstrap/css/bootstrap-theme.min.css"> <link rel="stylesheet" href="/bootstrap/css/bootstrap-multiselect.css" type="text/css"/> <link rel="stylesheet" href="/bootstrap/css/bootstrap-datepicker.css" type="text/css"/> <link rel="stylesheet" href="/bootstrap/css/sticky-footer.css" type="text/css"/> <link rel="stylesheet" href="/bootstrap/css/fileinput.min.css" media="all" type="text/css" /> <script src="/jquery/jquery.min.js"></script> <script src="/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="/bootstrap/js/bootstrap-multiselect.js"></script> <script type="text/javascript" src="/bootstrap/js/bootstrap-datepicker.js"></script> <script src="/bootstrap/js/fileinput.min.js" type="text/javascript"></script> % if pygal: <script type="text/javascript" src="/pygal/svg.jquery.js"></script> <script type="text/javascript" src="/pygal/pygal-tooltips.min.js"></script> % end % title_texts = dict(lapstat="Laps", sesstat="Sessions", players="Drivers", cs="Championships", stats="Statistics", livemap="Live Map", banlist="Ban List", groups="Groups", admin="General Admin", log="Log") % title = title_texts.get(src, "stracker") <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css"> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/plug-ins/1.10.19/sorting/natural.js"></script> <title>{{title}}</title> <link rel="shortcut icon" type="image/x-icon" href="/img/brand_icon_small_wob.png"> <style> table#lapstable tr.even:hover td, table#lapstable tr.odd:hover td { background-color: #d7f6e7 !important; } .aids { width:16px; height:16px; background:none left top no-repeat; display:inline-block; background-size:cover; margin-right:-3px; margin-left:-3px; margin-top:-3px; margin-bottom:-3px; } .aids.autoclutch.off { background-image:url(/img/icn_stability_off.png) } .aids.autoclutch.on { background-image:url(/img/icn_stability_on.png) } .aids.autoclutch.unknown { background-image:url(/img/icn_stability_unknown.png) } .aids.abs.off { background-image:url(/img/icn_abs_off.png) } .aids.abs.factory { background-image:url(/img/icn_abs_factory.png) } .aids.abs.on { background-image:url(/img/icn_abs_on.png) } .aids.abs.unknown { background-image:url(/img/icn_abs_unknown.png) } .aids.autobrake.off { background-image:url(/img/icn_automaticbraking_off.png) } .aids.autobrake.on { background-image:url(/img/icn_automaticbraking_on.png) } .aids.autobrake.unknown { background-image:url(/img/icn_automaticbraking_unknown.png) } .aids.autogearbox.off { background-image:url(/img/icn_gearbox_off.png) } .aids.autogearbox.on { background-image:url(/img/icn_gearbox_on.png) } .aids.autogearbox.unknown { background-image:url(/img/icn_gearbox_unknown.png) } .aids.blip.off { background-image:url(/img/icn_heeltoe_off.png) } .aids.blip.on { background-image:url(/img/icn_heeltoe_on.png) } .aids.blip.unknown { background-image:url(/img/icn_heeltoe_unknown.png) } .aids.idealline.off { background-image:url(/img/icn_idealline_off.png) } .aids.idealline.on { background-image:url(/img/icn_idealline_on.png) } .aids.idealline.unknown { background-image:url(/img/icn_idealline_unknown.png) } .aids.tc.off { background-image:url(/img/icn_tractioncontrol_off.png) } .aids.tc.factory { background-image:url(/img/icn_tractioncontrol_factory.png) } .aids.tc.on { background-image:url(/img/icn_tractioncontrol_on.png) } .aids.tc.unknown { background-image:url(/img/icn_tractioncontrol_unknown.png) } .aids.damage.off { background-image:url(/img/icn_stability_off.png) } .aids.damage.on { background-image:url(/img/icn_stability_on.png) } .aids.damage.unknown { background-image:url(/img/icn_stability_unknown.png) } .bestLap { color:#ff00ff } .bestSector { color:#00c000 } .multiselect { text-align: left; } .multiselect b.caret { position: absolute; top: 14px; right: 8px; } .multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:0px} .table-condensed>thead>tr>th, .table-condensed>tbody>tr>th, .table-condensed>tfoot>tr>th, .table-condensed>thead>tr>td, .table-condensed>tbody>tr>td, .table-condensed>tfoot>tr>td { padding: 2px; } .clickableRow td { cursor: pointer; cursor: hand; } .clickableRow td.noclick { cursor: auto; } .table tbody>tr>td.vert-align { vertical-align: middle; } .table thead>tr>th.vert-align { vertical-align: middle; } .navbar-fixed-bottom { z-index: 900; } % if features['pts']: html body { background: rgba(255,255,255,0.6); } .table-striped > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th { background-color: rgba(249,249,249,0.6); } .navbar-default { background: rgba(255,255,255,0.6); background: -moz-linear-gradient(top, rgba(255,255,255,0.6) 0%, rgba(248,248,248,0.6) 100%); background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,255,255,0.6)), color-stop(100%, rgba(248,248,248,0.6))); background: -webkit-linear-gradient(top, rgba(255,255,255,0.6) 0%, rgba(248,248,248,0.6) 100%); background: -o-linear-gradient(top, rgba(255,255,255,0.6) 0%, rgba(248,248,248,0.6) 100%); background: -ms-linear-gradient(top, rgba(255,255,255,0.6) 0%, rgba(248,248,248,0.6) 100%); background: linear-gradient(to bottom, rgba(255,255,255,0.6) 0%, rgba(248,248,248,0.6) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#f8f8f8', GradientType=0 ); } .navbar-default .navbar-nav > .active > a { background: rgba(235,235,235,0.6); background: -moz-linear-gradient(top, rgba(235,235,235,0.6) 0%, rgba(248,248,248,0.6) 100%); background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(235,235,235,0.6)), color-stop(100%, rgba(248,248,248,0.6))); background: -webkit-linear-gradient(top, rgba(235,235,235,0.6) 0%, rgba(248,248,248,0.6) 100%); background: -o-linear-gradient(top, rgba(235,235,235,0.6) 0%, rgba(248,248,248,0.6) 100%); background: -ms-linear-gradient(top, rgba(235,235,235,0.6) 0%, rgba(248,248,248,0.6) 100%); background: linear-gradient(to bottom, rgba(235,235,235,0.6) 0%, rgba(248,248,248,0.6) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ebebeb', endColorstr='#f8f8f8', GradientType=0 ); } % end </style> <link rel="stylesheet" href="/bootstrap/css/custom.css" media="all" type="text/css" /> </head> <body> % from stracker_lib import config % navbar_style = "inverse" if config.config.HTTP_CONFIG.inverse_navbar else "default" <nav class="navbar navbar-{{!navbar_style}}" role="navigation"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="{{!rootpage}}"><img class="img-responsive" alt="stracker" src="/img/brand_icon_large_wob.png" /></a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li {{!'class="active"' if src == "lapstat" else ""}}><a href="{{!rootpage}}lapstat">Lap Times</a></li> <li {{!'class="active"' if src == "sesstat" else ""}}><a href="{{!rootpage}}sessionstat">Sessions</a></li> <li {{!'class="active"' if src == "players" else ""}}><a href="{{!rootpage}}players">Drivers</a></li> % if not features['pts'] or 'server' in curr_url: <li {{!'class="active"' if src == "cs" else ""}}><a href="{{!rootpage}}championship">Championships</a></li> % end <li {{!'class="active"' if src == "stats" else ""}}><a href="{{!rootpage}}statistics">Statistics</a></li> % if not features['pts']: <li {{!'class="active"' if src == "livemap" else ""}}><a href="{{!rootpage}}livemap">Live Map</a></li> % end % admin = features['admin'] % banlist = features['banlist'] % if not admin is None and admin: % if banlist: <li {{!'class="active"' if src == "banlist" else ""}}><a href="{{!rootpage}}banlist">Banlist</a></li> % end <li {{!'class="active"' if src == "groups" else ""}}><a href="{{!rootpage}}groups">Groups</a></li> <li {{!'class="active"' if src == "admin" else ""}}><a href="{{!rootpage}}general_admin">General Admin</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Logs <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="{{!rootpage}}log">Stracker log</a></li> <li><a href="{{!rootpage}}chatlog">Chat log</a></li> </ul> </li> % end </ul> <ul class="nav navbar-nav navbar-right"> % if not admin is None and admin: % user_url = curr_url % if user_url.startswith("/admin"): % user_url = user_url[len("/admin"):] % end <li><a href="{{!user_url}}">User Area</a></li> % elif not admin is None and not admin: <li><a href="{{!"/admin%s" % curr_url}}">Admin Area</a></li> % end </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> {{!base}} <nav class="navbar navbar-{{!navbar_style}} navbar-fixed-bottom"> <div class="container-fluid"> <div class="col-sm-3"> </div> <div style="text-align:center" class="col-sm-6"> % # comment lines below in case you want page paginator to be visible % del pagination % pagination = (None) % if not pagination is None: % page = pagination[0] % totalPages = pagination[1] % import re % def link_to_page(p): % nopage_url = re.sub(r"([?&])page=[^?&]*([?&])?", r"\g<1>", curr_url) % if not '?' in nopage_url: % nopage_url += "?" % elif not nopage_url[-1] in ['?', '&']: % nopage_url += "&" % end % res = nopage_url + ("page=%d" % p) % return res % end % def class_of_page(p, cp): % if p < 0 or p >= totalPages: % return 'class="disabled"' % elif p == cp: % return 'class="active"' % else: % return '' % end % end % def displayed_pages(cp): % minp = max(0,cp-2) % maxp = min(minp+4,totalPages-1) % minp = max(0,maxp-4) % return range(minp, maxp+1) % end <ul class="pagination pagination-sm"> <li><a href="{{!link_to_page(0)}}"><span class="glyphicon glyphicon-fast-backward"></span></a></li> <li {{!class_of_page(page-1,page)}}><a href="{{!link_to_page(page-1)}}"><span class="glyphicon glyphicon-backward"></span></a></li> % for p in displayed_pages(page): <li {{!class_of_page(p,page)}}><a href="{{!link_to_page(p)}}">{{"%d" % (p+1)}}</a></li> % end <li {{!class_of_page(page+1,page)}}><a href="{{!link_to_page(page+1)}}"><span class="glyphicon glyphicon-forward"></span></a></li> <li><a href="{{!link_to_page(totalPages-1)}}"><span class="glyphicon glyphicon-fast-forward"></span></a></li> </ul> % end </div> <div class="col-sm-3"> <p class="navbar-text navbar-right"> {{"v"+features['version']}} provided by <b>Neys</b> </p> </ul> </div> </nav> <!--</div>--> </body> <!-- Initialize the multiselect plugin: --> <script type="text/javascript"> $(document).ready(function() { $('.multiselect').multiselect({ buttonWidth: '100%', includeSelectAllOption: true, enableFiltering: true, enableCaseInsensitiveFiltering: true, maxHeight: 350 }); }); </script> <!-- Support clickable table rows --> <script type="text/javascript"> jQuery(document).ready(function($) { $(".clickableRow td:not(.noclick)").click(function() { var tr = $(this).context.parentElement; window.document.location = $(tr).attr("href"); }); }); </script> <!-- Initialize the datepicker plugin --> <script type="text/javascript"> $('.datepicker').datepicker() </script> </html> """)
def test_unicode_code(self): """ Templates: utf8 code in file""" t = SimpleTemplate(name='./views/stpl_unicode.tpl') self.assertRenders(t, 'start ñç äöü end\n', var=touni('äöü'))
def test_name(self): t = SimpleTemplate(name='stpl_simple', lookup=['./views/']) self.assertRenders(t, 'start var end\n', var='var')
def test_file(self): with chdir(__file__): t = SimpleTemplate(name='./views/stpl_simple.tpl', lookup=['.']) self.assertRenders(t, 'start var end\n', var='var')
def inbox_page(): token = request.get_cookie('token', secret=cookie_secret) if request.method == 'POST' and validate_csrf_token( token, request.forms.csrf_token): if request.forms.get('mark_as_read') or request.forms.get( 'mark_as_unread'): action = 'mark_as_read' if request.forms.get( 'mark_as_read') else 'mark_as_unread' message_id = request.forms.get(action) rest_request = { 'token': token, 'message_id': message_id, 'action': action } rest_response = requests.put( 'http://localhost:8081/restapi/msgmod', json=rest_request).json() if rest_response['status'] == 'ok': info_message = 'Message has been successfully marked as {}.'.format( 'read' if action == 'mark_as_read' else 'unread') else: info_message = 'Operation failed. Please, try to logout and then login.' else: info_message = '' elif request.method == 'POST': info_message = 'CSRF attack detected' else: info_message = '' include_read = request.query.include_read include_read = True if include_read == '1' else False rest_request = {'token': token, 'include_read': include_read} rest_response = requests.put('http://localhost:8081/restapi/messages', json=rest_request).json() if rest_response['status'] == 'ok': messages_table = '<center>{}</center><table>{}</table>' rows = [] messages = rest_response['messages'] row = \ SimpleTemplate('<tr><td>From:</td><td>{{message["from"]}}</td></tr>' '<tr><td>Date:</td><td>{{message["datetime"]}}</td></tr>' '<tr><td>Action:</td><td>{{!action}}</td></tr>' '<tr><td colspan="2">Content:</td></tr>' '<tr><td colspan="2">{{message["content"]}}</td></tr>') for message in messages: is_read = message['read'] action = '<form action="" method="post">' \ '<input type="hidden" name="csrf_token" value="{}">' \ '<input name="{}" value="{}" type="hidden" />' \ '<input name="submit" type="submit" value="{}" />' \ '</form>'.format(generate_csrf_token(token), 'mark_as_unread' if is_read else 'mark_as_read', message['_id'], 'Mark as unread' if is_read else 'Mark as read') rows.append(row.render(message=message, action=action)) if not rows: messages_table = '<center>{}</center><center>You have no messages.</center>'.format( info_message) else: messages_table = messages_table.format(info_message, ''.join(rows)) else: messages_table = '<center>Could not retrieve messages from the server. ' \ 'Please, try to logout and then login.</center>' return main_page_template.render(sub_page_name='Inbox', body=messages_table)
def test_old_include(self): t1 = SimpleTemplate('%include foo') t1.cache['foo'] = SimpleTemplate('foo') self.assertEqual(t1.render(), 'foo')
class WwwServer(Thread): cp_config = { '/images': { 'tools.expires.on': True, 'tools.expires.secs': 3600 * 24 * 7, 'tools.staticdir.on': True, 'tools.staticdir.dir': abspath(os.path.join(static_base_dir, "images")), }, '/bootstrap': { 'tools.expires.on': True, 'tools.expires.secs': 3600 * 24 * 7, 'tools.staticdir.on': True, 'tools.staticdir.dir': abspath(os.path.join(static_base_dir, "bootstrap")), }, '/downloads': { 'tools.expires.on': True, 'tools.expires.secs': 3600 * 24 * 7, 'tools.staticdir.on': True, 'tools.staticdir.dir': abspath(os.path.join(static_base_dir, "downloads")), # 'tools.click_count.on' : True, }, '/git': { 'tools.expires.on': True, 'tools.expires.secs': 3600 * 24 * 7, 'tools.staticdir.on': True, 'tools.staticdir.dir': abspath(os.path.join(static_base_dir, "git")), # 'tools.click_count.on' : True, }, } def __init__(self, managed_dir=static_base_dir): Thread.__init__(self) self.daemon = True self.managed_dir = managed_dir self.pages = [] self.lastFileContents = None self._update_contents() self._templ = SimpleTemplate( open(static_base_dir + "/templ.html").read()) self.start() def _cmp_pages(self, np): if len(np) != len(self.pages): return False for i in range(len(np)): if len(np[i]) != len(self.pages[i]): return False for k in np[i].keys(): if not k in self.pages[i]: return False if self.pages[i][k] != np[i][k]: return False return True def run(self): lastCompleteUpdate = time.time() while 1: time.sleep(interval) t = time.time() if t - lastCompleteUpdate > 60 * 60 * 24: # regenerate the pages at least once a day lastCompleteUpdate = t self.lastFileContents = None self._update_contents() def _update_contents(self): pages = [] files = sorted(glob.glob(self.managed_dir + "/*.htm")) fileContents = [ open(f).read() for f in (files + [static_base_dir + "/templ.html"]) ] if fileContents == self.lastFileContents: pass for f in files: p = self._parse(f) if not p is None: pages.append(p) pages.sort(key=lambda x: (x['index'], x['nav'])) if not self._cmp_pages(pages): self.pages = pages for p in self.pages: f = functools.partial(self._genpage, page=p) setattr(self, p['link'], f) getattr(self, p['link']).exposed = True def _parse(self, f): link = os.path.splitext(os.path.basename(f))[0] l = open(f).readline() M = re.match( r'<!--\s*title="([^"]*)"\s*nav="([^"]*)"\s*index=([0-9]+)\s*sections=(.*)\s*-->', l.strip()) try: if not M is None: title = M.group(1) nav = M.group(2) index = int(M.group(3)) raw_sections = M.group(4) if raw_sections.strip() == "auto": html = open(f).read() pattern = r'<h([0-9])>(.*)</h\1>' chapters = [] while 1: M = re.search(pattern, html) if M is None: break level = int(M.group(1)) name = M.group(2) counter = len(chapters) ref = "auto_chapter_%(counter)d" % locals() chapters.append((ref, name, level)) html = ( html[:M.start(0)] + ('<h%(level)d id="%(ref)s">%(name)s</h%(level)d>' % locals()) + html[M.end(0):]) else: html = open(f).read() sections = raw_sections.split(",") chapters = [] try: for sp in sections: ref, desc = sp.split("+") desc = desc.strip() desc = desc[1:-1] chapters.append((ref, desc, 1)) except: pass res = dict(title=title, nav=nav, index=index, link=link, chapters=chapters, template=SimpleTemplate(html)) return res except: print(traceback.format_exc()) pass def _genpage(self, page, **kw): return self._templ.render(server=self, src=page['link'], kw=kw) def _redirect(self, name, **kw): s = "?" new_url = name for p in kw: v = kw[p] if not v is None: new_url += s + p + "=" + str(kw[p]) s = "&" raise cherrypy.HTTPRedirect(new_url) @cherrypy.expose def default(self): self._redirect(self.pages[0]['link']) def link_from_file(self, file): ap = abspath(file) if ap.startswith(self.managed_dir): ap = ap[len(self.managed_dir):] return ap def get_num_downloads(self, name): if db is None: return 0 try: c = db.cursor() c.execute("SELECT NumClicks,Name FROM Clicks WHERE Name=%s", (name, )) a = c.fetchone() if not a is None: return a[0] return 0 except: print(traceback.format_exc()) return 0
def test_defect_coding(self): t1 = SimpleTemplate('%#coding comment\nfoo{{y}}') self.assertEqual(t1.render(y='bar'), 'foobar')
#!/usr/bin/env python3 from bottle import SimpleTemplate tpl = SimpleTemplate('hello {{name}}') print(tpl.render(name='world'))
import requests from bottle import route, request, response, redirect, run, SimpleTemplate from urllib.parse import urlparse from hashlib import md5 cookie_secret = 'nboitCJ05G3y80QU' register_form_template = \ SimpleTemplate('<html><head><title>Fictional goggles : Login page</title>' '<style>table { margin-left: auto; margin-right: auto; } body { text-align: center; }</style>' '</head><body><a href="/login">Login page</a><br/>{{message}}' '<form action="/register" method="post"><table>' '<tr><td>Username:</td><td><input name="username" type="text" /></td></tr>' '<tr><td>Password:</td><td><input name="password" type="password" /></td></tr>' '<tr><td colspan="2" style="text-align: center;"><input value="Register" type="submit" /></td></tr>' '</table></form></body></html>') login_form_template = \ SimpleTemplate('<html><head><title>Fictional goggles : Login page</title>' '<style>table { margin-left: auto; margin-right: auto; } body { text-align: center; }</style>' '</head><body><a href="/register">Create a new account</a><br/>{{message}}' '<form action="/login" method="post"><table>' '<tr><td>Username:</td><td><input name="username" type="text" /></td></tr>' '<tr><td>Password:</td><td><input name="password" type="password" /></td></tr>' '<tr><td colspan="2" style="text-align: center;"><input value="Login" type="submit" /></td></tr>' '</table></form></body></html>') main_page_template = \ SimpleTemplate('<html><head><title>Fictional goggles : {{sub_page_name}}</title><style>' 'table { margin-left: auto; margin-right: auto; } ' 'body { margin: 10px; margin-top: 50px; } '
def test_rebase(self): """ Templates: %rebase and method passing """ t = SimpleTemplate(name='stpl_t2main', lookup=['./views/']) result = '+base+\n+main+\n!1234!\n+include+\n-main-\n+include+\n-base-\n' self.assertRenders(t, result, content='1234')
def sent_page(): def generate_friend_list(token, recipient): rest_response = requests.put('http://localhost:8081/restapi/friends', json={ 'token': token }).json() option = '<option value="{0}"{1}>{0}</option>' select = '<select name="recipient">{}</select>' if rest_response['status'] == 'ok': friends = rest_response['friends'] else: friends = [] options = [] for friend in friends: if friend['is_friend'] != 2: continue options.append( option.format( friend['username'], ' selected' if friend['username'] == recipient else '')) if options: return select.format(''.join(options)) else: return '<input name="recipient" value="You have no friends." type="text" readonly />' token = request.get_cookie('token', secret=cookie_secret) if request.method == 'POST' and validate_csrf_token( token, request.forms.csrf_token): recipient = request.forms.recipient content = request.forms.content print(content) rest_request = { 'token': token, 'recipient': recipient, 'content': content } rest_response = requests.put('http://localhost:8081/restapi/sendmsg', json=rest_request).json() if rest_response['status'] == 'ok': info_message = 'Message has been successfully sent to {}.'.format( recipient) recipient = '' content = '' else: info_message = 'Operation failed. Please, try to logout and then login.' elif request.method == 'POST': recipient = '' content = '' info_message = 'CSRF attack detected' else: recipient = '' content = '' info_message = '' include_read = request.query.include_read include_read = True if include_read == '1' else False rest_request = { 'token': token, 'include_read': include_read, 'include_received': False, 'include_sent': True } rest_response = requests.put('http://localhost:8081/restapi/messages', json=rest_request).json() if rest_response['status'] == 'ok': messages_table = '<center>{}</center><form action="" method="post">' \ '<input type="hidden" name="csrf_token" value="{}"><table>' \ '<tr><td>To:</td>' \ '<td>{}</td></tr>' \ '<tr><td colspan="2">Content:</td></tr>' \ '<tr><td colspan="2"><textarea name="content" rows="10">{}</textarea></td></tr>' \ '<tr><td colspan="2" style="text-align: center;">' \ '<input value="Send" type="submit" /></td></tr>' \ '</table></form>{}' rows = [] messages = rest_response['messages'] row = \ SimpleTemplate('<tr><td>To:</td><td>{{to}}</td></tr>' '<tr><td>Date:</td><td>{{datetime}}</td></tr>' '<tr><td colspan="2">Content:</td></tr>' '<tr><td colspan="2">{{content}}</td></tr>') for message in messages: rows.append(row.render(**message)) if not rows: messages_table = messages_table.format( info_message, generate_csrf_token(token), generate_friend_list(token, recipient), content, '<center>You have not sent any messages.</center>') else: messages_table = messages_table.format( info_message, generate_csrf_token(token), generate_friend_list(token, recipient), content, '<table>{}</table>'.format(''.join(rows))) else: messages_table = '<center>Could not retrieve messages from the server. ' \ 'Please, try to logout and then login.</center>' return main_page_template.render(sub_page_name='Sent', body=messages_table)
def gen_template(self, code, feature): self.check_feature(feature) temp = self.read_template() s = SimpleTemplate(temp) s = s.render({'routes':code}) self.write_file(s)
def test_include(self): """ Templates: Include statements""" t = SimpleTemplate(name='stpl_include', lookup=['./views/']) self.assertRenders(t, 'before\nstart var end\nafter\n', var='var')
def test_newline_in_parameterlist(self): ''' Block statements with non-terminating newlines in list ''' t = SimpleTemplate("%a=[1,\n%2]\n{{len(a)}}") self.assertEqual(u"2", t.render())
def test_error(self): """ Templates: Exceptions""" self.assertRaises(SyntaxError, lambda: SimpleTemplate('%for badsyntax').co) self.assertRaises(IndexError, SimpleTemplate('{{i[5]}}').render, i=[0])
def test_multiline(self): ''' Block statements with non-terminating newlines ''' t = SimpleTemplate("%if 1\\\n%and 1:\nyes\n%end\n") self.assertEqual(u"yes\n", t.render())
def test_file(self): t = SimpleTemplate(name='./views/stpl_simple.tpl') self.assertRenders(t, 'start var end\n', var='var')
return join_xml(b) # region: bottle try: from bottle import SimpleTemplate except ImportError: test_bottle = None else: bottle_template = SimpleTemplate( s("""\ <table> % for row in table: <tr> % for key, value in row.items(): <td>{{key}}</td><td>{{!value}}</td> % end </tr> % end </table> """)) def test_bottle(): return bottle_template.render(**ctx) def run(number=100): import profile from timeit import Timer from pstats import Stats names = globals().keys()
mainPageTemplate = SimpleTemplate(""" <div class="container"> <div class="row page-header"> <div class="col-md-6"><img src="/img/banner.png" title="Logo Track" class="ACimg"> </div> <div class="col-md-6"> </div> </div> <div class="row"> <div class="col-md-12"> <h1>Welcome to the stracker statistics query</h1> <h2>What is stracker</h2> <p><i>stracker</i> is a service supporting Assetto Corsa servers with automatically generated statistics.</p> <h2>Prerequisites</h2> <p>While <i>stracker</i> works as a standalone server-side application, Assetto Corsa drivers are encouraged to use the app <i>ptracker</i> which offers the following benefits: <ul> <li>in-game access to the most important statistics pages</li> <li>sending setups between drivers</li> <li>automaticall save personal best setups</li> <li>optional leaderboard display with various delta methods</li> <li>optional live delta display to your fastest lap or any stored lap in the server</li> <li>optional display of <i>stracker</i> messages</li> <li>send detailed lap information to <i>stracker</i></li> </ul> </p> <h2>Project homepages</h2> <p><a href="http://n-e-y-s.de">ptracker and stracker homepage</a><br> <a href="http://n-e-y-s.de/ptracker_doc">ptracker documentation and FAQ</a><br> <a href="http://n-e-y-s.de/stracker_doc">stracker documentation and FAQ</a></p> </div> </div> </div> """)
"""Simple hacks for an agenda""" from bottle import SimpleTemplate from datetime import date, timedelta import itertools import re import db from appbase import get_url, static, user_is_admin from app import renderMarkdown, renderTemplate, log link = SimpleTemplate('<a href="{{url}}" target="_blank">{{text}}</a>') db.init() def comment_line(line, user): """ When parse reads a line starting with a #, create a comment line for admin users """ if not user_is_admin(user): return "" line = renderMarkdown(line[1:]) return f"<font color='grey'>{line}</font>" def slide_line(line): """ Given an agenda line, create a slide html link for it """ words = line[2:].strip().split(' ', 1) assert len( words ) == 2, f"COMP550Agenda split_line should be a filename in static/slides and then a description" url = static("slides/" + words[0])
def apitest(): return SimpleTemplate( source= '<html><head> <script src="/js/prototype.js" type="text/javascript"></script><script src="/js/api.js" type="text/javascript"></script></head></html>' ).render()
sesStatTableTemplate = SimpleTemplate(""" % from ptracker_lib.helpers import format_datetime, unixtime2datetime <div class="container"> <div class="row page-header"> <div class="col-md-6"><img src="/img/banner.png" title="Logo Track" class="ACimg"> </div> <div class="col-md-6"> <form class="form-horizontal collapse-group" role="form"> <div class="form-group"> <label for="trackname" class="col-md-4 control-label">Track</label> <div class="col-md-8"> <select id="trackname" name="trackname" class="multiselect form-control"> % for d in tracks: % t = d['track'] % uit = d['uitrack'] % if t == currtrack: % s = "selected" % else: % s = "" % end <option {{!s}} value="{{t}}">{{uit}}</option> % end </select> </div> <label for="session_type" class="col-md-4 control-label">Type</label> <div class="col-md-8"> <select id="session_type" name="session_type" class="form-control multiselect" multiple="multiple"> <option {{"selected" if "Practice" in session_types else ""}} value="Practice">Practice</option> <option {{"selected" if "Qualify" in session_types else ""}} value="Qualify">Qualify</option> <option {{"selected" if "Race" in session_types else ""}} value="Race">Race</option> </select> </div> </div> %options_detailed = num_players > 0 or num_laps > 0 or datespan[0] != "" or datespan[1] != "" <div class="form-group collapse {{!"in" if options_detailed else ""}}" id="filterCollapse"> <div class="row"> <label for="num_players" class="col-md-4 control-label">Number of Players</label> <div class="col-md-8"> <select id="num_players" name="num_players" class="form-control multiselect"> <option {{"selected" if num_players == 0 else ""}} value="0">any</option> % for i in range(1,25): <option {{"selected" if num_players == i else ""}} value="{{i}}">{{"%d or more" % i}}</option> % end </select> </div> </div> <div class="row"> <label for="num_laps" class="col-md-4 control-label">Number of Laps</label> <div class="col-md-8"> <select id="num_laps" name="num_laps" class="form-control multiselect"> <option {{"selected" if num_laps == 0 else ""}} value="0">any</option> % for i in range(1,50): <option {{"selected" if num_laps == i else ""}} value="{{i}}">{{"%d or more" % i}}</option> % end </select> </div> </div> <div class="row"> <label for="datespan" class="col-md-4 control-label">Date</label> <div id="datespan" class="col-md-8"> <div class="form-group row"> <label for="dateStart" class="col-md-2 control-label">From</label> <div class="col-md-4"> <input id="dateStart" class="datepicker form-control" data-date-format="yyyy-mm-dd" value="{{!datespan[0]}}" /> </div> <label for="dateStop" class="col-md-2 control-label">To</label> <div class="col-md-4"> <input id="dateStop" class="datepicker form-control" data-date-format="yyyy-mm-dd" value="{{!datespan[1]}}" /> </div> </div> </div> </div> </div> <div class="form-group"> <script> function toggleCollapse(e, self) { var $e = $(e); var $collapse = $e.closest('.collapse-group').find('.collapse'); var $self = $(self); console.log("toggleCollapse: " + $($self[0]).text()); if( $($self[0]).text() == "+" ) { $($self[0]).text("-"); $collapse.collapse('show'); } else { $($self[0]).text("+"); $collapse.collapse('hide'); } } </script> <div class="col-md-offset-2 col-md-2"> <a class="form-control btn btn-info" role="button" onclick="toggleCollapse(getElementById('filterCollapse'), this)" href="#">{{!"-" if options_detailed else "+"}}</a> </div> <div class="col-md-offset-0 col-md-4"> <script> function ms_to_string(ms) { res = ''; for(var i=0; i < ms.length; i++) { if (ms.options[i].selected) { if (res != '') { res = res + ","; } res = res + ms.options[i].value } } return res; } function applySelections() { var track = document.getElementById("trackname").value; var startDate = document.getElementById("dateStart").value; var stopDate = document.getElementById("dateStop").value; var session_types = ms_to_string(document.getElementById("session_type")); var num_players = document.getElementById("num_players").value var num_laps = document.getElementById("num_laps").value window.location='sessionstat?track='+track+'&start='+startDate+'&stop='+stopDate+'&session_types='+session_types+'&num_players='+num_players+'&num_laps='+num_laps; } </script> <a class="form-control btn btn-primary" role="button" onclick="applySelections()" href="#">Show selected</a> </div> <div class="col-md-offset-0 col-md-4"> <a class="form-control btn btn-primary" href="sessionstat" role="button">Show all</a> </div> </div> </form> </div> </div> <div class="row"><div class="col-md-12"> <table class="table table-striped table-condensed table-bordered table-hover"> <thead> <tr> <th>Track</th> <th>Type</th> <th>First</th> <th>Second</th> <th>Third</th> <th>Number of drivers</th> <th>Date</th> </tr> </thead> <tbody> % for i,r in enumerate(sesStatRes): <tr class="clickableRow" href="sessiondetails?sessionid={{"%d" % r['id']}}#"> <td>{{r['uitrack']}}</td> <td>{{r['type']}}</td> <td>{{"" if r['podium'][0] is None else r['podium'][0]}}</td> <td>{{"" if r['podium'][1] is None else r['podium'][1]}}</td> <td>{{"" if r['podium'][2] is None else r['podium'][2]}}</td> <td>{{r['numPlayers']}}</td> <td> % ts = r.get('timeStamp', None) % if ts is None: % ts = "-" % else: % ts = format_datetime(unixtime2datetime(ts)) % end {{ts}} </td> </tr> % end </tbody> </table> </div></div> </div> """)