diff options
-rwxr-xr-x | app.py | 29 | ||||
-rw-r--r-- | db.py | 5 | ||||
-rw-r--r-- | static/init.js | 48 | ||||
-rw-r--r-- | static/playlist.js | 8 | ||||
-rw-r--r-- | static/style.css | 3 | ||||
-rw-r--r-- | static/templates.js | 8 |
6 files changed, 91 insertions, 10 deletions
@@ -21,6 +21,16 @@ class JSONApplication(object): d['cache'] = JSONApplication.cache_check(track) return d + @staticmethod + def format_album(album, artist = False): + d = { + 'id': album.id, + 'name': album.name, + } + if artist: + d['artist'] = {'name': album.artist.name} + return d + def list(self, environ, start_response, path): root_id = int(path[1]) if len(path) > 1 and len(path[1]) else 0 session = db.Session() @@ -95,7 +105,7 @@ class JSONApplication(object): try: session = db.Session() albums = session.query(db.Album).offset(page*page_size).limit(page_size) - results = [{'id': a.id, 'name': a.name, 'artist': {'name': a.artist.name}} for a in albums] + results = [self.format_album(a, artist = True) for a in albums] finally: session.close() @@ -114,12 +124,29 @@ class JSONApplication(object): start_response('200 OK', []) return json.dumps(results) + def artist(self, environ, start_response, path): + artist = int(path[1]) + try: + session = db.Session() + artist = session.query(db.Artist).filter(db.Artist.id == artist).one() + results = { + 'id': artist.id, + 'name': artist.name, + 'albums': [self.format_album(a) for a in artist.albums], + } + finally: + session.close() + + start_response('200 OK', []) + return json.dumps(results) + handlers = { 'list': list, 'hint': hint, 'search': search, 'albums': albums, 'album': album, + 'artist': artist, } def __call__(self, environ, start_response, path): @@ -199,7 +199,10 @@ class Track(Base): if self.name: metadata['title'] = self.name if self.artist: - metadata['artist'] = self.artist.name + metadata.update({ + 'artist': self.artist.name, + 'artist_id': self.artist.id, + }) if self.album: metadata.update({ 'album': self.album.name, diff --git a/static/init.js b/static/init.js index c4f6c2c..2c63ac8 100644 --- a/static/init.js +++ b/static/init.js @@ -60,7 +60,15 @@ function load_directory(dir_id, dir_item) { $('#directory-add').prop('disabled', track_list.find('.ui-selected').length == 0); return false; }); - $(el, 'a.album').click(function() { + el.find('a.artist').click(function() { + var artist = { + id: item.metadata.artist_id, + name: item.metadata.artist + }; + show_artist(artist); + return false; + }); + el.find('a.album').click(function() { var album = { id: item.metadata.album_id, name: item.metadata.album @@ -108,6 +116,14 @@ function set_tracks(container, select, click) { select.prop('disabled', container.find('.ui-selected').length == 0); return false; }); + el.find('a.artist').click(function(event) { + var artist = { + id: track.metadata.artist_id, + name: track.metadata.artist + }; + show_artist(artist); + return false; + }); el.find('a.album').click(function(event) { var album = { id: track.metadata.album_id, @@ -130,6 +146,30 @@ function set_tracks(container, select, click) { }); } +function show_artist(artist) { + var tabs = $('#tabs'); + var tabid = '#artist-tab-' + artist.id; + var tab = $(tabid); + if(tab.length > 0) { + tabs.tabs('select', tab.index()-1); + return; + } + var tabli = $(templates.artist_tabli({tabid: tabid, artist: artist})); + tabs.find('.ui-tabs-nav').append(tabli); + var tab = $(templates.artist_tab(artist)); + tabs.append(tab).tabs('refresh'); + $.get('/json/artist/' + artist.id, function(data) { + var albums = []; + $.each(data.albums, function(i, album) { + album.artist = {id: data.id, name: data.name}; + albums.push(album); + }); + tab.empty(); + add_albums(tabid, albums); + }, 'json'); + tabs.tabs('select', tab.index()-1); +} + function show_album(album) { var tabs = $('#tabs'); var tabid = '#album-tab-' + album.id; @@ -155,8 +195,8 @@ function show_album(album) { tabs.tabs('select', tab.index()-1); } -function add_albums(data) { - var div = $('#albums-list'); +function add_albums(selector, data) { + var div = $(selector); $.each(data, function(i, album) { var el = $(templates.albums_item(album)); el.find('a').click(function() { @@ -190,7 +230,7 @@ function load_albums(initiate_scrolling) { albums_loading = true; $.get('/json/albums/' + page, function(data) { if(data.length > 0) - add_albums(data); + add_albums('#albums-list', data); else albums_end = true; if(initiate_scrolling == true) diff --git a/static/playlist.js b/static/playlist.js index 90167ce..07953ce 100644 --- a/static/playlist.js +++ b/static/playlist.js @@ -24,6 +24,14 @@ $(function(){ playsound(model); return false; }); + $('a.artist', this.el).click(function() { + var artist = { + id: model.attributes.metadata.artist_id, + name: model.attributes.metadata.artist + }; + show_artist(artist); + return false; + }); $('a.album', this.el).click(function() { var album = { id: model.attributes.metadata.album_id, diff --git a/static/style.css b/static/style.css index 058a3d8..8b2f1e8 100644 --- a/static/style.css +++ b/static/style.css @@ -17,8 +17,9 @@ html, body, #content { height: 100%; } .track-table tr.ui-selected td { background-color: #fea; } .track-table tr:hover td { background-color: #fbb; } -.track-table a { color: inherit; text-decoration: inherit; background-repeat: no-repeat; padding-left: 20px; display: block; } +.track-table a { color: inherit; text-decoration: inherit; display: block; } .track-table a:hover { text-decoration: underline; } +.track-table a.track, .track-table a.dir { background-repeat: no-repeat; padding-left: 20px; } .track-table .dir { background-image: url('/static/icons/folder.png'); } .track-table .track { background-image: url('/static/icons/music.png'); } .track-table .track.nocache { background-image: url('/static/icons/music_nocache.png'); } diff --git a/static/templates.js b/static/templates.js index fa2a240..71b77e8 100644 --- a/static/templates.js +++ b/static/templates.js @@ -10,10 +10,12 @@ Handlebars.registerHelper('trackname', function() { }); var templates = new (function Templates() { - this.track_item = Handlebars.compile('<tr id="{{type}}-{{id}}"><td><a href="#" class="{{type}}{{#unless cache}} nocache{{/unless}}">{{trackname}}</a></td><td>{{metadata.artist}}</td><td><a href="#" class="album">{{metadata.album}}</a></td></tr>'); + this.track_item = Handlebars.compile('<tr id="{{type}}-{{id}}"><td><a href="#" class="{{type}}{{#unless cache}} nocache{{/unless}}">{{trackname}}</a></td><td><a href="#" class="artist">{{metadata.artist}}</a></td><td><a href="#" class="album">{{metadata.album}}</a></td></tr>'); // The playlist automatically adds a tr tag. - this.playlist_item = Handlebars.compile('<td><a href="#" class="play">{{trackname}}</a></td><td><a href="#" class="artist">{{metadata.artist}}</a></td><td><a href="#" class="album">{{metadata.album}}</a></td><td class="track-buttons"><a href="#" class="delete"><img src="/static/icons/delete.png" alt="Delete" title="Delete" /></a></td>'); + this.playlist_item = Handlebars.compile('<td><a href="#" class="track play">{{trackname}}</a></td><td><a href="#" class="artist">{{metadata.artist}}</a></td><td><a href="#" class="album">{{metadata.album}}</a></td><td class="track-buttons"><a href="#" class="delete"><img src="/static/icons/delete.png" alt="Delete" title="Delete" /></a></td>'); this.albums_item = Handlebars.compile('<div class="album-tile" id="albums-album-{{id}}"><a href="#album-tab-{{id}}" title="{{name}} by {{artist.name}}"><img src="/album-cover/{{id}}.jpg" alt="{{name}} by {{artist.name}}" /><br /><span class="album-name">{{name}}</span></div>'); - this.album_tab = Handlebars.compile('<div id="album-tab-{{id}}"><input type="button" value="Add selected" /><table id="album-tab-{{id}}-table" class="track-table"><tbody><tr><td><img src="/static/icons/loading.gif" alt="Loading..." /></td></tr></tbody></table></div>'); + this.album_tab = Handlebars.compile('<div id="album-tab-{{id}}"><input type="button" value="Add selected" /><table id="album-tab-{{id}}-table" class="track-table"><tbody><tr><td><img src="/static/icons/loading.gif" alt="Loading..." /> Loading...</td></tr></tbody></table></div>'); this.album_tabli = Handlebars.compile('<li><a href="{{tabid}}">Album: {{album.name}}</a> <span class="ui-icon ui-icon-close">Remove tab</span></li>'); + this.artist_tab = Handlebars.compile('<div id="artist-tab-{{id}}"><img src="/static/icons/loading.gif" alt="Loading..." /> Loading...</div>'); + this.artist_tabli = Handlebars.compile('<li><a href="{{tabid}}">Artist: {{artist.name}}</a> <span class="ui-icon ui-icon-close">Remove tab</span></li>'); })(); |