def render(self, form): formHtml = ( T.form(class_="form-horizontal", method='POST')[ forEach(form, lambda field: ( self.renderField(field) )), T.div(class_="form-group")[ T.div(class_="col-sm-offset-3 col-sm-9")[ [ T.button(class_="btn btn-default")[name] for name in self.buttons ] ] ], ] ) if self.renderPanel: formHtml = ( T.div(class_="panel panel-default")[ T.div(class_="panel-body")[ formHtml ] ] ) return ( formHtml )
def renderLoginForm(self, form, count): formView = FormRenderer() formView.addButton('Login') formView.setRenderPanel() content = [ T.div(class_="row")[ T.div(class_="col-sm-4")[ T.h2['Login form '], ], T.div(class_="col-sm-4 text-right")[ T.h2[T.a(href=self.getUrl('register'))['Register account']] ] ], T.div(class_="row")[ T.div(class_="col-sm-8")[ formView.render(form) ] ], ] layout = HtmlLayout(isLogged=False) layout.setContent(content) return layout
def renderRegisterForm(self, form): html = HtmlLayout(isLogged=False) formView = FormRenderer() formView.addButton('Create account') formView.setRenderPanel() content = ( T.div(class_="row")[ T.div(class_="col-sm-4")[ T.h2['Register form'], ], T.div(class_="col-sm-4 text-right")[ T.h2[T.a(href=self.getUrl('index'))['Back']] ] ], T.div(class_="row")[ T.div(class_="col-sm-8")[ formView.render(form) ] ] ) html.setContent(content) return html
def renderApiKeys(self, keys): content = ( T.h2['API Keys'], T.p[ T.a(href=self.getUrl('profile/newKey'))[ T.button(class_='btn btn-primary')['Add key'] ], ], T.div(class_='panel panel-default')[ T.div(class_='panel-heading')['Added keys'], T.table(class_='table')[ T.thead[ T.tr[ T.th['Key ID'], T.th['Expires'], T.th['Characters'], T.th() ] ], T.tbody[ forEach(keys, lambda keyId, expires, characters: ( T.tr[ T.td[keyId], T.td[expires], T.td[ [ T.div[char] for char in characters ] ], T.td[ T.a(class_='glyphicon glyphicon-info-sign withTooltip', title='Detailed info', href='#', **{'data-placement': 'top', 'data-toggle': 'tooltip'}), ' ', T.a(class_='glyphicon glyphicon-trash withTooltip text-danger', title='Delete key', href='#', **{'data-placement': 'top', 'data-toggle': 'tooltip'}), ] ] )), ] ] ] ) html = HtmlLayout() html.setContent(content) return html
def Panel(content, heading=None): return T.div(class_="panel panel-default")[ C.when(heading is not None)[ T.div(class_='panel-heading')[ T.h3(class_='panel-title')[ heading ] ] ], T.div(class_="panel-body")[ content ] ]
def render(self, request, url): """ :type url: werkzeug.routing.MapAdapter :type request: werkzeug.wrappers.Request """ # ifLogged = lambda fun: fun if self.isLogged else '' isTrusted = IGBRequest(request).isTrusted layout = ( T.html(lang='en')[ T.head[ T.meta(charset='utf-8'), T.meta(content='IE=Edge', **{'http-equiv': "X-UA-Compatible"}), T.meta(name='viewport', content='width=device-width, initial-scale=1'), T.title['PyEve IGB'], T.link(href='/static/css/bootstrap-black.min.css', rel='stylesheet'), T.link(href='/static/css/igb.css', rel='stylesheet'), T.script(src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'), T.script(src='/static/js/bootstrap.js'), T.script(src='/static/js/igbCore.js'), self.getAdditionalJs() ], T.body[ # 'HOWDY', # request.headers.get('EVE_TRUSTED', 'alo'), T.div(class_='container-fluid')[ C.switch(isTrusted)[ C.case(True)[self.content], C.case(False)[self.renderRequestTrust()] ], T.div(class_='text-center')[ T.small[ 'PyEVE. Created by ', T.a(href="#", onclick="CCPEVE.showInfo(1377, 93747896); return false")[ 'Rudykocur Maxwell' ] ] ] ], ] ] ) return Response(flatten(layout), mimetype='text/html')
def renderBooleanField(self, field): return ( T.div(class_="form-group")[ T.div(class_="col-sm-offset-3 col-sm-9")[ T.div(class_="checkbox")[ T.label[ field(), field.label ] ] ] ], )
def render(self, request, url): """ :type url: werkzeug.routing.MapAdapter """ ifLogged = lambda fun: fun if self.isLogged else '' layout = ( T.html(lang='en')[ T.head[ T.meta(charset='utf-8'), T.meta(content='IE=Edge', **{'http-equiv': "X-UA-Compatible"}), T.meta(name='viewport', content='width=device-width, initial-scale=1'), T.title['PyEve WSGI App'], T.link(href='/static/css/bootstrap.min.css', rel='stylesheet') ], T.body[ T.div(class_="container-fluid")[ T.h1['PyEve'], invisible(render=ifLogged(self.renderNavbar), data=(url, None)), T.div(class_='row')[ T.div(class_='col-sm-3')[ invisible(render=ifLogged(self.renderModuleNav), data=(url, None)) ], T.div(class_='col-sm-9')[ self.content ] ], ], T.script(src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'), T.script(src='/static/js/bootstrap.js'), T.inlineJS(""" $(document).ready(function() { $(document.body).tooltip({ selector: ".withTooltip" }) }) """) ] ] ) return Response(flatten(layout), mimetype='text/html')
def _renderHeader(self, helper): return [ 'Hello ', T.strong[helper.charName], T.div(class_='pull-right')[ T.a(href=self.getUrl('scanning/corporation'))['Go to corp'] ] ]
def _renderHeader(self, helper): """ :type helper: pyeve.www.igb.IGBRequest """ return [ 'Hello ', T.strong[helper.charName], ', from ', T.strong[helper.corpName], T.div(class_='pull-right')[ T.a(href=self.getUrl('scanning/personal'))['Go to personal'] ] ]
def doGet(self, request): layout = IGBLayout() layout.addJs('dom.jsPlumb-1.6.4-min.js') layout.addJs('whMap.js') layout.setContent([ Panel(heading=['Simple map'], content=T.div(id='wormholeMap')[ T.div(class_='whRow')[ whSlotEmpty(), whSlotEmpty(), whSlot('J123456', 'Some data'), whSlot('J098654', 'Some data 2'), whSlotEmpty(), whSlotEmpty(), ], T.div(class_='whRow')[ whSlotEmpty(), whSlotEmpty(), whSlotEmpty(), whSlot('J432567', 'Some data 2'), whSlotEmpty(), whSlotEmpty(), ], T.div(class_='whRow')[ whSlotEmpty(), whSlot('J111111', 'Some data 9'), whSlot('J111112', 'Some data 8'), whSlot('J111113', 'Some data 7'), whSlot('J111114', 'Some data 6'), whSlot('J111115', 'Some data 5'), ], ] ) ]) return layout
def renderStandardField(self, field): additionalClasses = set() feedbackIcon = None if field.flags.required: feedbackIcon = 'glyphicon-asterisk' if field.errors: additionalClasses.add('has-error') feedbackIcon = 'glyphicon-remove' if feedbackIcon is not None: additionalClasses.add('has-feedback') classes = ' %s' % ' '.join(additionalClasses) return ( T.div(class_="form-group%s" % classes)[ T.label(class_="col-sm-3 control-label")[field.label], T.div(class_="col-sm-9")[ field(class_='form-control'), C.when(feedbackIcon)[ T.span(class_='glyphicon form-control-feedback %s' % feedbackIcon), ], C.when(field.errors)[ T.span(class_='help-block')[ T.ul[ [T.li[err] for err in field.errors] ] ] ] ], ], )
def test_escaping(): """escaping, xml() directive""" template = T.html[ T.head[T.title[my_name()]], T.body[ T.div(style='width: 400px;<should be &escaped&>')[ T.p(class_='foo')['&&&'], T.p['Coffee', E.nbsp, E.amp, E.nbsp, 'cream'], xml ("""<div>this should be <u>unescaped</u> & unaltered.</div>""") ] ] ] output = flatten(template) assert output == ('<html><head><title>test_escaping</title></head>' '<body><div style="width: 400px;<should be &escaped&>">' '<p class="foo">&&&</p><p>Coffee & cream</p>' '<div>this should be <u>unescaped</u> & unaltered.</div></div>' '</body></html>')
def test_toc_macro ( self ): '''test table-of-contents macro''' template = ( assign ( 'TOC', [ ] ), macro ( 'TableOfContents', lambda matchtags, tag: ( macro ( 'toc_search', lambda tag, is_tag: tag.name in matchtags and ( TOC.append ( T.a ( href='#toc-%s' % tag.children [ 0 ] ) [ tag.children [ 0 ] ] ), tag.attrs.update ( { 'class': 'chapter-%s' % tag.name } ), tag.children.insert ( 0, T.a ( name='toc-%s' % tag.children [ 0 ] ) [ tag.name ] ) ) or True ), tag.walk ( toc_search, True ) ) ), T.html [ T.head [ T.title [ my_name ( ) ] ], T.body [ T.div ( id='TableOfContents' ) [ 'Table of Contents', lambda: T.ul [ [ T.li [ _t ] for _t in TOC ] ] ], TableOfContents ( ( 'h1', 'h2', 'h3' ), T.div [ T.h1 [ 'Chapter 1' ], T.div [ 'chapter 1 content' ], T.h1 [ 'Chapter 2' ], T.div [ 'chapter 2 content', T.h2 [ 'Chapter 2 subsection' ], T.div [ 'chapter 2 subsection content' ] ] ] ) ] ] ) actual = flatten ( template )
def test_dom_traversal_from_macro(): """macro abuse: self-traversing template""" template = ( assign('selectors', []), macro('css_sep', lambda attr: attr == 'class' and '.' or '#' ), macro('get_selectors', lambda tag, is_tag: selectors.extend([ # @UndefinedVariable "%s%s%s { }" % (tag.name, css_sep(_k.strip('_')), _v) # @UndefinedVariable for _k, _v in tag.attrs.items() if _k.strip('_') in ('id', 'class') ]) ), macro('extract_css', lambda tag: tag.walk(get_selectors, True) and tag # @UndefinedVariable ), macro('css_results', lambda selectors: T.pre['\n'.join(selectors)] ), T.html[ T.head[T.title['macro madness']], T.body[extract_css(# @UndefinedVariable T.div('class', 'text', 'id', 'main-content')[ T.img('src', '/images/breve-logo.png', 'alt', 'breve logo'), T.br, T.span (class_='bold') [ """Hello from Breve!""" ] ] ), css_results(selectors)] # @UndefinedVariable ] ) output = flatten(template) assert output == ('<html><head><title>macro madness</title></head>' '<body><div class="text" id="main-content">' '<img src="/images/breve-logo.png" alt="breve logo"></img>' '<br /><span class="bold">Hello from Breve!</span></div>' '<pre>div.text { }\ndiv#main-content { }\nspan.bold { }</pre>' '</body></html>')
def Modal(id, content, heading=None, footer=None): result = [] result.append(T.div(class_='modal fade', id=id, tabindex='-1', role='dialog')[ T.div(class_='modal-dialog')[ T.div(class_='modal-content')[ T.div(class_='modal-header')[ T.button(type='button', class_='close', **{'data-dismiss': 'modal'})[ T.span[entities.times], T.span(class_='sr-only')['Close'] ], T.h4(class_='modal-title')[heading] ], T.div(class_='modal-body')[ content ], C.when(footer is not None)[ T.div(class_='modal-footer')[footer] ] ] ] ]) return result
def renderNavbar(self, tag, data): """ :type data: (werkzeug.routing.MapAdapter, None) """ (url, unused) = data currentEndpoint = url.match()[0] burgerToggle = lambda targetId: ( T.button(class_='navbar-toggle', **{'data-toggle': 'collapse', 'data-target': '#%s' % targetId})[ T.span(class_='sr-only')['Toggle navigation'], T.span(class_='icon-bar'), T.span(class_='icon-bar'), T.span(class_='icon-bar'), ] ) mainNavigation = lambda: ( forEach(self.modules, lambda mod: ( T.li(class_='active' if currentEndpoint in mod.endpoints else None)[ T.a(href=url.build(mod.pages[0].endpoint))[mod.name] ] )) ) html = ( T.nav(class_='navbar navbar-default', role='navigation')[ T.div(class_='container-fluid')[ T.div(class_='navbar-header')[ burgerToggle('mainNavCollapse'), T.span(class_='navbar-brand')['Rudykocur Maxwell'] ], T.div(class_='collapse navbar-collapse', id='mainNavCollapse')[ T.ul(class_="nav navbar-nav")[ mainNavigation() ], T.ul(class_="nav navbar-nav navbar-right")[ T.li(class_='dropdown')[ T.a(href='#', class_='dropdown-toggle', **{'data-toggle': 'dropdown'})[ 'Characters', ' ', T.span(class_='caret') ], T.ul(class_='dropdown-menu', role='menu')[ T.li(role='presentation', class_='dropdown-header')['Account: Rudykocur'], T.li[T.a(href='#')['Rudykocur Maxwell']], T.li[T.a(href='#')['Imaginary Profile']], T.li(role='presentation', class_='divider'), T.li(role='presentation', class_='dropdown-header')['Account: Generic'], T.li[T.a(href='#')['All Skills V']], ], ], T.li[ T.a(href=url.build('logout'))['Logout'] ] ] ] ] ] ) return tag[html]
def whSlotEmpty(): return T.div(class_='whSlot emptySlot')
def renderSignatureLoot(self, signatureKey): result = Modal( id='lootModal', content=[ T.div(id='containers')[ T.div(class_='buttons')[ T.button(type='button', class_='btn btn-success', **{'data-level': 'trivial'})['+ Debris'], T.button(type='button', class_='btn btn-success', **{'data-level': 'easy'})['+ Rubble'], T.button(type='button', class_='btn btn-warning', **{'data-level': 'medium'})['+ Remains'], T.button(type='button', class_='btn btn-danger', **{'data-level': 'hard'})['+ Ruins'], ], T.div(id='contentPaste')[ Panel( heading='Paste content of container below', content=[ T.div(class_='row')[ T.div(class_='col-xs-9')[ T.textarea(class_="form-control", rows="2"), ], T.div(class_='col-xs-3')[ T.button(class_='btn btn-default')['Submit'], T.div(class_='ajaxLoader', style='white-space: nowrap')[ T.img(src='/static/images/ajax-loader.gif'), ' Processing' ], ], ], ] ), ], T.div(class_='row container-list')[ T.div(class_='col-xs-3 blueprint')[ T.div(class_='thumbnail')[ T.img(src='#'), T.div(class_='caption')[ T.strong()['Lorem ipsum'], T.div(class_='totalWorth')['Lorem ipsum'], ], T.a(href='#', title='Delete', **{'data-toggle': 'tooltip', 'data-placement': 'top'})[ T.span(class_='glyphicon glyphicon-remove-circle') ] ] ] ], ] ], heading=['Loot for signature ', T.strong[signatureKey]], ) return result
def renderResponse(self, helper, signatures): layout = IGBLayout() layout.addJs('common.js') layout.addJs('scanning.js') layout.addJs('loot.js') if helper.isTrusted: content = [ Panel( heading=[ self._renderHeader(helper), ], content=[ T.div(class_='row')[ T.div(class_='col-xs-8')[ T.textarea(class_="form-control", id="signaturesInput", rows="2", style="overflow: hidden; resize: none", placeholder="Paste scanning content here") ], T.div(class_='col-xs-4')[ T.button(class_='btn btn-default', id='processButton')['Submit'], T.img(id='ajaxLoader', src='/static/images/ajax-loader.gif'), ], ] ] ), Panel(heading=['Known signatures in ', T.strong[helper.systemName], T.div(class_='pull-right')[ T.a(href=self.getUrl('scanning/help'))['How to use this tool'] ]], content=[ T.div(id='bookmarkContainer')[ self.getKnownSignaturesTable(signatures) ], ]), T.script[ """ $(document).ready(function() { BookmarkManager.init({ container: document.getElementById('bookmarkContainer'), processButton: document.getElementById('processButton'), signaturesInput: document.getElementById('signaturesInput'), ajaxLoader: document.getElementById('ajaxLoader'), systemName: '%(system)s' }); LootInterface.init(); }); """ % dict(system=helper.systemName) ] ] layout.setContent(content) return layout
def whSlot(title, data): return T.div(class_='whSlot', id='sig-%s' % title)[ T.div(class_='title')[title], T.div(class_='')[data] ]