diff --git a/oml/commands.py b/oml/commands.py index 2c1b3ff..8795776 100644 --- a/oml/commands.py +++ b/oml/commands.py @@ -98,6 +98,11 @@ class PostUpdate(Command): changed = True if changed: 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): """ diff --git a/oml/item/api.py b/oml/item/api.py index b2ed0a5..2596ad7 100644 --- a/oml/item/api.py +++ b/oml/item/api.py @@ -87,11 +87,15 @@ def find(data): j = i.json() response['items'].append({k:j[k] for k in j if not data['keys'] or k in data['keys']}) else: - response['items'] = q['qs'].count() - #from sqlalchemy.sql import func - #models.db.session.query(func.sum(models.Item.sort_size).label("size")) - #response['size'] = x.scalar() - response['size'] = sum([i.info.get('size', 0) for i in q['qs'].join(models.Sort).options(load_only('id', 'info'))]) + key = 'stats:' + hashlib.sha1(json.dumps(data)).hexdigest() + stats = state.cache.get(key) + if stats is None: + stats = {} + 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 actions.register(find) diff --git a/oml/item/handlers.py b/oml/item/handlers.py index da96d1e..74d8240 100644 --- a/oml/item/handlers.py +++ b/oml/item/handlers.py @@ -38,7 +38,6 @@ class EpubHandler(OMLHandler): }.get(filename.split('.')[0], mimetypes.guess_type(filename)[0]) or 'text/plain' self.set_header('Content-Type', content_type) self.write(z.read(filename)) - self.finish() def serve_static(handler, path, mimetype, include_body=True): #fixme use static file handler / serve ranges @@ -47,7 +46,6 @@ def serve_static(handler, path, mimetype, include_body=True): if include_body: with open(path) as fd: handler.write(fd.read()) - handler.finish() return class FileHandler(OMLHandler): @@ -61,7 +59,6 @@ class FileHandler(OMLHandler): path = item.get_path() if item else None if not item or not path: self.set_status(404) - self.finish() return mimetype={ 'epub': 'application/epub+zip', @@ -77,7 +74,6 @@ class ReaderHandler(OMLHandler): item = Item.get(id) if not item: self.set_status(404) - self.finish() return if item.info['extension'] == 'epub': html = 'html/epub.html' @@ -87,7 +83,6 @@ class ReaderHandler(OMLHandler): html = 'html/txt.html' else: self.set_status(404) - self.finish() return item.accessed = datetime.utcnow() item.timesaccessed = (item.timesaccessed or 0) + 1 diff --git a/oml/item/icons.py b/oml/item/icons.py index 7338b6e..ebc5a96 100644 --- a/oml/item/icons.py +++ b/oml/item/icons.py @@ -160,7 +160,6 @@ class IconHandler(tornado.web.RequestHandler): if type_ not in ('cover', 'preview'): self.set_status(404) - self.finish() return 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) if not response: self.set_status(404) - self.finish() return if self._finished: return diff --git a/oml/item/models.py b/oml/item/models.py index f30b66f..7e74255 100644 --- a/oml/item/models.py +++ b/oml/item/models.py @@ -192,15 +192,15 @@ class Item(db.Model): f.item_id = self.id f.key = 'list' if p.id == settings.USER_ID: - f.value = ':' + f.findvalue = f.value = ':' else: - f.value = '%s:' % p.id + f.findvalue = f.value = '%s:' % p.id db.session.add(f) for l in self.lists: f = Find() f.item_id = self.id f.key = 'list' - f.value = l.find_id + f.findvalue = f.value = l.find_id db.session.add(f) def update(self): diff --git a/oml/node/server.py b/oml/node/server.py index 21d9351..bcdabc8 100644 --- a/oml/node/server.py +++ b/oml/node/server.py @@ -72,14 +72,12 @@ class NodeHandler(tornado.web.RequestHandler): self.set_header('X-Ed25519-Signature', sig) self.set_header('X-Node-Protocol', settings.NODE_PROTOCOL) self.write(content) - self.finish() def get(self): self.set_header('X-Node-Protocol', settings.NODE_PROTOCOL) if self.request.headers.get('X-Node-Protocol', None) > settings.NODE_PROTOCOL: state.update_required = True self.write('Open Media Library') - self.finish() @run_async def api_call(app, action, key, args, callback): @@ -108,7 +106,7 @@ class ShareHandler(tornado.web.RequestHandler): i = item.models.Item.get(id) if not i: self.set_status(404) - self.finish() + return path = i.get_path() mimetype = { 'epub': 'application/epub+zip', @@ -123,8 +121,6 @@ class ShareHandler(tornado.web.RequestHandler): if not data: break self.write(data) - self.finish() - def publish_node(app): update_online() diff --git a/oml/oxtornado.py b/oml/oxtornado.py index 48b3712..35e03c7 100644 --- a/oml/oxtornado.py +++ b/oml/oxtornado.py @@ -102,7 +102,6 @@ class ApiHandler(tornado.web.RequestHandler): def get(self): self.write('use POST') - self.finish() @tornado.web.asynchronous @tornado.gen.coroutine @@ -111,14 +110,12 @@ class ApiHandler(tornado.web.RequestHandler): logger.debug('reject cross site attempt to access api %s', self.request) self.set_status(403) self.write('') - self.finish() return response = yield tornado.gen.Task(api_task, self._app, self.request) response = json_dumps(json_response(response)) self.set_header('Content-Type', 'application/json') self.write(response) - self.finish() class ApiActions(dict): properties = {} diff --git a/oml/queryparser.py b/oml/queryparser.py index 6d8eba5..6bc5381 100644 --- a/oml/queryparser.py +++ b/oml/queryparser.py @@ -15,7 +15,7 @@ logger = logging.getLogger('queryparser') def get_operator(op, type='str'): return { 'str': { - '==': operators.ilike_op, + '==': operators.eq, '>': operators.gt, '>=': operators.ge, '<': operators.lt, @@ -81,7 +81,6 @@ class Parser(object): if k == 'list': key_type = '' - if (not exclude and op == '=' or op in ('$', '^')) and v == '': return None elif k == 'resolution': @@ -104,7 +103,9 @@ class Parser(object): elif key_type in ("string", "text"): if isinstance(v, unicode): 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 != '*': q &= (self._find.key == k) if exclude: @@ -119,7 +120,6 @@ class Parser(object): else: p = self._user.query.filter_by(id=settings.USER_ID).first() v = ':%s' % name - #print 'get list:', p.id, name, l, v if name: l = self._list.query.filter_by(user_id=p.id, name=name).first() else: @@ -132,7 +132,7 @@ class Parser(object): data.get('operator', '&')) else: if exclude: - q = (self._find.key == 'list') & (self._find.value == v) + q = (self._find.key == 'list') & (self._find.findvalue == v) ids = [i.id for i in self._model.query.join(self._find).filter(q).group_by(self._model.id).options(load_only('id'))] if ids: @@ -141,7 +141,7 @@ class Parser(object): q = (self._model.id != 0) else: - q = (self._find.key == 'list') & (self._find.value == v) + q = (self._find.findvalue == v) & (self._find.key == 'list') return q elif key_type == 'date': def parse_date(d): diff --git a/static/js/viewer.js b/static/js/viewer.js index cb75c7b..bb32c1a 100644 --- a/static/js/viewer.js +++ b/static/js/viewer.js @@ -17,7 +17,7 @@ oml.ui.viewer = function() { that.updateElement = function() { item = ui.item; - if (item) { + if (item && item.length) { oml.api.get({id: item, keys: ['mediastate']}, function(result) { if (result.data.mediastate == 'available') { $iframe = $iframe || Ox.Element('