serve covers with tornado

This commit is contained in:
j 2014-05-19 23:39:52 +02:00
parent 040bdd1b03
commit b690aabe1b
3 changed files with 59 additions and 32 deletions

View file

@ -1,10 +1,20 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4 # vi:si:et:sw=4:sts=4:ts=4
from __future__ import division from __future__ import division, with_statement
import sqlite3 import sqlite3
import Image
from StringIO import StringIO from StringIO import StringIO
import Image
import tornado.ioloop
import tornado.web
import tornado.gen
import tornado.concurrent
from oxtornado import run_async
from utils import resize_image
from settings import covers_db_path from settings import covers_db_path
@ -75,3 +85,48 @@ class Covers(dict):
conn.close() conn.close()
covers = Covers(covers_db_path) covers = Covers(covers_db_path)
@run_async
def get_cover(app, id, size, callback):
with app.app_context():
from item.models import Item
item = Item.get(id)
if not item:
callback('')
data = None
if size:
data = covers['%s:%s' % (id, size)]
if data:
size = None
if not data:
data = covers[id]
if not data:
data = item.update_cover()
if not data:
data = covers.black()
if size:
data = covers['%s:%s' % (id, size)] = resize_image(data, size=size)
data = str(data)
if not 'coverRatio' in item.info:
img = Image.open(StringIO(data))
item.info['coverRatio'] = img.size[0]/img.size[1]
item.save()
callback(data)
class CoverHandler(tornado.web.RequestHandler):
def initialize(self, app):
self._app = app
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self, id, size=None):
size = int(size) if size else None
response = yield tornado.gen.Task(get_cover, self._app, id, size)
if not response:
self.set_status(404)
self.write('')
else:
self.set_header('Content-Type', 'image/jpeg')
self.write(response)
self.finish()

View file

@ -53,36 +53,6 @@ def get(id):
}.get(path.split('.')[-1], None) }.get(path.split('.')[-1], None)
return send_file(path, mimetype=mimetype) return send_file(path, mimetype=mimetype)
@app.route('/<string:id>/cover.jpg')
@app.route('/<string:id>/cover<int:size>.jpg')
def cover(id, size=None):
item = Item.get(id)
if not item:
abort(404)
data = None
if size:
data = covers['%s:%s' % (id, size)]
if data:
size = None
if not data:
data = covers[id]
if not data:
data = item.update_cover()
if not data:
data = covers.black()
if size:
data = covers['%s:%s' % (id, size)] = resize_image(data, size=size)
data = str(data)
if not 'coverRatio' in item.info:
#img = Image.open(StringIO(str(covers[id])))
img = Image.open(StringIO(data))
item.info['coverRatio'] = img.size[0]/img.size[1]
db.session.add(item)
db.session.commit()
resp = make_response(data)
resp.content_type = "image/jpeg"
return resp
@app.route('/<string:id>/reader/') @app.route('/<string:id>/reader/')
def reader(id, filename=''): def reader(id, filename=''):
item = Item.get(id) item = Item.get(id)

View file

@ -15,6 +15,7 @@ import websocket
import state import state
import node.server import node.server
import oxtornado import oxtornado
from item.covers import CoverHandler
def run(): def run():
root_dir = os.path.normpath(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')) root_dir = os.path.normpath(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..'))
@ -31,6 +32,7 @@ def run():
handlers = [ handlers = [
(r'/(favicon.ico)', StaticFileHandler, {'path': static_path}), (r'/(favicon.ico)', StaticFileHandler, {'path': static_path}),
(r'/static/(.*)', StaticFileHandler, {'path': static_path}), (r'/static/(.*)', StaticFileHandler, {'path': static_path}),
(r'/(.*)/cover(\d*).jpg', CoverHandler, dict(app=app)),
(r'/api/', oxtornado.ApiHandler, dict(app=app)), (r'/api/', oxtornado.ApiHandler, dict(app=app)),
(r'/ws', websocket.Handler), (r'/ws', websocket.Handler),
(r".*", FallbackHandler, dict(fallback=tr)), (r".*", FallbackHandler, dict(fallback=tr)),