#!venv/bin/python
import os
import time
import urllib
import urllib2
import simplejson
import unicodedata
from tornado import httpserver, httpclient, ioloop, options, web, escape
from tornado.options import define, options as opt
define("port", default=8888, help="run on the given port", type=int)
class Application(web.Application):
def __init__(self):
handlers = [
(r"/", HomeHandler),
(r"/(.[0-9\.]+)", EntryHandler),
#(r"/(\d+)/(\d+)", CommentHandler),
]
settings = dict(
content_type_plain = 'text/plain',
content_type_json = 'text/plain',
couchdb_url = 'http://sevenov.ru:5984/restlog',
template_path=os.path.join(os.path.dirname(__file__), "templates"),
)
super(Application, self).__init__(handlers, **settings)
class Database(object):
def __init__(self, url):
self.client = httpclient.AsyncHTTPClient()
self.url = url
def view(self, design, callback, key=None, *args, **kwargs):
app_name, view_name = design.split('/', 1)
full_url = '%s/_design/%s/_view/%s%s' % (
self.url, app_name, view_name, key and '?key="%s"' % key or ''
)
self.client.fetch(full_url, callback, *args, **kwargs)
def post(self, callback, body):
self.client.fetch(self.url, callback, method="POST", body=body)
def put(self, doc_id, callback, body):
self.client.fetch(self.url + '/' + doc_id, callback, method="PUT", body=body)
def get(self, doc_id, callback):
self.client.fetch(self.url + '/' + doc_id, callback)
class BaseHandler(web.RequestHandler):
def __init__(self, *args, **kwargs):
super(BaseHandler, self).__init__(*args, **kwargs)
self.db = Database(self.settings.get('couchdb_url'))
def render_by_type(self, data):
if self.datatype == 'json':
return simplejson.dumps(data)
return self.render_string(self.template, **data)
class HomeHandler(BaseHandler):
template = 'entry_list.html'
@web.asynchronous
def get(self):
self.datatype = self.get_argument('type', 'text')
self.db.view('entry/new', self._get)
def _get(self, response):
self.set_header('Content-Type', 'text/plain; charset=UTF-8')
data = simplejson.loads(response.body)
data_entries = {'entries': [row['value'] for row in data['rows']]}
result = self.render_by_type(data_entries)
self.write(result)
self.finish()
@web.asynchronous
def put(self):
doc = dict(
type = u'entry',
author = 'Anonymous',
body = self.request.body
)
body = simplejson.dumps(doc)
self.db.put('%0.2f' % time.time(), self._put, body)
def _put(self, response):
data = simplejson.loads(response.body)
result = self.render_string("entry_created.html", data=data)
self.write(result)
self.finish()
class EntryHandler(BaseHandler):
template = 'entry.html'
@web.asynchronous
def get(self, entry_id):
self.datatype = self.get_argument('type', 'text')
self.db.view('entry/comments', self._get, key=entry_id)
def _get(self, response):
self.set_header('Content-Type', 'text/plain; charset=UTF-8')
data = simplejson.loads(response.body)
data_entry = {}
data_comments = []
for row in data['rows']:
value = row['value']
if value['type'] == 'entry':
data_entry = {
'_id': value['_id'],
'body': value['body'],
'author': value['author']}
elif value['type'] == 'comment':
comment = {'_id': value['_id'],
'body': value['body'],
'author': value['author']}
data_comments.append(comment)
data = {'entry': data_entry, 'comments': data_comments}
result = self.render_by_type(data)
self.write(result)
self.finish()
@web.asynchronous
def put(self, entry_id):
doc = dict(
type = u'comment',
author = 'Anonymous',
entry = entry_id,
body = self.request.body
)
body = simplejson.dumps(doc)
self.db.put('%0.2f' % time.time(), self._put, body)
def _put(self, response):
data = simplejson.loads(response.body)
result = self.render_string("comment_created.html", data=data)
self.write(result)
self.finish()
class CommentHandler(web.RequestHandler):
def get(self, entry_id, comment_id):
data = ["Comment:", '%s -> %s' % (entry_id, comment_id)]
self.finish('\n'.join(data))
def put(self, entry_id, comment_id):
data = ["Comment for %s" % comment_id, self.request.body]
self.finish('\n'.join(data))
def main():
options.parse_command_line()
http_server = httpserver.HTTPServer(Application())
http_server.listen(opt.port)
ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()