From: Kristoffer Grönlund Date: Sat, 9 Jan 2010 01:47:22 +0000 (+0100) Subject: Big threading update, most things are asynchronous now X-Git-Url: http://git.maemo.org/git/?p=jamaendo;a=commitdiff_plain;h=ed6ce6efe7c4f87b7d8c0e06bff8b50a74f6039d Big threading update, most things are asynchronous now --- diff --git a/jamaendo/api.py b/jamaendo/api.py index ca4e51f..8bc2353 100644 --- a/jamaendo/api.py +++ b/jamaendo/api.py @@ -694,9 +694,9 @@ def get_albums(artist_id): """Returns: [Album] Parameter can either be an artist_id or a list of album ids. """ + if isinstance(artist_id, list): + return get_album_list(artist_id) with _APILOCK: - if isinstance(artist_id, list): - return get_album_list(artist_id) a = _artists.get(artist_id, None) if a and a.albums: return a.albums @@ -747,9 +747,9 @@ def get_tracks(album_id): """Returns: [Track] Parameter can either be an album_id or a list of track ids. """ + if isinstance(album_id, list): + return get_track_list(album_id) with _APILOCK: - if isinstance(album_id, list): - return get_track_list(album_id) a = _albums.get(album_id, None) if a and a.tracks: return a.tracks diff --git a/jamaui/favorites.py b/jamaui/favorites.py index 6e829ac..ef58143 100644 --- a/jamaui/favorites.py +++ b/jamaui/favorites.py @@ -21,7 +21,6 @@ # Copyright (c) 2008-05-26 Thomas Perl # (based on http://pygstdocs.berlios.de/pygst-tutorial/seeking.html) # -import gtk try: import hildon except: @@ -32,8 +31,10 @@ from showartist import ShowArtist from showalbum import ShowAlbum from settings import settings import logging +from fetcher import Fetcher +import itertools -from albumlist import AlbumList +from albumlist import MusicList log = logging.getLogger(__name__) @@ -47,51 +48,66 @@ class FavoritesWindow(hildon.StackableWindow): def __init__(self): hildon.StackableWindow.__init__(self) self.set_title("Favorites") - - if settings.user: - # Results list - self.panarea = hildon.PannableArea() - self.results = AlbumList() - self.results.connect('row-activated', self.row_activated) - self.panarea.add(self.results) - - self.idmap = {} - - def add_album(ID, album_factory): - if ID not in self.idmap: - album = album_factory() - self.idmap[ID] = album - self.results.add_album(album) - - try: - for item in jamaendo.favorite_albums(settings.user): - add_album(item.ID, lambda: item) - except jamaendo.JamendoAPIException, e: - msg = "Query failed, is the user name '%s' correct?" % (settings.user) - banner = hildon.hildon_banner_show_information(self, '', - msg) - banner.set_timeout(3000) - - favorite_albums = [f[1] for f in settings.favorites if isinstance(f, tuple) and len(f) == 2 and f[0] == 'album' and f[1] not in self.idmap] - try: - for album in jamaendo.get_albums(favorite_albums): - add_album(album.ID, lambda: album) - - except jamaendo.JamendoAPIException, e: - log.exception("jamaendo.get_albums(%s)"%(favorite_albums)) - - self.add(self.panarea) - + self.connect('destroy', self.on_destroy) + self.fetcher = None + self.idmap = {} + + self.panarea = hildon.PannableArea() + self.favorites = MusicList() + self.favorites.connect('row-activated', self.row_activated) + self.panarea.add(self.favorites) + self.add(self.panarea) + + if not settings.user: + self.favorites.loading_message = """give your username +to the settings dialog +favorites appear +""" else: - vbox = gtk.VBox() - lbl = gtk.Label() - lbl.set_markup("""jamendo.com -in the settings dialog -enter your username -""") - lbl.set_single_line_mode(False) - vbox.pack_start(lbl, True, False) - self.add(vbox) + self.favorites.loading_message = """Loading favorites""" + + self.start_favorites_fetcher() + + def on_destroy(self, wnd): + if self.fetcher: + self.fetcher.stop() + self.fetcher = None + + def start_favorites_fetcher(self): + if self.fetcher: + self.fetcher.stop() + self.fetcher = None + + def gen(): + generated = [] + for item in jamaendo.favorite_albums(settings.user): + generated.append(item.ID) + yield item + fav = [f[1] for f in settings.favorites \ + if isinstance(f, tuple) and \ + len(f) == 2 and \ + f[0] == 'album' and \ + f[1] not in generated] + for item in jamaendo.get_albums(fav): + yield item + + self.fetcher = Fetcher(gen, + self, + on_item = self.on_favorites_result, + on_ok = self.on_favorites_complete, + on_fail = self.on_favorites_complete) + self.fetcher.start() + + def on_favorites_result(self, wnd, item): + if wnd is self: + if item.ID not in self.idmap: + self.idmap[item.ID] = item + self.favorites.add_items([item]) + + def on_favorites_complete(self, wnd, error=None): + if wnd is self: + self.fetcher.stop() + self.fetcher = None def get_item_text(self, item): if isinstance(item, jamaendo.Album): @@ -101,25 +117,11 @@ enter your username else: return item.name - def make_button(self, text, subtext, callback): - button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, - hildon.BUTTON_ARRANGEMENT_VERTICAL) - button.set_text(text, subtext) - - if callback: - button.connect('clicked', callback) - - #image = gtk.image_new_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON) - #button.set_image(image) - #button.set_image_position(gtk.POS_RIGHT) - - return button - def row_activated(self, treeview, path, view_column): - _id = self.results.get_album_id(path) - item = self.idmap[_id] - #print _id, item - self.open_item(item) + _id = self.favorites.get_item_id(path) + item = self.idmap.get(_id) + if item: + self.open_item(item) def open_item(self, item): if isinstance(item, jamaendo.Album): diff --git a/jamaui/fetcher.py b/jamaui/fetcher.py index e4fa3e0..eb1d08d 100644 --- a/jamaui/fetcher.py +++ b/jamaui/fetcher.py @@ -9,6 +9,7 @@ from postoffice import postoffice import jamaendo import logging +import gobject import gtk import hildon @@ -22,13 +23,19 @@ class _Worker(threading.Thread): self.owner = owner def _post(self, item): - postoffice.notify("fetch", self.owner, item) + def idle_fetch(owner, item): + postoffice.notify("fetch", owner, item) + gobject.idle_add(idle_fetch, self.owner, item) def _post_ok(self): - postoffice.notify("fetch-ok", self.owner) + def idle_fetch_ok(owner): + postoffice.notify("fetch-ok", owner) + gobject.idle_add(idle_fetch_ok, self.owner) def _post_fail(self, e): - postoffice.notify("fetch-fail", self.owner, e) + def idle_fetch_fail(owner, e): + postoffice.notify("fetch-fail", owner, e) + gobject.idle_add(idle_fetch_fail, self.owner, e) def run(self): try: diff --git a/jamaui/showalbum.py b/jamaui/showalbum.py index f1933d2..a1aec5c 100644 --- a/jamaui/showalbum.py +++ b/jamaui/showalbum.py @@ -34,6 +34,8 @@ from settings import settings from postoffice import postoffice import util import logging +import thread +import gobject from albumlist import TrackList from playlists import add_to_playlist from fetcher import Fetcher @@ -160,8 +162,19 @@ class ShowAlbum(hildon.StackableWindow): return btn def on_goto_artist(self, btn): - artist = jamaendo.get_artist(int(self.album.artist_id)) - self.open_item(artist) + def threadfun(wnd, artist_id): + try: + artist = jamaendo.get_artist(artist_id) + def oncomplete(wnd, artist): + wnd.open_item(artist) + hildon.hildon_gtk_window_set_progress_indicator(wnd, 0) + gobject.idle_add(oncomplete, wnd, artist) + except: + def onfail(wnd): + hildon.hildon_gtk_window_set_progress_indicator(wnd, 0) + gobject.idle_add(onfail, wnd) + hildon.hildon_gtk_window_set_progress_indicator(self, 1) + thread.start_new_thread(threadfun, (self, int(self.album.artist_id))) def on_download(self, btn): banner = hildon.hildon_banner_show_information(self, '', "Opening in web browser") diff --git a/jamaui/showartist.py b/jamaui/showartist.py index 1a6557f..9b49b4e 100644 --- a/jamaui/showartist.py +++ b/jamaui/showartist.py @@ -91,6 +91,7 @@ class ShowArtist(hildon.StackableWindow): self.start_album_fetcher() def on_destroy(self, wnd): + postoffice.disconnect('images', self) if self.fetcher: self.fetcher.stop() self.fetcher = None @@ -131,15 +132,45 @@ class ShowArtist(hildon.StackableWindow): self.menu.show_all() self.set_app_menu(self.menu) + def start_addpl_fetcher(self): + if self.fetcher: + self.fetcher.stop() + self.fetcher = None + def fetchgen(): + for album in self.albumlist: + yield jamaendo.get_tracks(album.ID) + raise StopIteration + self.fetcher = Fetcher(fetchgen, self, + on_item = self.on_addpl_result, + on_ok = self.on_addpl_complete, + on_fail = self.on_addpl_complete) + self.fetcher.tracklist = [] + self.fetcher.pdlg = gtk.Dialog("Fetching album tracks", self) + self.fetcher.pbar = gtk.ProgressBar() + self.fetcher.pbar.set_fraction(0) + self.fetcher.pdlg.vbox.add(self.fetcher.pbar) + self.fetcher.pdlg.show_all() + self.fetcher.ppos = 1 + self.fetcher.start() + + def on_addpl_result(self, wnd, items): + if wnd is self: + self.fetcher.tracklist.extend(items) + self.fetcher.ppos += 1 + self.fetcher.pbar.set_fraction(float(self.fetcher.ppos)/float(len(self.albumlist)+1)) + + def on_addpl_complete(self, wnd, error=None): + if wnd is self: + self.fetcher.stop() + self.fetcher.pdlg.destroy() + if self.fetcher.tracklist: + add_to_playlist(self, self.fetcher.tracklist) + self.fetcher = None + + def on_add_to_playlist(self, button, user_data=None): if self.albumlist: - try: - tracklist = [] - for album in self.albumlist: - tracklist.extend(jamaendo.get_tracks(album.ID)) - add_to_playlist(self, tracklist) - except jamaendo.JamendoAPIException: - log.exception("Failed to get track list for artist %s", self.artist.ID) + self.start_addpl_fetcher() else: show_banner(self, "Error when opening track list") @@ -170,15 +201,37 @@ class ShowArtist(hildon.StackableWindow): if pb: self.image.set_from_pixbuf(pb) - def on_destroy(self, wnd): - postoffice.disconnect('images', self) + def start_albumplay_fetcher(self, ID): + if self.fetcher: + self.fetcher.stop() + self.fetcher = None + def albumgen(): + yield jamaendo.get_album(ID) + raise StopIteration + self.fetcher = Fetcher(albumgen, self, + on_item = self.on_albumplay_result, + on_ok = self.on_albumplay_complete, + on_fail = self.on_albumplay_complete) + self.fetcher.album = None + self.fetcher.start() + + def on_albumplay_result(self, wnd, item): + if wnd is self: + if isinstance(item, list): + self.fetcher.album = item[0] + else: + self.fetcher.album = item + + def on_albumplay_complete(self, wnd, error=None): + if wnd is self: + self.fetcher.stop() + if self.fetcher.album: + self.open_item(self.fetcher.album) + self.fetcher = None def row_activated(self, treeview, path, view_column): _id = self.albums.get_album_id(path) - album = jamaendo.get_album(_id) - if isinstance(album, list): - album = album[0] - self.open_item(album) + self.start_albumplay_fetcher(_id) def open_item(self, item): if isinstance(item, jamaendo.Album): diff --git a/jamaui/ui.py b/jamaui/ui.py index 100be8d..ac1c6a8 100644 --- a/jamaui/ui.py +++ b/jamaui/ui.py @@ -286,7 +286,9 @@ JAMENDO is an online platform that distributes musical works under Creative Comm self.create_menu() self.setup_widgets() self.window.show_all() + gtk.gdk.threads_enter() gtk.main() + gtk.gdk.threads_leave() ossohelper.application_exit() if __name__=="__main__":