From 5f8094bba31e09b8ae39190671371046bcd9c2ff Mon Sep 17 00:00:00 2001 From: j Date: Thu, 21 Jan 2016 12:35:49 +0530 Subject: [PATCH] try to get preview from peers, fixes #79 --- oml/changelog.py | 1 + oml/item/icons.py | 12 +++++++----- oml/item/models.py | 13 +++++++++++++ oml/node/server.py | 5 ++--- oml/nodes.py | 14 ++++++++++---- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/oml/changelog.py b/oml/changelog.py index 7f665fb..896c231 100644 --- a/oml/changelog.py +++ b/oml/changelog.py @@ -170,6 +170,7 @@ class Changelog(db.Model): i = Item.get(itemid) if i: i.sync_metadata() + i.get_preview() return True def action_removeitem(self, user, timestamp, itemid): diff --git a/oml/item/icons.py b/oml/item/icons.py index a1f021f..e663521 100644 --- a/oml/item/icons.py +++ b/oml/item/icons.py @@ -93,14 +93,12 @@ class Icons(dict): icons = Icons(icons_db_path) -@run_async -def get_icon(id, type_, size, callback): +def get_icon_sync(id, type_, size): if size: skey = '%s:%s:%s' % (type_, id, size) data = icons[skey] if data: - callback(bytes(data)) - return + return bytes(data) key = '%s:%s' % (type_, id) data = icons[key] if not data: @@ -128,7 +126,11 @@ def get_icon(id, type_, size, callback): if size: data = icons[skey] = resize_image(data, size=size) data = bytes(data) or '' - callback(data) + return data + +@run_async +def get_icon(id, type_, size, callback): + callback(get_icon_sync(id, type_, size)) def clear_default_cover_cache(): icons.clear('default:cover:') diff --git a/oml/item/models.py b/oml/item/models.py index 9be67d0..209969f 100644 --- a/oml/item/models.py +++ b/oml/item/models.py @@ -366,6 +366,11 @@ class Item(db.Model): path = self.get_path() if path: return getattr(media, self.info['extension']).cover(path) + else: + for u in self.users: + if u.id != settings.USER_ID: + if state.nodes.download_preview(u.id, self.id): + break def update_cover(self): key = 'cover:%s'%self.id @@ -388,6 +393,14 @@ class Item(db.Model): del self.info['coverRatio'] icons.clear('cover:%s:' % self.id) + def get_preview(self): + key = 'preview:%s'%self.id + data = icons[key] + if not data: + preview = self.extract_preview() + if preview: + icons[key] = preview + def update_preview(self): key = 'preview:%s'%self.id preview = self.extract_preview() diff --git a/oml/node/server.py b/oml/node/server.py index 6d90a6b..f374404 100644 --- a/oml/node/server.py +++ b/oml/node/server.py @@ -127,9 +127,8 @@ class Handler(http.server.SimpleHTTPRequestHandler): self.wfile.write(b'404 - Not Found') return if preview: - from item.icons import icons - key = 'preview:' + id - data = icons[key] + from item.icons import get_icon_sync + data = get_icon_sync(id, 'preview', 512) if data: self.send_response(200, 'ok') self.send_header('Content-type', 'image/jpg') diff --git a/oml/nodes.py b/oml/nodes.py index 9391675..764533f 100644 --- a/oml/nodes.py +++ b/oml/nodes.py @@ -359,10 +359,11 @@ class Node(Thread): logger.debug('FAILED %s', url) return False - def download_preview(self, item): + def download_preview(self, item_id): + logger.debug('trying to download preview from %s for %s', self.url, item_id) from item.icons import icons self.resolve() - url = '%s/preview/%s' % (self.url, item.id) + url = '%s/preview/%s' % (self.url, item_id) self._opener.addheaders = list(zip(self.headers.keys(), self.headers.values())) try: r = self._opener.open(url, timeout=self.TIMEOUT*2) @@ -376,9 +377,9 @@ class Node(Thread): if r.headers.get('content-encoding', None) == 'gzip': fileobj = gzip.GzipFile(fileobj=r) content = fileobj.read() - key = 'preview:' + item.id + key = 'preview:' + item_id icons[key] = content - icons.clear('preview:%s:'%item.id) + icons.clear(key+':') return True except: logger.debug('preview download failed %s', url, exc_info=1) @@ -446,6 +447,11 @@ class Nodes(Thread): def download(self, id, item): return id in self._nodes and self._nodes[id].download(item) + def download_preview(self, id, item): + return id in self._nodes and \ + self._nodes[id].is_online() and \ + self._nodes[id].download_preview(item) + def _call(self, target, action, *args): if target == 'all': nodes = list(self._nodes.values())