+from __future__ import with_statement
+
import os
+import logging
import cairo
import gtk
+import browser_emu
+from util import go_utils
+import util.misc as misc_utils
+
+
+_moduleLogger = logging.getLogger(__name__)
+
class ImageStore(object):
self._storePath = storePath
self._cachePath = cachePath
+ self._browser = browser_emu.MozillaEmulator()
+ self._downloader = go_utils.AsyncPool()
+
+ def start(self):
+ self._downloader.start()
+
+ def stop(self):
+ self._downloader.stop()
+
def get_surface_from_store(self, imageName):
path = os.path.join(self._storePath, imageName)
image = cairo.ImageSurface.create_from_png(path)
path = os.path.join(self._storePath, imageName)
return gtk.gdk.pixbuf_new_from_file(path)
+ def get_pixbuf_from_url(self, url, on_success, on_error):
+ # @ todo Test bad image for both paths
+ filepath = self._url_to_cache(url)
+ if os.path.exists(filepath):
+ pix = gtk.gdk.pixbuf_new_from_file(filepath)
+ try:
+ on_success(pix)
+ except Exception:
+ pass
+ doDownload = False
+ else:
+ doDownload = True
+
+ if doDownload:
+ self._get_image(
+ url,
+ lambda filepath: on_success(gtk.gdk.pixbuf_new_from_file(filepath)),
+ on_error,
+ )
+
def get_pixbuf_animation_from_store(self, imageName):
path = os.path.join(self._storePath, imageName)
return gtk.gdk.PixbufAnimation(path)
+
+ def _get_image(self, url, on_success, on_error):
+ self._downloader.add_task(
+ self._browser.download,
+ (url, ),
+ {},
+ lambda image: self._on_get_image(url, image, on_success, on_error),
+ on_error,
+ )
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_get_image(self, url, image, on_success, on_error):
+ try:
+ filepath = self._url_to_cache(url)
+ _moduleLogger.info("Saved %s" % filepath)
+ with open(filepath, "wb") as f:
+ f.write(image)
+ on_success(filepath)
+ except Exception, e:
+ on_error(e)
+
+ def _url_to_cache(self, url):
+ filename = url.rsplit("/", 1)[-1]
+ filepath = os.path.join(self._cachePath, filename)
+ return filepath
"""
@bug Fix segfault on closing of window while playing
-@todo Add images for Magazines and Issues
@todo Need to confirm id's are persistent (not just for todos but broken behavior on transition)
@todo Track recent
@todo Persisted Pause
self._index = stream_index.AudioIndex()
self._player = player.Player(self._index)
+ self._store.start()
self._index.start()
try:
if not hildonize.IS_HILDON_SUPPORTED:
self._load_settings()
except:
self._index.stop()
+ self._store.stop()
raise
def _save_settings(self):
self._save_settings()
self._index.stop()
+ self._store.stop()
try:
self._deviceState.close()
if kwds is None:
kwds = {}
- self._indexing.clear_tasks()
self._indexing.add_task(
getattr(self._backend, func),
args,
return
self._hide_loading()
- for programNode in programs:
+ for i, programNode in enumerate(programs):
program = programNode.get_properties()
img = self._store.get_pixbuf_from_store(self._store.STORE_LOOKUP["nomagazineimage"])
row = programNode, img, program["title"]
self._model.append(row)
+ programNode.get_children(self._create_on_issues(i), self._on_error)
+
self._select_row()
+ def _create_on_issues(self, row):
+ return lambda issues: self._on_issues(row, issues)
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_issues(self, row, issues):
+ for issue in issues:
+ self._store.get_pixbuf_from_url(
+ issue.get_properties()["pictureURL"],
+ lambda pix: self._on_image(row, pix),
+ self._on_error,
+ )
+ break
+ else:
+ _moduleLogger.info("No issues for magazine %s" % row)
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_image(self, row, pix):
+ treeiter = self._model.iter_nth_child(None, row)
+ self._model.set_value(treeiter, 1, pix)
+ treeiter = self._model.iter_nth_child(None, row)
+ self._model.row_changed((row, ), treeiter)
+
@misc_utils.log_exception(_moduleLogger)
def _on_error(self, exception):
self._hide_loading()
row = programNode, img, program["title"]
self._model.append(row)
+ self._store.get_pixbuf_from_url(
+ program["pictureURL"],
+ self._create_on_image(programNode),
+ self._on_error,
+ )
+
self._select_row()
@misc_utils.log_exception(_moduleLogger)
self._hide_loading()
self._errorBanner.push_message(str(exception))
+ def _create_on_image(self, programNode):
+ return lambda pix: self._on_image(programNode, pix)
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_image(self, childNode, pix):
+ for i, row in enumerate(self._model):
+ if row[0] is childNode:
+ break
+ else:
+ raise RuntimeError("Could not find %r" % childNode)
+ treeiter = self._model.iter_nth_child(None, i)
+ self._model.set_value(treeiter, 1, pix)
+ treeiter = self._model.iter_nth_child(None, i)
+ self._model.row_changed((i, ), treeiter)
+
def _window_from_node(self, node):
issuesWindow = MagazineArticlesWindow(self._player, self._store, node)
issuesWindow.window.set_modal(True)