Skip to content

Commit

Permalink
add browsing feature so that ncmpcpp and friends can see subsonic stuffs
Browse files Browse the repository at this point in the history
  • Loading branch information
evanscottgray committed May 18, 2016
1 parent b7f2756 commit 2267bcf
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
125 changes: 125 additions & 0 deletions mopidy_subsonic/browse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from __future__ import unicode_literals
import logging
from mopidy import models

logger = logging.getLogger(__name__)

ROOT_DIR = models.Ref.directory(
uri='subsonic:directory', name='Subsonic')

_ROOT_DIR_CONTENTS = [
models.Ref.directory(
uri='subsonic:artists', name='Artists'),
models.Ref.directory(
uri='subsonic:debug', name='debug'),
]


def _get_artist_albums(remote, uri):
artist_id = uri.split(':')[2]

albums = remote.id_to_albums(artist_id)
return albums


def _album_to_ref(album):
name = album.get('title', 'Unknown Album')
uri = 'subsonic:album:%s' % album.get('id')
return models.Ref.directory(uri=uri, name=name)


def _track_to_ref(remote, track, with_track_no=False):
name = ''
try:
if with_track_no and track.get('track') > 0:
name = '%d - ' % track.get('track')
name += track.get('title', 'Unknown Title')
uri = 'subsonic://%s' % track.get('id')
except:
uri = track.uri
name = track.name
return models.Ref.track(uri=uri, name=name)


def _get_artist_tracks(remote, uri):
artist_id = uri.split(':')[2]
tracks = remote.get_tracks_by_artist_id(artist_id)
return tracks


def _browse_artist_all_tracks(remote, uri):
refs = []
for track in _get_artist_tracks(remote, uri):
trackref = _track_to_ref(remote, track)
refs.append(trackref)
return refs


def _get_album_tracks(remote, uri):
album_id = uri.split(':')[2]

tracks = remote.id_to_dir(album_id)
return tracks


def _browse_album(remote, uri):
refs = []
for track in _get_album_tracks(remote, uri):
trackref = _track_to_ref(remote, track, True)
refs.append(trackref)
return refs


def _browse_artist(remote, uri):
refs = []
for album in _get_artist_albums(remote, uri):
refs.append(_album_to_ref(album))
refs.sort(key=lambda ref: ref.name)
if len(refs) > 0:
refs.insert(0, models.Ref.directory(uri=uri + ':all',
name='All Tracks'))
return refs
else:
# Show all tracks if no album is available
return _browse_artist_all_tracks(remote, uri)


def _artist_to_ref(artist):
artist_name = next(iter(artist.artists))
if artist_name.name:
name = artist_name.name
else:
name = 'Unknown artist'

artist_id = artist.uri.split('//')[-1]
uri = 'subsonic:artist:%s' % artist_id
return models.Ref.directory(uri=uri, name=name)


def _browse_artists(remote):
refs = []
for artist in remote.get_artists():
refs.append(_artist_to_ref(artist))
refs.sort(key=lambda ref: ref.name)
return refs


def browse(remote, uri):

parts = uri.split(':')

logger.debug('GOT URI |%s|' % uri)

if uri == ROOT_DIR.uri:
return _ROOT_DIR_CONTENTS
if uri == 'subsonic:artists':
return _browse_artists(remote)

if len(parts) == 3 and parts[1] == 'artist':
return _browse_artist(remote, uri)

if len(parts) == 3 and parts[1] == 'album':
return _browse_album(remote, uri)

if len(parts) == 4 and parts[1] == 'artist' and parts[3] == 'all':
return _browse_artist_all_tracks(remote, uri)
12 changes: 12 additions & 0 deletions mopidy_subsonic/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,18 @@ def get_tracks_by(self, artist_query, album_query):

return tracks

@cache()
def get_tracks_by_artist_id(self, artist_id):
albums = makelist(self.id_to_albums(artist_id))

tracks = []
for album in albums:
album = self.album_to_tracks(album)
album = [x for x in album if x is not None]
tracks.extend(album)

return tracks

@cache()
def get_song(self, id):
try:
Expand Down
6 changes: 6 additions & 0 deletions mopidy_subsonic/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

from mopidy import backend
from mopidy.models import SearchResult
from mopidy_subsonic import browse

logger = logging.getLogger(__name__)


class SubsonicLibraryProvider(backend.LibraryProvider):

root_directory = browse.ROOT_DIR

def __init__(self, *args, **kwargs):
super(SubsonicLibraryProvider, self).__init__(*args, **kwargs)
self.remote = self.backend.remote
Expand All @@ -26,6 +29,9 @@ def _find_exact(self, query=None, uris=None):
tracks=self.remote.get_tracks_by(
query.get('artist'), query.get('album')))

def browse(self, uri):
return browse.browse(self.remote, uri)

def search(self, query=None, uris=None, exact=False):
if exact:
return self._find_exact(query=query, uris=uris)
Expand Down

0 comments on commit 2267bcf

Please sign in to comment.