Refactoring sampler code into modules

This commit is contained in:
Payton Quackenbush 2013-06-23 20:03:44 -05:00
parent 161a0f3ea8
commit 5b0cfa1768
6 changed files with 165 additions and 94 deletions

View 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)

View File

@ -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()

View File

@ -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
View 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)}

View File

@ -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

View File

@ -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>