fix lists, handle async requests
This commit is contained in:
parent
39ea0437df
commit
d451eb3063
9 changed files with 25 additions and 30 deletions
|
@ -98,6 +98,11 @@ class PostUpdate(Command):
|
||||||
changed = True
|
changed = True
|
||||||
if changed:
|
if changed:
|
||||||
f.save()
|
f.save()
|
||||||
|
if old <= '20140526-117-39ea043' and new > '20140526-117-39ea043':
|
||||||
|
import item.models
|
||||||
|
for i in item.models.Item.query:
|
||||||
|
i.update_lists()
|
||||||
|
item.models.db.session.commit()
|
||||||
|
|
||||||
class Setup(Command):
|
class Setup(Command):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -87,11 +87,15 @@ def find(data):
|
||||||
j = i.json()
|
j = i.json()
|
||||||
response['items'].append({k:j[k] for k in j if not data['keys'] or k in data['keys']})
|
response['items'].append({k:j[k] for k in j if not data['keys'] or k in data['keys']})
|
||||||
else:
|
else:
|
||||||
response['items'] = q['qs'].count()
|
key = 'stats:' + hashlib.sha1(json.dumps(data)).hexdigest()
|
||||||
#from sqlalchemy.sql import func
|
stats = state.cache.get(key)
|
||||||
#models.db.session.query(func.sum(models.Item.sort_size).label("size"))
|
if stats is None:
|
||||||
#response['size'] = x.scalar()
|
stats = {}
|
||||||
response['size'] = sum([i.info.get('size', 0) for i in q['qs'].join(models.Sort).options(load_only('id', 'info'))])
|
size = [i.info.get('size', 0) for i in q['qs'].join(models.Sort).options(load_only('id', 'info'))]
|
||||||
|
stats['items'] = len(size)
|
||||||
|
stats['size'] = sum(size)
|
||||||
|
state.cache.set(key, stats, ttl=60)
|
||||||
|
response = stats
|
||||||
return response
|
return response
|
||||||
actions.register(find)
|
actions.register(find)
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ class EpubHandler(OMLHandler):
|
||||||
}.get(filename.split('.')[0], mimetypes.guess_type(filename)[0]) or 'text/plain'
|
}.get(filename.split('.')[0], mimetypes.guess_type(filename)[0]) or 'text/plain'
|
||||||
self.set_header('Content-Type', content_type)
|
self.set_header('Content-Type', content_type)
|
||||||
self.write(z.read(filename))
|
self.write(z.read(filename))
|
||||||
self.finish()
|
|
||||||
|
|
||||||
def serve_static(handler, path, mimetype, include_body=True):
|
def serve_static(handler, path, mimetype, include_body=True):
|
||||||
#fixme use static file handler / serve ranges
|
#fixme use static file handler / serve ranges
|
||||||
|
@ -47,7 +46,6 @@ def serve_static(handler, path, mimetype, include_body=True):
|
||||||
if include_body:
|
if include_body:
|
||||||
with open(path) as fd:
|
with open(path) as fd:
|
||||||
handler.write(fd.read())
|
handler.write(fd.read())
|
||||||
handler.finish()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
class FileHandler(OMLHandler):
|
class FileHandler(OMLHandler):
|
||||||
|
@ -61,7 +59,6 @@ class FileHandler(OMLHandler):
|
||||||
path = item.get_path() if item else None
|
path = item.get_path() if item else None
|
||||||
if not item or not path:
|
if not item or not path:
|
||||||
self.set_status(404)
|
self.set_status(404)
|
||||||
self.finish()
|
|
||||||
return
|
return
|
||||||
mimetype={
|
mimetype={
|
||||||
'epub': 'application/epub+zip',
|
'epub': 'application/epub+zip',
|
||||||
|
@ -77,7 +74,6 @@ class ReaderHandler(OMLHandler):
|
||||||
item = Item.get(id)
|
item = Item.get(id)
|
||||||
if not item:
|
if not item:
|
||||||
self.set_status(404)
|
self.set_status(404)
|
||||||
self.finish()
|
|
||||||
return
|
return
|
||||||
if item.info['extension'] == 'epub':
|
if item.info['extension'] == 'epub':
|
||||||
html = 'html/epub.html'
|
html = 'html/epub.html'
|
||||||
|
@ -87,7 +83,6 @@ class ReaderHandler(OMLHandler):
|
||||||
html = 'html/txt.html'
|
html = 'html/txt.html'
|
||||||
else:
|
else:
|
||||||
self.set_status(404)
|
self.set_status(404)
|
||||||
self.finish()
|
|
||||||
return
|
return
|
||||||
item.accessed = datetime.utcnow()
|
item.accessed = datetime.utcnow()
|
||||||
item.timesaccessed = (item.timesaccessed or 0) + 1
|
item.timesaccessed = (item.timesaccessed or 0) + 1
|
||||||
|
|
|
@ -160,7 +160,6 @@ class IconHandler(tornado.web.RequestHandler):
|
||||||
|
|
||||||
if type_ not in ('cover', 'preview'):
|
if type_ not in ('cover', 'preview'):
|
||||||
self.set_status(404)
|
self.set_status(404)
|
||||||
self.finish()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
self.set_header('Content-Type', 'image/jpeg')
|
self.set_header('Content-Type', 'image/jpeg')
|
||||||
|
@ -168,7 +167,6 @@ class IconHandler(tornado.web.RequestHandler):
|
||||||
response = yield tornado.gen.Task(get_icon, self._app, id, type_, size)
|
response = yield tornado.gen.Task(get_icon, self._app, id, type_, size)
|
||||||
if not response:
|
if not response:
|
||||||
self.set_status(404)
|
self.set_status(404)
|
||||||
self.finish()
|
|
||||||
return
|
return
|
||||||
if self._finished:
|
if self._finished:
|
||||||
return
|
return
|
||||||
|
|
|
@ -192,15 +192,15 @@ class Item(db.Model):
|
||||||
f.item_id = self.id
|
f.item_id = self.id
|
||||||
f.key = 'list'
|
f.key = 'list'
|
||||||
if p.id == settings.USER_ID:
|
if p.id == settings.USER_ID:
|
||||||
f.value = ':'
|
f.findvalue = f.value = ':'
|
||||||
else:
|
else:
|
||||||
f.value = '%s:' % p.id
|
f.findvalue = f.value = '%s:' % p.id
|
||||||
db.session.add(f)
|
db.session.add(f)
|
||||||
for l in self.lists:
|
for l in self.lists:
|
||||||
f = Find()
|
f = Find()
|
||||||
f.item_id = self.id
|
f.item_id = self.id
|
||||||
f.key = 'list'
|
f.key = 'list'
|
||||||
f.value = l.find_id
|
f.findvalue = f.value = l.find_id
|
||||||
db.session.add(f)
|
db.session.add(f)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
|
|
@ -72,14 +72,12 @@ class NodeHandler(tornado.web.RequestHandler):
|
||||||
self.set_header('X-Ed25519-Signature', sig)
|
self.set_header('X-Ed25519-Signature', sig)
|
||||||
self.set_header('X-Node-Protocol', settings.NODE_PROTOCOL)
|
self.set_header('X-Node-Protocol', settings.NODE_PROTOCOL)
|
||||||
self.write(content)
|
self.write(content)
|
||||||
self.finish()
|
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
self.set_header('X-Node-Protocol', settings.NODE_PROTOCOL)
|
self.set_header('X-Node-Protocol', settings.NODE_PROTOCOL)
|
||||||
if self.request.headers.get('X-Node-Protocol', None) > settings.NODE_PROTOCOL:
|
if self.request.headers.get('X-Node-Protocol', None) > settings.NODE_PROTOCOL:
|
||||||
state.update_required = True
|
state.update_required = True
|
||||||
self.write('Open Media Library')
|
self.write('Open Media Library')
|
||||||
self.finish()
|
|
||||||
|
|
||||||
@run_async
|
@run_async
|
||||||
def api_call(app, action, key, args, callback):
|
def api_call(app, action, key, args, callback):
|
||||||
|
@ -108,7 +106,7 @@ class ShareHandler(tornado.web.RequestHandler):
|
||||||
i = item.models.Item.get(id)
|
i = item.models.Item.get(id)
|
||||||
if not i:
|
if not i:
|
||||||
self.set_status(404)
|
self.set_status(404)
|
||||||
self.finish()
|
return
|
||||||
path = i.get_path()
|
path = i.get_path()
|
||||||
mimetype = {
|
mimetype = {
|
||||||
'epub': 'application/epub+zip',
|
'epub': 'application/epub+zip',
|
||||||
|
@ -123,8 +121,6 @@ class ShareHandler(tornado.web.RequestHandler):
|
||||||
if not data:
|
if not data:
|
||||||
break
|
break
|
||||||
self.write(data)
|
self.write(data)
|
||||||
self.finish()
|
|
||||||
|
|
||||||
|
|
||||||
def publish_node(app):
|
def publish_node(app):
|
||||||
update_online()
|
update_online()
|
||||||
|
|
|
@ -102,7 +102,6 @@ class ApiHandler(tornado.web.RequestHandler):
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
self.write('use POST')
|
self.write('use POST')
|
||||||
self.finish()
|
|
||||||
|
|
||||||
@tornado.web.asynchronous
|
@tornado.web.asynchronous
|
||||||
@tornado.gen.coroutine
|
@tornado.gen.coroutine
|
||||||
|
@ -111,14 +110,12 @@ class ApiHandler(tornado.web.RequestHandler):
|
||||||
logger.debug('reject cross site attempt to access api %s', self.request)
|
logger.debug('reject cross site attempt to access api %s', self.request)
|
||||||
self.set_status(403)
|
self.set_status(403)
|
||||||
self.write('')
|
self.write('')
|
||||||
self.finish()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
response = yield tornado.gen.Task(api_task, self._app, self.request)
|
response = yield tornado.gen.Task(api_task, self._app, self.request)
|
||||||
response = json_dumps(json_response(response))
|
response = json_dumps(json_response(response))
|
||||||
self.set_header('Content-Type', 'application/json')
|
self.set_header('Content-Type', 'application/json')
|
||||||
self.write(response)
|
self.write(response)
|
||||||
self.finish()
|
|
||||||
|
|
||||||
class ApiActions(dict):
|
class ApiActions(dict):
|
||||||
properties = {}
|
properties = {}
|
||||||
|
|
|
@ -15,7 +15,7 @@ logger = logging.getLogger('queryparser')
|
||||||
def get_operator(op, type='str'):
|
def get_operator(op, type='str'):
|
||||||
return {
|
return {
|
||||||
'str': {
|
'str': {
|
||||||
'==': operators.ilike_op,
|
'==': operators.eq,
|
||||||
'>': operators.gt,
|
'>': operators.gt,
|
||||||
'>=': operators.ge,
|
'>=': operators.ge,
|
||||||
'<': operators.lt,
|
'<': operators.lt,
|
||||||
|
@ -81,7 +81,6 @@ class Parser(object):
|
||||||
if k == 'list':
|
if k == 'list':
|
||||||
key_type = ''
|
key_type = ''
|
||||||
|
|
||||||
|
|
||||||
if (not exclude and op == '=' or op in ('$', '^')) and v == '':
|
if (not exclude and op == '=' or op in ('$', '^')) and v == '':
|
||||||
return None
|
return None
|
||||||
elif k == 'resolution':
|
elif k == 'resolution':
|
||||||
|
@ -104,7 +103,9 @@ class Parser(object):
|
||||||
elif key_type in ("string", "text"):
|
elif key_type in ("string", "text"):
|
||||||
if isinstance(v, unicode):
|
if isinstance(v, unicode):
|
||||||
v = unicodedata.normalize('NFKD', v).lower()
|
v = unicodedata.normalize('NFKD', v).lower()
|
||||||
q = get_operator(op)(self._find.value, v.lower())
|
else:
|
||||||
|
v = v.lower()
|
||||||
|
q = get_operator(op)(self._find.findvalue, v)
|
||||||
if k != '*':
|
if k != '*':
|
||||||
q &= (self._find.key == k)
|
q &= (self._find.key == k)
|
||||||
if exclude:
|
if exclude:
|
||||||
|
@ -119,7 +120,6 @@ class Parser(object):
|
||||||
else:
|
else:
|
||||||
p = self._user.query.filter_by(id=settings.USER_ID).first()
|
p = self._user.query.filter_by(id=settings.USER_ID).first()
|
||||||
v = ':%s' % name
|
v = ':%s' % name
|
||||||
#print 'get list:', p.id, name, l, v
|
|
||||||
if name:
|
if name:
|
||||||
l = self._list.query.filter_by(user_id=p.id, name=name).first()
|
l = self._list.query.filter_by(user_id=p.id, name=name).first()
|
||||||
else:
|
else:
|
||||||
|
@ -132,7 +132,7 @@ class Parser(object):
|
||||||
data.get('operator', '&'))
|
data.get('operator', '&'))
|
||||||
else:
|
else:
|
||||||
if exclude:
|
if exclude:
|
||||||
q = (self._find.key == 'list') & (self._find.value == v)
|
q = (self._find.key == 'list') & (self._find.findvalue == v)
|
||||||
ids = [i.id
|
ids = [i.id
|
||||||
for i in self._model.query.join(self._find).filter(q).group_by(self._model.id).options(load_only('id'))]
|
for i in self._model.query.join(self._find).filter(q).group_by(self._model.id).options(load_only('id'))]
|
||||||
if ids:
|
if ids:
|
||||||
|
@ -141,7 +141,7 @@ class Parser(object):
|
||||||
q = (self._model.id != 0)
|
q = (self._model.id != 0)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
q = (self._find.key == 'list') & (self._find.value == v)
|
q = (self._find.findvalue == v) & (self._find.key == 'list')
|
||||||
return q
|
return q
|
||||||
elif key_type == 'date':
|
elif key_type == 'date':
|
||||||
def parse_date(d):
|
def parse_date(d):
|
||||||
|
|
|
@ -17,7 +17,7 @@ oml.ui.viewer = function() {
|
||||||
|
|
||||||
that.updateElement = function() {
|
that.updateElement = function() {
|
||||||
item = ui.item;
|
item = ui.item;
|
||||||
if (item) {
|
if (item && item.length) {
|
||||||
oml.api.get({id: item, keys: ['mediastate']}, function(result) {
|
oml.api.get({id: item, keys: ['mediastate']}, function(result) {
|
||||||
if (result.data.mediastate == 'available') {
|
if (result.data.mediastate == 'available') {
|
||||||
$iframe = $iframe || Ox.Element('<iframe>').css({
|
$iframe = $iframe || Ox.Element('<iframe>').css({
|
||||||
|
|
Loading…
Reference in a new issue