def __init__(self): self.pre = Pre( '{}', style={ 'background-color': 'lightgrey', }, ) self.nodes = [ Div( Div( Button('None Node Event', _id='non-node-event'), Button('Node Event', _id='node-event'), style={ 'float': 'left', 'width': '50%', }, ), Div( self.pre, style={ 'float': 'left', 'width': '50%', }, ), ), ]
def __init__(self): self.server_state = Div() self.nodes = [ self.server_state, Div(_id='client-state'), ]
class LockingView(LonaView): def handle_request(self, request): now = Span() self.message = Div('Button not clicked') self.button = Button('Button') self.html = Div( H2('Server State Locking View'), Div(Strong('Now: '), now), Br(), self.message, self.button, ) while True: self.server.state['now'] = str(datetime.now()) now.set_text(self.server.state['now']) self.show(self.html) self.sleep(1) def handle_input_event(self, input_event): with self.server.state.lock: self.message.set_text('Button clicked; Lock') self.show(self.html) self.sleep(2) self.message.set_text('Unlock') self.show(self.html)
def update_user_list(self): with self.html.lock: self.user_list.clear() self.user_list.append(Div('User Online: ')) for user in self.state['user']: self.user_list.append(Div(' {}'.format(str(user)))) self.show()
def handle_request(self, request): widget = HTML() interval = Select(values=[ (1, '1s', False), (0.5, '0.5s', True), (0.25, '0.25s', False), (0.01, '0.01s', False), ], ) html = HTML( H2('Interactive View'), Strong('Interval: '), interval, Br(), Br(), widget, ) while True: widget.clear() for i in range(0, 5): widget.append(Div('Div {}'.format(i + 1))) self.show(html) self.sleep(float(interval.value)) for i in range(0, 5): widget[i].insert(i + 1, Div('Div {}.{}'.format(i + 1, i + 1))) self.show(html) self.sleep(float(interval.value)) for i in range(0, 5): widget[i].style = {'color': 'red'} self.show(html) self.sleep(float(interval.value)) moving_div = Div('Div 6', style={'color': 'blue'}) for i in range(0, 5): widget[i].append(moving_div) self.show(html) self.sleep(float(interval.value)) self.show(html)
def handle_request(self, request): timestamp = Div() html = HTML( H1('Interactive View'), A('Home', href='/'), timestamp, ) while True: timestamp.set_text(str(datetime.now())) self.show(html) self.sleep(1)
def add_message_to_history(self, message, show=True): issuer, text = message self.history.append(Div('{}: {}'.format(issuer, text))) if show: self.show()
class TestWidget(Widget): STATIC_FILES = [ Script(name='TestWidget', path='widget_data.js'), ] FRONTEND_WIDGET_CLASS = 'widget_data' def __init__(self): self.server_state = Div() self.nodes = [ self.server_state, Div(_id='client-state'), ] def update_state(self): self.server_state.set_text(dumps(self.data))
def handle_request(self, request): now = Span() self.message = Div('Button not clicked') self.button = Button('Button') self.html = Div( H2('HTML Tree Locking View'), Div(Strong('Now: '), now), Br(), self.message, self.button, ) while True: now.set_text(datetime.now()) self.show(self.html) self.sleep(1)
def handle_request(self, request): now = Span() self.message = Div('Button not clicked') self.button = Button('Button') self.html = Div( H2('Server State Locking View'), Div(Strong('Now: '), now), Br(), self.message, self.button, ) while True: self.server.state['now'] = str(datetime.now()) now.set_text(self.server.state['now']) self.show(self.html) self.sleep(1)
def handle_request(self, request): message = Div('Button not clicked') button = Button('Click me!') html = HTML( H1('Click the button!'), message, button, ) self.show(html) # this call blocks until the button was clicked input_event = self.await_click(button) if input_event.node == button: message.set_text('Button clicked') return html
def handle_request(self, request): div = Div() html = HTML( H2('Set Title'), A('Back', href='/'), div, ) self.show(html) while True: for i in range(3): title = 'Title {}'.format(i) div.set_text( "Using set_title(); Title should be '{}'".format(title)) self.set_title(title) self.show() self.sleep(1) for i in range(3): title = 'Title {}'.format(i) div.set_text("using show; Title should be '{}'".format(title)) self.show(html, title=title) self.sleep(1)
def handle_request(self, request): self.stop_at = None self.console = Pre(style={ 'background-color': 'lightgrey', }, ) html = HTML( H2('Event Bubbling'), Div( 'Stop Event at ', SelectNode( OptionNode( '---', value='', selected=True, ), OptionNode( 'handle_input_event_root', value='handle_input_event_root', ), OptionNode( 'Widget 1', value='Widget 1', ), OptionNode( 'Widget 2', value='Widget 2', ), OptionNode( 'Widget 3', value='Widget 3', ), OptionNode( 'handle_input_event', value='handle_input_event', ), events=[CHANGE], ), ), self.console, Button('Click Me'), BubblingWidget( self, 'Widget 1', BubblingWidget(self, 'Widget 2', BubblingWidget( self, 'Widget 3', )))) while True: input_event = self.await_input_event(html=html) self.print('>> view.handle_request {}'.format(repr(input_event)))
def handle_request(self, request): handle_request_button = Button( 'Crash in handle_request()', _id='handle_request', ) handle_input_event_button = Button( 'Crash in handle_input_event()', _id='handle_input_event', ) handle_input_event_button.hide() html = HTML( H2('Crashing Event Handler'), Div(), Button('Start refresh loop', _id='refresh-loop'), Button('Stop view', _id='stop-view'), Br(), Br(), handle_request_button, Button( 'Crash in handle_input_event_root()', _id='handle_input_event_root', ), handle_input_event_button, CrashWidget(), ) input_event = self.await_input_event(html=html) if input_event.node_has_id('handle_request'): raise ValueError('Success! Crash in handle_request()') handle_request_button.hide() handle_input_event_button.show() if input_event.node_has_id('stop-view'): return html if input_event.node_has_id('refresh-loop'): while True: html[1].set_text(str((datetime.now()))) self.show(html) self.sleep(1)
def handle_request(self, request): self.message = Div('Nothing clicked yet') self.html = HTML( H2('Class Based View'), self.message, Br(), Button('handle_input_event_root()', _id='handle_input_event_root'), Button('handle_input_event()', _id='handle_input_event'), Button('handle_request()', _id='handle_request'), Br(), Button('Stop View', _id='stop_view')) while True: input_event = self.await_click( self.html[-3], self.html[-1], html=self.html, ) if input_event.node == self.html[-1]: self.message.set_text('View Stopped') self.show(self.html) return self.message.set_text('handled by handle_request()')
def handle_request(self, request): try: html = HTML( H2('Async View'), Div(), Br(), Button('Sleep forever', _id='sleep-forever'), Button('Await short running coroutine', _id='await-short-running-coroutine'), Button('Await long running coroutine', _id='await-long-running-coroutine'), Button('Show HTML', _id='show-html'), Button('Crash', _id='crash'), ) input_event = self.await_input_event(html=html) if input_event.node_has_id('sleep-forever'): html[1].set_text('Sleeping forever') self.show(html) self.sleep(300) elif input_event.node_has_id('await-short-running-coroutine'): return_value = self.await_sync(short_running_coroutine()) html[1].set_text( 'short_running_coroutine() returned {}'.format( repr(return_value))) self.show(html) elif input_event.node_has_id('await-long-running-coroutine'): html[1].set_text('running long_running_coroutine()') self.show(html) self.await_sync(long_running_coroutine()) elif input_event.node_has_id('show-html'): self.await_sync(show_html(self)) return html finally: print('>> async view stopped')
def __init__(self, view, text, *nodes): self.text = text self.view = view self.nodes = [ Div( style={ 'padding': '0px 5px 5px 10px', 'border': '1px solid black', 'margin-top': '10px', }, nodes=[ P(text), Button('Click Me'), *nodes, ], ), ]
def handle_request(self, request): s = Strong() html = Div( H2('Redirect'), P('You will be HTTP redirected in ', s, ' seconds'), ) for i in [3, 2, 1]: s.set_text(str(i)) self.show(html) self.sleep(1) return { 'http_redirect': '/', }
def handle_request(self, request): request_data = { 'GET': request.GET, 'POST': request.POST, } message = Div() html = HTML( H2('Form View'), Pre(pformat(request_data)), Button('Interactive GET', _id='interactive-get'), Button('Interactive POST', _id='interactive-post'), Br(), Button('Non Interactive GET', _id='non-interactive-get'), Button('Non Interactive POST', _id='non-interactive-post'), ) input_event = self.await_click(html=html) action = '.' method = 'post' if (input_event.node_has_id('non-interactive-get') or input_event.node_has_id('interactive-get')): method = 'get' html = HTML( H2('Form View'), message, Form( TextInput(name='text'), Submit('Submit'), method=method, action=action, ), ) if (input_event.node_has_id('non-interactive-get') or input_event.node_has_id('non-interactive-post')): message.set_text('View stopped') return html else: message.set_text('View waits for input events') self.await_input_event(html=html)
def handle_request(self, request): pre = Pre( 'nothing changed', style={ 'background-color': 'lightgrey', } ) html = Div( H2('Change Events'), Div( Div( Div(CheckboxNode(events=[CHANGE])), Div(TextInputNode(value='Change me', events=[CHANGE])), style={ 'float': 'left', 'width': '50%', }, ), Div( pre, style={ 'float': 'left', 'width': '50%', }, ), ), ) self.show(html) while True: input_event = self.await_change(html=html) pre.set_text( 'changed node: {}\nvalue: {}'.format( input_event.node._id, pformat(input_event.data), ) )
def handle_request(self, request): check_box = CheckBox(bubble_up=True) text_input = TextInput(bubble_up=True) select = Select( values=[ ('', '---'), ('option-a', 'Option A', True), ('option-b', 'Option B', False), ], bubble_up=True, ) select_multiple = Select( values=[ ('option-a', 'Option A', True), ('option-b', 'Option B', False), ('option-c', 'Option C'), ], bubble_up=True, multiple=True, ) text_area = TextArea(bubble_up=True) pre = Pre( '{}', style={ 'background-color': 'lightgrey', }, ) html = HTML( H2('Databinding'), Div( Div( Div(check_box), Div(text_input), Div(select), Div(select_multiple), Div(text_area), style={ 'float': 'left', 'width': '50%', }, ), Div( pre, Button('Set texts', _id='set-texts'), Button('Daemonize', _id='daemonize'), Button('Stop', _id='stop'), style={ 'float': 'left', 'width': '50%', }, ), ), ) while True: input_event = self.await_input_event(html=html) if input_event.node_has_id('set-texts'): text_input.value = 'test' text_area.value = 'test' elif input_event.node_has_id('daemonize'): self.daemonize() elif input_event.node_has_id('stop'): return 'View Stopped' else: pre.set_text( pformat({ 'check_box': check_box.value, 'text_input': text_input.value, 'select': select.value, 'select_multiple': select_multiple.value, 'text_area': text_area.value, }))
def handle_request(self, request): self.topic = request.match_info.get('topic', '') # setup state self.state = None with request.server.state.lock: if 'multi-user-chat' not in request.server.state: request.server.state['multi-user-chat'] = {} if self.topic not in request.server.state['multi-user-chat']: request.server.state['multi-user-chat'][self.topic] = { 'user': [], 'messages': [], } self.state = request.server.state['multi-user-chat'][self.topic] # setup user list if self.request.user not in self.state['user']: self.state['user'].append(self.request.user) # setup history messages = self.state['messages'] self.history = Div() for message in messages: self.add_message_to_history(message, show=False) # setup html self.user_list = Div() self.text_area = TextArea() self.html = HTML(H1('Multi User Chat'), H2('Topic: {}'.format(self.topic or '(blank)')), self.user_list, Hr(), self.history, Hr(), self.text_area, Button('Send', _id='send')) for view_object in self.iter_objects(): if view_object.topic != self.topic: continue view_object.update_user_list() # main loop (waiting for messages) while True: self.show(self.html) self.await_click() message = ( str(self.request.user), self.text_area.value, ) with self.state.lock: self.state['messages'].append(message, ) for view_object in self.iter_objects(): if view_object.topic != self.topic: continue view_object.add_message_to_history(message)
def test_attribute_list(): from lona.html import Div # init #################################################################### # id d = Div() assert d.id_list == [] d = Div(_id=['foo', 'bar']) assert d.id_list == ['foo', 'bar'] d = Div(_id='foo bar') assert d.id_list == ['foo', 'bar'] d = Div(**{'id': 'foo bar'}) assert d.id_list == ['foo', 'bar'] # class d = Div() assert d.class_list == [] d = Div(_class=['foo', 'bar']) assert d.class_list == ['foo', 'bar'] d = Div(_class='foo bar') assert d.class_list == ['foo', 'bar'] d = Div(**{'class': 'foo bar'}) assert d.class_list == ['foo', 'bar'] # reset ################################################################### # id d = Div() d.id_list = ['foo', 'bar'] assert d.id_list == ['foo', 'bar'] # class d = Div() d.class_list = ['foo', 'bar'] assert d.class_list == ['foo', 'bar'] # value errors ############################################################ with pytest.raises(ValueError): d = Div(_id={}) with pytest.raises(ValueError): d.id_list = {} with pytest.raises(ValueError): d.id_list = [{}] # len ##################################################################### d = Div() assert len(d.id_list) == 0 d = Div(_id='foo bar') assert len(d.id_list) == 2 # comparisons ############################################################# d = Div(_id='foo bar') assert d.id_list != [] assert d.id_list != ['foo', 'bar', 'baz'] assert d.id_list == ['foo', 'bar'] assert d.id_list == ['bar', 'foo'] assert d.id_list == ['foo', 'bar', 'foo', 'bar'] assert 'foo' in d.id_list assert 'bar' in d.id_list assert 'baz' not in d.id_list d = Div(_id='foo') assert bool(d.id_list) d = Div() assert not bool(d.id_list) # add ##################################################################### d = Div() d.id_list.add('foo') assert d.id_list == ['foo'] d = Div() d.id_list.add('foo') d.id_list.add('foo') assert d.id_list == ['foo'] d = Div() with pytest.raises(ValueError): d.id_list.add({}) # extend ################################################################## d = Div(_id='foo') d.id_list.extend(['bar', 'baz']) assert d.id_list == ['foo', 'bar', 'baz'] d = Div(_id='foo') d.id_list.extend(['foo', 'bar', 'baz']) assert d.id_list == ['foo', 'bar', 'baz'] # remove ################################################################## d = Div(_id='foo bar') d.id_list.remove('foo') assert d.id_list == ['bar'] d.id_list.remove('foo') assert d.id_list == ['bar'] # clear ################################################################### d = Div(_id='foo bar') d.id_list.clear() assert d.id_list == [] d = Div() d.id_list.clear() assert d.id_list == [] # toggle ################################################################## d = Div(_id='foo bar') d.id_list.toggle('foo') assert d.id_list == ['bar'] d.id_list.toggle('foo') assert d.id_list == ['foo', 'bar']
def test_attribute_dict(): from lona.html import Div # init #################################################################### d = Div(foo='foo', bar='bar') assert d.attributes['foo'] == 'foo' assert d.attributes['bar'] == 'bar' # reset ################################################################### d = Div() d.attributes = { 'foo': 'foo', 'bar': 'bar', } assert d.attributes == { 'foo': 'foo', 'bar': 'bar', } # value errors ############################################################ with pytest.raises(ValueError): d = Div(foo={}) d = Div() with pytest.raises(RuntimeError): d.attributes['id'] = 'foo' # comparisons ############################################################# d = Div() assert not bool(d.attributes) d.attributes['foo'] = 'foo' assert bool(d.attributes)
def handle_request(self, request, name='blank'): message = Div('View not started yet') log = Div() start = Button('Start') start_daemonized = Button('Start daemonized') html = Div( H2('Daemonized View (name={})'.format(name)), message, log, start, start_daemonized, ) input_event = self.await_input_event(html=html) if input_event.node == start_daemonized: self.daemonize() message.set_text('View started daemonized') else: message.set_text('View started normal') for i in range(15): log.set_text('Counting ({}/15)'.format(i + 1)) self.show(html) self.sleep(1) message.set_text('View stopped') self.show(html)
def handle_request(self, request): colors = ['navy', 'maroon', 'green', 'teal', 'grey', 'purple', 'aqua'] style = { 'float': 'left', 'margin': '3px', 'width': '50px', 'height': '50px', 'cursor': 'pointer', 'background-color': colors[0], } pre = Pre( '{}', style={ 'background-color': 'lightgrey', }, ) html = Div( H2('Click Events'), Div( Div( Div( A('Link', href='/', events=[CLICK]), Br(), Br(), ), Div(style=style, events=[CLICK]), Div(style=style, events=[CLICK]), Div(style=style, events=[CLICK]), Div(style=style, events=[CLICK]), Div(style=style, events=[CLICK]), style={ 'float': 'left', 'width': '50%', }, ), Div( pre, style={ 'float': 'left', 'width': '50%', }, ), ), ) while True: input_event = self.await_click(html=html) data = { 'event_id': input_event.event_id, 'node': input_event.node._id, 'tag_name': input_event.node.tag_name, 'event_data': input_event.data } pre.set_text(pformat(data)) if input_event.node.tag_name == 'div': next_color = colors[ colors.index(input_event.node.style['background-color']) - 1] input_event.node.style['background-color'] = next_color