More screens updated to do background fetching
[jamaendo] / jamaui / fetcher.py
1 # Background fetcher:
2 # Takes a generator and a notification identifier as parameter,
3 # starts a thread, and post a notification whenever data arrives.
4 # Posts a completion notification when done.
5 # Terminates if generator fails or encounters an error.
6
7 import threading
8 from postoffice import postoffice
9 import jamaendo
10 import logging
11
12 import gtk
13 import hildon
14
15 log = logging.getLogger(__name__)
16
17 class _Worker(threading.Thread):
18     def __init__(self, generator, owner):
19         threading.Thread.__init__(self)
20         self.setDaemon(True)
21         self.generator = generator
22         self.owner = owner
23
24     def _post(self, item):
25         postoffice.notify("fetch", self.owner, item)
26
27     def _post_ok(self):
28         postoffice.notify("fetch-ok", self.owner)
29
30     def _post_fail(self, e):
31         postoffice.notify("fetch-fail", self.owner, e)
32
33     def run(self):
34         try:
35             for item in self.generator():
36                 self._post(item)
37             self._post_ok()
38         except jamaendo.JamendoAPIException, e:
39             log.exception("Failed to fetch, id %s" % (self.owner))
40             self._post_fail(e)
41
42 class Fetcher(object):
43     def __init__(self, generator, owner, on_item = None, on_ok = None, on_fail = None):
44         self.generator = generator
45         self.owner = owner
46         self.worker = None
47
48         self.on_item = on_item
49         self.on_ok = on_ok
50         self.on_fail = on_fail
51
52     def _on_item_cb(self, i, x):
53         self.on_item(i, x)
54
55     def _on_ok_cb(self, i):
56         self.on_ok(i)
57         if isinstance(self.owner, gtk.Window):
58             hildon.hildon_gtk_window_set_progress_indicator(self.owner, 0)
59
60     def _on_fail_cb(self, i, e):
61         self.on_fail(i, e)
62         if isinstance(self.owner, gtk.Window):
63             hildon.hildon_gtk_window_set_progress_indicator(self.owner, 0)
64
65     def start(self):
66         postoffice.connect('fetch', self, self._on_item_cb)
67         postoffice.connect('fetch-ok', self, self._on_ok_cb)
68         postoffice.connect('fetch-fail', self, self._on_fail_cb)
69         if isinstance(self.owner, gtk.Window):
70             hildon.hildon_gtk_window_set_progress_indicator(self.owner, 1)
71         self.worker = _Worker(self.generator, self.owner)
72         self.worker.start()
73
74     def stop(self):
75         postoffice.disconnect(['fetch', 'fetch-ok', 'fetch-fail'], self)