Port to tornado

This commit is contained in:
Florian Mounier
2014-01-14 12:11:43 +01:00
parent 910046f81c
commit e1cb6ae064
12 changed files with 173 additions and 139 deletions

View File

@@ -1,4 +1,33 @@
from flask import Flask
app = Flask(__name__)
import os
import tornado.web
import tornado.options
import tornado.web
from . import routes
application = tornado.web.Application(
debug=tornado.options.options.debug,
cookie_secret=tornado.options.options.secret,
static_path=os.path.join(os.path.dirname(__file__), "static"),
template_path=os.path.join(os.path.dirname(__file__), "templates")
)
class url(object):
def __init__(self, url):
self.url = url
def __call__(self, cls):
application.add_handlers(
r'.*$',
(tornado.web.url(self.url, cls, name=cls.__name__),)
)
return cls
class Route(tornado.web.RequestHandler):
@property
def log(self):
return log
import app.routes

View File

@@ -1,7 +1,22 @@
from . import app
from flask import render_template
import tornado.websocket
from app import url, Route
@url(r'/')
class Index(Route):
def get(self):
return self.render('index.html')
@url(r'/ws')
class EchoWebSocket(Route, tornado.websocket.WebSocketHandler):
def open(self):
log.info('Websocket opened')
def on_message(self, message):
self.write_message(message)
def on_close(self):
log.info('Websocket closed')
@app.route("/")
def index():
return render_template('index.jinja2')

91
app/templates/_base.html Normal file
View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="{{ static_url('images/favicon.png') }}">
{% include "_ie.html" %}
<title>Apparatus</title>
<link href="{{ static_url('stylesheets/bootstrap/bootstrap.css') }}" rel="stylesheet">
<link href="{{ static_url('stylesheets/main.css') }}" rel="stylesheet">
</head>
<body>
{% include "_nav.html" %}
<section id="myCarousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
{% for i in range(3) %}
<article class="item{{ ' active' if i == 0 else '' }}">
<div class="container">
<div class="carousel-caption">
<h1>Title</h1>
<p>Venenatis nullam purus fusce sed et, pellentesque dolor venenatis at donec. Pretium quam, rhoncus sed tempus dictum. Neque ut tincidunt vestibulum vel et, inceptos vestibulum blandit, pellentesque praesent sit. Posuere in praesent, volutpat accumsan felis ut veritatis metus, leo amet purus pede semper in ornare. Convallis sollicitudin at dapibus, phasellus eros felis aliquet nulla amet, in in et tristique enim. Justo gravida nulla rhoncus, faucibus est in lacus sollicitudin fringilla sed, aliquet eu magna morbi lectus nulla pede. Mi pellentesque dictumst nam suspendisse vero. Metus ut elit mauris sollicitudin elit, malesuada semper pede elementum. Id aliquet magna consequat nulla, erat amet et pharetra lacinia quisque vitae. Suspendisse luctus, in malesuada pellentesque, porta dui orci dui eget lorem. </p>
<p>
<a class="btn btn-lg btn-primary" href="#" role="button">Okay</a>
</p>
</div>
</div>
</article>
{% end %}
</div>
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</section>
<section class="container">
<article class="row">
{% for i in range(3) %}
<div class="col-lg-4">
<h2>Title</h2>
<p>Lorem ipsum dolor sit amet, aliquet porttitor tortor mattis nec mauris, duis nunc accumsan vel. Eget neque suspendisse nonummy turpis, tempus urna cum vestibulum lectus. Ut elit lectus neque, elementum nulla curabitur faucibus, qui augue cubilia. Neque erat nullam ullamco massa habitasse dolor, erat at sed donec vulputate sodales. Et elementum arcu vel blandit ultrices, eu quam, eget nunc ultricies quam tincidunt aenean. Et sem massa ac, egestas justo tempus nam nulla ac mauris, est neque maecenas imperdiet per ipsum. A beatae neque et incidunt mollis ipsum. Nulla lorem. Ullamcorper quisque commodo elit a elementum, suscipit etiam faucibus ante, suspendisse aliquet sed non, nec tellus mauris. Purus urna euismod, viverra etiam dis elit, phasellus quam wisi posuere lorem porttitor, pulvinar consequat nec eu fringilla malesuada. Nec leo dignissim lacus egestas nunc, lorem magna, sodales laoreet dignissim. A facilisis, quisque tristique lorem, gravida risus etiam, in lacinia, congue et nunc at.</p>
<p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
</div>
{% end %}
</article>
<hr class="featurette-divider">
{% for i in range(3) %}
<article class="row featurette">
{% if i % 2 %}
<div class="col-md-5">
<img src="http://lorempixel.com/g/400/400#{{ i }}" />
</div>
{% end %}
<div class="col-md-7">
<h2 class="featurette-heading">Title <span class="text-muted">Subtitle</span></h2>
<p class="lead">Lead</p>
</div>
{% if i % 2 == 0 %}
<div class="col-md-5">
<img src="http://lorempixel.com/g/400/400#{{ i }}" />
</div>
{% end %}
<hr class="featurette-divider">
</article>
{% end %}
<footer>
<p class="pull-right"><a href="#">Back to top</a></p>
<p>&copy; 2013 Company, Inc. &middot; <a href="#">Privacy</a> &middot; <a href="#">Terms</a></p>
</footer>
</section>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="{{ static_url('javascripts/bootstrap.min.js') }}"></script>
<script src="{{ static_url('javascripts/main.js') }}"></script>
</body>
</html>

