eb1d08d12eadc797d50bd6526590714e5a2e6ada
[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 gobject
13 import gtk
14 import hildon
15
16 log = logging.getLogger(__name__)
17
18 class _Worker(threading.Thread):
19     def __init__(self, generator, owner):
20         threading.Thread.__init__(self)
21         self.setDaemon(True)
22         self.generator = generator
23         self.owner = owner
24
25     def _post(self, item):
26         def idle_fetch(owner, item):
27             postoffice.notify("fetch", owner, item)
28         gobject.idle_add(idle_fetch, self.owner, item)
29
30     def _post_ok(self):
31         def idle_fetch_ok(owner):
32             postoffice.notify("fetch-ok", owner)
33         gobject.idle_add(idle_fetch_ok, self.owner)
34
35     def _post_fail(self, e):
36         def idle_fetch_fail(owner, e):
37             postoffice.notify("fetch-fail", owner, e)
38         gobject.idle_add(idle_fetch_fail, self.owner, e)
39
40     def run(self):
41         try:
42             for item in self.generator():
43                 self._post(item)
44             self._post_ok()
45         except jamaendo.JamendoAPIException, e:
46             log.exception("Failed to fetch, id %s" % (self.owner))
47             self._post_fail(e)
48
49 class Fetcher(object):
50     def __init__(self, generator, owner, on_item = None, on_ok = None, on_fail = None):
51         self.generator = generator
52         self.owner = owner
53         self.worker = None
54
55         self.on_item = on_item
56         self.on_ok = on_ok
57         self.on_fail = on_fail
58
59     def _on_item_cb(self, i, x):
60         self.on_item(i, x)
61
62     def _on_ok_cb(self, i):
63         self.on_ok(i)
64         if isinstance(self.owner, gtk.Window):
65             hildon.hildon_gtk_window_set_progress_indicator(self.owner, 0)
66
67     def _on_fail_cb(self, i, e):
68         self.on_fail(i, e)
69         if isinstance(self.owner, gtk.Window):
70             hildon.hildon_gtk_window_set_progress_indicator(self.owner, 0)
71
72     def start(self):
73         postoffice.connect('fetch', self, self._on_item_cb)
74         postoffice.connect('fetch-ok', self, self._on_ok_cb)
75         postoffice.connect('fetch-fail', self, self._on_fail_cb)
76         if isinstance(self.owner, gtk.Window):
77             hildon.hildon_gtk_window_set_progress_indicator(self.owner, 1)
78         self.worker = _Worker(self.generator, self.owner)
79         self.worker.start()
80
81     def stop(self):
82         postoffice.disconnect(['fetch', 'fetch-ok', 'fetch-fail'], self)