Refactoring sampler code into modules
This commit is contained in:
parent
161a0f3ea8
commit
5b0cfa1768
36
pydashie/dashie_sampler.py
Normal file
36
pydashie/dashie_sampler.py
Normal file
@ -0,0 +1,36 @@
|
||||
import datetime
|
||||
import json
|
||||
from repeated_timer import RepeatedTimer
|
||||
|
||||
class DashieSampler:
|
||||
def __init__(self, app, interval):
|
||||
self._app = app
|
||||
self._timer = RepeatedTimer(interval, self._sample)
|
||||
|
||||
def stop(self):
|
||||
self._timer.stop()
|
||||
|
||||
def name(self):
|
||||
'''
|
||||
Child class implements this function
|
||||
'''
|
||||
return 'UnknownSampler'
|
||||
|
||||
def sample(self):
|
||||
'''
|
||||
Child class implements this function
|
||||
'''
|
||||
return {}
|
||||
|
||||
def _send_event(self, widget_id, body):
|
||||
body['id'] = widget_id
|
||||
body['updateAt'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S +0000')
|
||||
formatted_json = 'data: %s\n\n' % (json.dumps(body))
|
||||
self._app.last_events[widget_id] = formatted_json
|
||||
for event_queue in self._app.events_queue.values():
|
||||
event_queue.put(formatted_json)
|
||||
|
||||
def _sample(self):
|
||||
data = self.sample()
|
||||
if data:
|
||||
self._send_event(self.name(), data)
|
163
pydashie/main.py
163
pydashie/main.py
@ -1,54 +1,50 @@
|
||||
import os
|
||||
import json
|
||||
import Queue
|
||||
import random
|
||||
import logging
|
||||
import datetime
|
||||
import collections
|
||||
import coffeescript
|
||||
import SocketServer
|
||||
from repeated_timer import RepeatedTimer
|
||||
from flask import Flask, render_template, Response, send_from_directory, request, current_app
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
events_queue = {}
|
||||
items = collections.deque()
|
||||
last_events = {}
|
||||
seedX = 0
|
||||
|
||||
@app.route("/")
|
||||
def main():
|
||||
return render_template('main.html', title='pyDashie')
|
||||
|
||||
@app.route("/assets/application.js")
|
||||
def javascripts():
|
||||
# scripts = [
|
||||
# 'assets/javascripts/jquery.js',
|
||||
# 'assets/javascripts/es5-shim.js',
|
||||
# 'assets/javascripts/d3.v2.min.js',
|
||||
# 'assets/javascripts/batman.js',
|
||||
# 'assets/javascripts/batman.jquery.js',
|
||||
# 'assets/javascripts/jquery.gridster.js',
|
||||
# 'assets/javascripts/jquery.leanModal.min.js',
|
||||
# 'assets/javascripts/dashing.coffee',
|
||||
# 'assets/javascripts/jquery.knob.js',
|
||||
# 'assets/javascripts/rickshaw.min.js',
|
||||
# 'assets/javascripts/application.coffee',
|
||||
# 'assets/javascripts/dashing.gridster.coffee'
|
||||
# ]
|
||||
scripts = ['assets/javascripts/application.js']
|
||||
if not hasattr(current_app, 'javascripts'):
|
||||
import coffeescript
|
||||
scripts = [
|
||||
'assets/javascripts/jquery.js',
|
||||
'assets/javascripts/es5-shim.js',
|
||||
'assets/javascripts/d3.v2.min.js',
|
||||
'assets/javascripts/batman.js',
|
||||
'assets/javascripts/batman.jquery.js',
|
||||
'assets/javascripts/jquery.gridster.js',
|
||||
'assets/javascripts/jquery.leanModal.min.js',
|
||||
'assets/javascripts/dashing.coffee',
|
||||
'assets/javascripts/jquery.knob.js',
|
||||
'assets/javascripts/rickshaw.min.js',
|
||||
'assets/javascripts/application.coffee',
|
||||
'assets/javascripts/dashing.gridster.coffee'
|
||||
]
|
||||
scripts = ['assets/javascripts/application.js']
|
||||
|
||||
base_directory = os.getcwd()
|
||||
full_paths = [os.path.join(base_directory, script_name) for script_name in scripts]
|
||||
output = ''
|
||||
for path in full_paths:
|
||||
if '.coffee' in path:
|
||||
print('Compiling Coffee on %s ' % path)
|
||||
output = output + coffeescript.compile(open(path).read())
|
||||
else:
|
||||
output = output + open(path).read()
|
||||
return Response(output, mimetype='application/javascript')
|
||||
base_directory = os.getcwd()
|
||||
full_paths = [os.path.join(base_directory, script_name) for script_name in scripts]
|
||||
output = []
|
||||
for path in full_paths:
|
||||
print path
|
||||
if '.coffee' in path:
|
||||
print('Compiling Coffee for %s ' % path)
|
||||
contents = coffeescript.compile_file(path)
|
||||
else:
|
||||
f = open(path)
|
||||
contents = f.read()
|
||||
f.close()
|
||||
|
||||
output.append(contents)
|
||||
|
||||
current_app.javascripts = ''.join(output)
|
||||
|
||||
return Response(current_app.javascripts, mimetype='application/javascript')
|
||||
|
||||
@app.route('/assets/application.css')
|
||||
def application_css():
|
||||
@ -73,18 +69,28 @@ def widget_html(widget_name):
|
||||
path = os.path.join(base_directory, 'widgets', widget_name, '%s.html' % widget_name)
|
||||
return open(path).read()
|
||||
|
||||
import Queue
|
||||
|
||||
class Z:
|
||||
pass
|
||||
xyzzy = Z()
|
||||
xyzzy.events_queue = {}
|
||||
xyzzy.last_events = {}
|
||||
|
||||
@app.route('/events')
|
||||
def events():
|
||||
event_stream_port = request.environ['REMOTE_PORT']
|
||||
current_event_queue = Queue.Queue()
|
||||
events_queue[event_stream_port] = current_event_queue
|
||||
current_app.logger.info('New Client %s connected. Total Clients: %s' % (event_stream_port, len(events_queue)))
|
||||
xyzzy.events_queue[event_stream_port] = current_event_queue
|
||||
current_app.logger.info('New Client %s connected. Total Clients: %s' % (event_stream_port, len(xyzzy.events_queue)))
|
||||
|
||||
#Start the newly connected client off by pushing the current last events
|
||||
for event in last_events.values():
|
||||
print 'Pushed %s' % event
|
||||
for event in xyzzy.last_events.values():
|
||||
#print 'Pushed %s' % event
|
||||
current_event_queue.put(event)
|
||||
return Response(pop_queue(current_event_queue), mimetype='text/event-stream')
|
||||
#return Response(pop_queue(current_event_queue), mimetype='text/event-stream')
|
||||
|
||||
return Response(xyzzy.last_events.values(), mimetype='text/event-stream')
|
||||
|
||||
def pop_queue(current_event_queue):
|
||||
while True:
|
||||
@ -92,60 +98,37 @@ def pop_queue(current_event_queue):
|
||||
print 'Popping data %s' % data
|
||||
yield data
|
||||
|
||||
def send_event(widget_id, body):
|
||||
body['id'] = widget_id
|
||||
body['updateAt'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S +0000')
|
||||
formatted_json = 'data: %s\n\n' % (json.dumps(body))
|
||||
last_events[widget_id] = formatted_json
|
||||
for event_queue in events_queue.values():
|
||||
event_queue.put(formatted_json)
|
||||
|
||||
def sample_synergy():
|
||||
synergy_data = {'value': random.randint(0, 100)}
|
||||
send_event('synergy', synergy_data)
|
||||
|
||||
def sample_buzzwords():
|
||||
my_little_pony_names = ['Rainbow Dash',
|
||||
'Blossomforth',
|
||||
'Derpy',
|
||||
'Fluttershy',
|
||||
'Lofty',
|
||||
'Scootaloo',
|
||||
'Skydancer']
|
||||
items = [{'label': pony_name, 'value': random.randint(0, 20)} for pony_name in my_little_pony_names]
|
||||
buzzwords_data = {'items':items}
|
||||
send_event('buzzwords', buzzwords_data)
|
||||
|
||||
def sample_convergence():
|
||||
global seedX
|
||||
if not seedX:
|
||||
seedX = 0
|
||||
items.append({'x':seedX,
|
||||
'y':random.randint(0,20)})
|
||||
seedX += 1
|
||||
if len(items) > 10:
|
||||
items.popleft()
|
||||
item_data = {'points': list(items)}
|
||||
send_event('convergence', item_data)
|
||||
|
||||
def close_stream(*args, **kwargs):
|
||||
print 'close_stream'
|
||||
event_stream_port = args[2][1]
|
||||
del events_queue[event_stream_port]
|
||||
print('Client %s disconnected. Total Clients: %s' % (event_stream_port, len(events_queue)))
|
||||
|
||||
if __name__ == "__main__":
|
||||
def test_app():
|
||||
import SocketServer
|
||||
SocketServer.BaseServer.handle_error = close_stream
|
||||
|
||||
refreshJobs = [
|
||||
(sample_synergy, 1,),
|
||||
(sample_buzzwords, 30,),
|
||||
(sample_convergence, 1,),
|
||||
import test_samplers
|
||||
|
||||
samplers = [
|
||||
test_samplers.SynergySampler(xyzzy, 3),
|
||||
test_samplers.BuzzwordsSampler(xyzzy, 2), # 10
|
||||
test_samplers.ConvergenceSampler(xyzzy, 1),
|
||||
]
|
||||
|
||||
timers = [RepeatedTimer(time, function) for function, time in refreshJobs]
|
||||
|
||||
try:
|
||||
app.run(debug=True, port=5000, threaded=True, use_reloader=False, use_debugger=True)
|
||||
app.run(debug=True,
|
||||
port=5000,
|
||||
threaded=True,
|
||||
use_reloader=False,
|
||||
use_debugger=True
|
||||
)
|
||||
finally:
|
||||
for timer in timers:
|
||||
timer.stop()
|
||||
print "Stopping %d timers" % len(samplers)
|
||||
for (i, sampler) in enumerate(samplers):
|
||||
sampler.stop()
|
||||
|
||||
print "Done"
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_app()
|
||||
|
@ -28,6 +28,14 @@
|
||||
<div data-id="synergy" data-view="Meter" data-title="Synergy" data-min="0" data-max="100"></div>
|
||||
</li>
|
||||
|
||||
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
|
||||
<div data-id="clock" data-view="Clock" data-title="Clock"></div>
|
||||
</li>
|
||||
|
||||
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
|
||||
<div data-id="comments" data-view="comments" data-title="Comments"></div>
|
||||
</li>
|
||||
|
||||
<li data-row="1" data-col="1" data-sizex="1" data-sizey="2">
|
||||
<div data-id="buzzwords" data-view="List" data-unordered="true" data-title="Buzzwords" data-moreinfo="Absolute ranking of pony preferences"></div>
|
||||
</li>
|
||||
@ -42,4 +50,4 @@
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
44
pydashie/test_samplers.py
Normal file
44
pydashie/test_samplers.py
Normal file
@ -0,0 +1,44 @@
|
||||
from dashie_sampler import DashieSampler
|
||||
|
||||
import random
|
||||
import collections
|
||||
|
||||
class SynergySampler(DashieSampler):
|
||||
def name(self):
|
||||
return 'synergy'
|
||||
|
||||
def sample(self):
|
||||
return {'value': random.randint(0, 100)}
|
||||
|
||||
class BuzzwordsSampler(DashieSampler):
|
||||
def name(self):
|
||||
return 'buzzwords'
|
||||
|
||||
def sample(self):
|
||||
my_little_pony_names = ['Rainbow Dash',
|
||||
'Blossomforth',
|
||||
'Derpy',
|
||||
'Fluttershy',
|
||||
'Lofty',
|
||||
'Scootaloo',
|
||||
'Skydancer']
|
||||
items = [{'label': pony_name, 'value': random.randint(0, 20)} for pony_name in my_little_pony_names]
|
||||
random.shuffle(items)
|
||||
return {'items':items}
|
||||
|
||||
class ConvergenceSampler(DashieSampler):
|
||||
def name(self):
|
||||
return 'convergence'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.seedX = 0
|
||||
self.items = collections.deque()
|
||||
DashieSampler.__init__(self, *args, **kwargs)
|
||||
|
||||
def sample(self):
|
||||
self.items.append({'x': self.seedX,
|
||||
'y': random.randint(0,20)})
|
||||
self.seedX += 1
|
||||
if len(self.items) > 10:
|
||||
self.items.popleft()
|
||||
return {'points': list(self.items)}
|
@ -6,7 +6,7 @@ class Dashing.Clock extends Dashing.Widget
|
||||
startTime: =>
|
||||
today = new Date()
|
||||
|
||||
h = today.getHours()
|
||||
h = (today.getHours() % 13) + 1
|
||||
m = today.getMinutes()
|
||||
s = today.getSeconds()
|
||||
m = @formatTime(m)
|
||||
@ -15,4 +15,4 @@ class Dashing.Clock extends Dashing.Widget
|
||||
@set('date', today.toDateString())
|
||||
|
||||
formatTime: (i) ->
|
||||
if i < 10 then "0" + i else i
|
||||
if i < 10 then "z0" + i else i
|
||||
|
@ -15,4 +15,4 @@
|
||||
</ul>
|
||||
|
||||
<p class="more-info" data-bind="moreinfo"></p>
|
||||
<p class="updated-at" data-bind="updatedAtMessage"></p>
|
||||
<p class="updated-at" data-bind="updatedAtMessage"></p>
|
||||
|
Loading…
x
Reference in New Issue
Block a user