View File

@@ -1,93 +0,0 @@
{%- from "_utils.jinja2" import static -%}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="{{ static('images/favicon.png') }}">
{%- include "_ie.jinja2" -%}
<title>Apparatus</title>
<link href="{{ static('stylesheets/bootstrap/bootstrap.css') }}" rel="stylesheet">
<link href="{{ static('stylesheets/main.css') }}" rel="stylesheet">
</head>
<body>
{%- include "_nav.jinja2" -%}
<section id="myCarousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
{% for i in range(3) %}
<article class="item{{ ' active' if i == 0}}">
<div class="container">
<div class="carousel-caption">
<h1>{{ lipsum(1, html=False, max=30) }}</h1>
{{ lipsum(1, max=40) }}
<p>
<a class="btn btn-lg btn-primary" href="#" role="button">{{ lipsum(1, html=False, min=1, max=3) }}</a>
</p>
</div>
</div>
</article>
{% endfor %}
</div>
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</section>
<section class="container">
<article class="row">
{% for i in range(3) %}
<div class="col-lg-4">
<h2>{{ lipsum(1, html=False, min=5, max=10) }}</h2>
{{ lipsum(1, max=40) }}
<p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
</div>
{% endfor %}
</article>
<hr class="featurette-divider">
{% macro item(i) %}
{% if i % 2 %}
<div class="col-md-5">
<img src="http://lorempixel.com/g/400/400#{{ i }}" />
</div>
{% else %}
<div class="col-md-7">
<h2 class="featurette-heading">{{ lipsum(1, html=False, min=3, max=6) }}<span class="text-muted">{{ lipsum(1, html=False, min=3, max=6) }}</span></h2>
<p class="lead">{{ lipsum(1, html=False, max=50) }}</p>
</div>
{% endif %}
{% endmacro %}
{% for i in range(3) %}
<article class="row featurette">
{{ item(i) }}
{{ item(i + 11) }}
<hr class="featurette-divider">
</article>
{% endfor %}
<footer>
<p class="pull-right"><a href="#">Back to top</a></p>
<p>&copy; 2013 Company, Inc. &middot; <a href="#">Privacy</a> &middot; <a href="#">Terms</a></p>
</footer>
</section>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="{{ static('javascripts/bootstrap.min.js') }}"></script>
<script src="{{ static('javascripts/main.js') }}"></script>
</body>
</html>

View File

@@ -1,3 +0,0 @@
{% macro static(fn) %}
{{ url_for('static', filename=fn) }}
{% endmacro %}

1
app/templates/index.html Normal file
View File

@@ -0,0 +1 @@
{% extends "_base.html" %}

View File

@@ -1 +0,0 @@
{%- extends "_base.jinja2" -%}

View File

@@ -1,5 +1,4 @@
wdb
log_colorizer
wsreload
cutter
pytest

View File

@@ -1 +1 @@
flask
tornado

View File

@@ -1,53 +1,49 @@
#!/usr/bin/env python
host = 'apparatus.l'
port = 2001
url = "http://%s:%d/*" % (host, port)
from log_colorizer import colorize
colorize()
try:
from wdb.ext import add_w_builtin
add_w_builtin()
except ImportError:
pass
import logging
from app import app
app.logger.setLevel(logging.DEBUG)
import tornado.options
import tornado.ioloop
del app.logger.handlers[:]
tornado.options.define("secret", default='secret', help="Secret")
tornado.options.define("debug", default=True, help="Debug mode")
tornado.options.define("host", default='apparatus.l', help="Server host")
tornado.options.define("port", default=2001, type=int, help="Server port")
logging.getLogger('werkzeug').setLevel(logging.DEBUG)
host = 'apparatus.l'
tornado.options.parse_command_line()
werkzeug_debugger = True
try:
from wdb.ext import WdbMiddleware
except ImportError:
app.logger.debug('wdb not found')
else:
app.wsgi_app = WdbMiddleware(app.wsgi_app, start_disabled=True)
werkzeug_debugger = False
from logging import getLogger
log = getLogger('apparatus')
log.setLevel(10 if tornado.options.options.debug else 30)
log.debug('Starting server')
ioloop = tornado.ioloop.IOLoop.instance()
from app import application
application.listen(tornado.options.options.port)
url = "http://%s:%d/*" % (
tornado.options.options.host, tornado.options.options.port)
try:
from wsreload.client import monkey_patch_http_server, watch
from wsreload.client import sporadic_reload, watch
except ImportError:
app.logger.debug('wsreload not found')
log.debug('wsreload not found')
else:
def log(httpserver):
app.logger.debug('WSReloaded after server restart')
monkey_patch_http_server({'url': url}, callback=log)
app.logger.debug('HTTPServer monkey patched for url %s' % url)
sporadic_reload({'url': url})
files = ['app/static/javascripts/',
'app/static/stylesheets/',
'app/templates/']
watch({'url': url}, files, unwatch_at_exit=True)
app.run(
debug=True,
host=host,
port=port,
use_debugger=werkzeug_debugger,
threaded=True)
log.debug('Starting loop')
ioloop.start()