serve covers with tornado
This commit is contained in:
parent
040bdd1b03
commit
b690aabe1b
3 changed files with 59 additions and 32 deletions
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
Loading…
Reference in a new issue