diff --git a/clay/app.py b/clay/app.py index f9b75f2..ba561c6 100755 --- a/clay/app.py +++ b/clay/app.py @@ -241,7 +241,7 @@ class AppWidget(urwid.Frame): elif key == 'ctrl q': sys.exit(0) elif key == 'esc': - NotificationArea.close_all() + NotificationArea.close_newest() else: super(AppWidget, self).keypress(size, key) diff --git a/clay/gp.py b/clay/gp.py index 863434a..98d8e84 100644 --- a/clay/gp.py +++ b/clay/gp.py @@ -90,6 +90,16 @@ class Playlist(object): return results +class Station(object): + def __init__(self): + pass + + @classmethod + def from_data(cls, data): + print(data) + raise Exception(str(data)) + + class GP(object): def __init__(self): self.mc = Mobileclient() @@ -139,6 +149,15 @@ class GP(object): ) return self.cached_playlists + @async + @synchronized + def create_station(self, name, track_id=None, artist_id=None, album_id=None, genre_id=None): + kwargs = dict(track_id=track_id, artist_id=artist_id, album_id=album_id, genre_id=genre_id) + # kwargs = {k: v for k, v in kwargs.items() if v is not None} + # if len(kwargs) != 1: + # raise Exception('Must provide one of artist_id, album_id or genre_id') + return Station.from_data(self.mc.create_station(name, **kwargs)) + def get_cached_tracks_map(self): return {track.id: track for track in self.cached_tracks} diff --git a/clay/mylibrary.py b/clay/mylibrary.py index 4083eb9..c5196c9 100644 --- a/clay/mylibrary.py +++ b/clay/mylibrary.py @@ -11,6 +11,7 @@ class MyLibrary(urwid.Columns): def __init__(self, app): self.app = app self.songlist = SongListBox(app) + self.notification = None gp.auth_state_changed += self.auth_state_changed @@ -22,6 +23,7 @@ class MyLibrary(urwid.Columns): if error: NotificationArea.notify('Failed to load my library: {}'.format(str(error))) return + # self.notification.close() self.songlist.populate(tracks) self.app.redraw() @@ -31,3 +33,5 @@ class MyLibrary(urwid.Columns): gp.get_all_tracks(callback=self.on_get_all_songs) + # self.notification = NotificationArea.notify('Loading library...') + diff --git a/clay/myplaylists.py b/clay/myplaylists.py index fffa45e..37ddfcc 100644 --- a/clay/myplaylists.py +++ b/clay/myplaylists.py @@ -40,17 +40,21 @@ class MyPlaylistListBox(urwid.ListBox): self.walker = urwid.SimpleListWalker([ urwid.Text('Not ready') ]) + self.notification = None gp.auth_state_changed += self.auth_state_changed super(MyPlaylistListBox, self).__init__(self.walker) def auth_state_changed(self, is_auth): - self.walker[:] = [ - urwid.Text(u'\n \uf01e Loading playlists...', align='center') - ] + if is_auth: + self.walker[:] = [ + urwid.Text(u'\n \uf01e Loading playlists...', align='center') + ] - gp.get_all_user_playlist_contents(callback=self.on_get_playlists) + gp.get_all_user_playlist_contents(callback=self.on_get_playlists) + + # self.notification = NotificationArea.notify('Loading playlists...') def on_get_playlists(self, playlists, error): if error: @@ -70,6 +74,8 @@ class MyPlaylistListBox(urwid.ListBox): ) items.append(myplaylistlistitem) + # self.notification.close() + self.walker[:] = items self.app.redraw() diff --git a/clay/notifications.py b/clay/notifications.py index 8695187..f080f11 100644 --- a/clay/notifications.py +++ b/clay/notifications.py @@ -1,13 +1,39 @@ import urwid +class Notification(urwid.Columns): + TEMPLATE = u' \u26A1 {}' + + def __init__(self, area, id, message): + self.area = area + self.id = id + self.text = urwid.Text(Notification.TEMPLATE.format(message)) + super(Notification, self).__init__([ + urwid.AttrWrap( + urwid.Columns([ + self.text, + ('pack', urwid.Text('[Hit ESC to close] ')) + ]), + 'notification' + ) + ]) + + def update(self, message): + self.text.text = Notification.TEMPLATE.format(message) + + def close(self): + for notification, props in reversed(self.area.contents): + if notification is self: + self.area.contents.remove((notification, props)) + + class NotificationArea(urwid.Pile): instance = None app = None - TEMPLATE = u' \u26A1 {}' - def __init__(self): + self.last_id = 0 + self.notifications = {} super(NotificationArea, self).__init__([]) @classmethod @@ -23,28 +49,34 @@ class NotificationArea(urwid.Pile): @classmethod def notify(cls, message): - cls.instance._notify(message) + return cls.instance._notify(message) @classmethod def close_all(cls): cls.instance._close_all() + @classmethod + def close_newest(cls): + cls.instance._close_newest() + def _notify(self, message): - text = urwid.Text(self.__class__.TEMPLATE.format(message)) + self.last_id += 1 + notification = Notification(self, self.last_id, message) self.contents.append( ( - urwid.AttrWrap( - urwid.Columns([ - text, - ('pack', urwid.Text('[Hit ESC to close] ')) - ]), - 'notification' - ), + notification, ('weight', 1) ) ) self.__class__.app.redraw() + return notification def _close_all(self): - self.contents[:] = [] + while len(self.contents): + self.contents[0][0].close() + + def _close_newest(self): + if not len(self.contents): + return + self.contents[-1][0].close() diff --git a/clay/songlist.py b/clay/songlist.py index f7989b5..ca71110 100644 --- a/clay/songlist.py +++ b/clay/songlist.py @@ -6,7 +6,8 @@ class SongListItem(urwid.Pile): signals = [ 'activate', 'append-requested', - 'unappend-requested' + 'unappend-requested', + 'station-requested' ] STATE_IDLE = 0 @@ -81,6 +82,9 @@ class SongListItem(urwid.Pile): elif key == 'ctrl u': if not self.is_currently_played: urwid.emit_signal(self, 'unappend-requested', self) + elif key == 'ctrl p': + if not self.is_currently_played: + urwid.emit_signal(self, 'station-requested', self) return super(SongListItem, self).keypress(size, key) def mouse_event(self, size, event, button, x, y, focus): @@ -147,6 +151,9 @@ class SongListBox(urwid.ListBox): urwid.connect_signal( songitem, 'unappend-requested', self.item_unappend_requested ) + urwid.connect_signal( + songitem, 'station-requested', self.item_station_requested + ) items.append(songitem) return (items, current_index) @@ -162,6 +169,11 @@ class SongListBox(urwid.ListBox): def item_unappend_requested(self, songitem): player.remove_from_queue(songitem.track) + def item_station_requested(self, songitem): + # TODO: Implement me + # player.start_station() + pass + def track_changed(self, track): for i, songitem in enumerate(self.walker): if isinstance(songitem, urwid.Text):