Merge branch 'develop' of https://github.com/mopidy/mopidy into feature/extra_tags
This commit is contained in:
commit
e12a75c880
@ -4,7 +4,7 @@ install:
|
||||
- "wget -O - http://apt.mopidy.com/mopidy.gpg | sudo apt-key add -"
|
||||
- "sudo wget -O /etc/apt/sources.list.d/mopidy.list http://apt.mopidy.com/mopidy.list"
|
||||
- "sudo apt-get update || true"
|
||||
- "sudo apt-get install $(apt-cache depends mopidy | awk '$2 !~ /mopidy/ {print $2}')"
|
||||
- "sudo apt-get install $(apt-cache depends mopidy | awk '$2 !~ /mopidy|python:any/ {print $2}')"
|
||||
- "pip install coveralls flake8"
|
||||
|
||||
before_script:
|
||||
|
||||
@ -4,6 +4,27 @@ Changelog
|
||||
|
||||
This changelog is used to track all major changes to Mopidy.
|
||||
|
||||
v0.17.0 (UNRELEASED)
|
||||
====================
|
||||
|
||||
**Core**
|
||||
|
||||
- The search field ``track`` has been renamed to ``track_name`` to avoid
|
||||
confusion with ``track_no``.
|
||||
|
||||
**Local backend**
|
||||
|
||||
- Fix search filtering by track number.
|
||||
|
||||
- When scanning, we no longer default the album artist to be the same as the
|
||||
track artist. Album artist is now only populated if the scanned file got an
|
||||
explicit album artist set.
|
||||
|
||||
**MPD frontend**
|
||||
|
||||
- Add support for ``list "albumartist" ...``.
|
||||
|
||||
|
||||
v0.16.0 (2013-10-27)
|
||||
====================
|
||||
|
||||
|
||||
@ -21,6 +21,12 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
|
||||
self._tag_cache_file = self.backend.config['local']['tag_cache_file']
|
||||
self.refresh()
|
||||
|
||||
def _convert_to_int(self, string):
|
||||
try:
|
||||
return int(string)
|
||||
except ValueError:
|
||||
return object()
|
||||
|
||||
def refresh(self, uri=None):
|
||||
logger.debug(
|
||||
'Loading local tracks from %s using %s',
|
||||
@ -61,12 +67,12 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
|
||||
# FIXME this is bound to be slow for large libraries
|
||||
for value in values:
|
||||
if field == 'track_no':
|
||||
q = value
|
||||
q = self._convert_to_int(value)
|
||||
else:
|
||||
q = value.strip()
|
||||
|
||||
uri_filter = lambda t: q == t.uri
|
||||
track_filter = lambda t: q == t.name
|
||||
track_name_filter = lambda t: q == t.name
|
||||
album_filter = lambda t: q == getattr(t, 'album', Album()).name
|
||||
artist_filter = lambda t: filter(
|
||||
lambda a: q == a.name, t.artists)
|
||||
@ -84,7 +90,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
|
||||
date_filter = lambda t: q == t.date
|
||||
any_filter = lambda t: (
|
||||
uri_filter(t) or
|
||||
track_filter(t) or
|
||||
track_name_filter(t) or
|
||||
album_filter(t) or
|
||||
artist_filter(t) or
|
||||
albumartist_filter(t) or
|
||||
@ -96,8 +102,8 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
|
||||
|
||||
if field == 'uri':
|
||||
result_tracks = filter(uri_filter, result_tracks)
|
||||
elif field == 'track':
|
||||
result_tracks = filter(track_filter, result_tracks)
|
||||
elif field == 'track_name':
|
||||
result_tracks = filter(track_name_filter, result_tracks)
|
||||
elif field == 'album':
|
||||
result_tracks = filter(album_filter, result_tracks)
|
||||
elif field == 'artist':
|
||||
@ -135,12 +141,12 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
|
||||
# FIXME this is bound to be slow for large libraries
|
||||
for value in values:
|
||||
if field == 'track_no':
|
||||
q = value
|
||||
q = self._convert_to_int(value)
|
||||
else:
|
||||
q = value.strip().lower()
|
||||
|
||||
uri_filter = lambda t: q in t.uri.lower()
|
||||
track_filter = lambda t: q in t.name.lower()
|
||||
track_name_filter = lambda t: q in t.name.lower()
|
||||
album_filter = lambda t: q in getattr(
|
||||
t, 'album', Album()).name.lower()
|
||||
artist_filter = lambda t: filter(
|
||||
@ -159,7 +165,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
|
||||
date_filter = lambda t: t.date and t.date.startswith(q)
|
||||
any_filter = lambda t: (
|
||||
uri_filter(t) or
|
||||
track_filter(t) or
|
||||
track_name_filter(t) or
|
||||
album_filter(t) or
|
||||
artist_filter(t) or
|
||||
albumartist_filter(t) or
|
||||
@ -171,8 +177,8 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
|
||||
|
||||
if field == 'uri':
|
||||
result_tracks = filter(uri_filter, result_tracks)
|
||||
elif field == 'track':
|
||||
result_tracks = filter(track_filter, result_tracks)
|
||||
elif field == 'track_name':
|
||||
result_tracks = filter(track_name_filter, result_tracks)
|
||||
elif field == 'album':
|
||||
result_tracks = filter(album_filter, result_tracks)
|
||||
elif field == 'artist':
|
||||
|
||||
@ -120,7 +120,6 @@ def _convert_mpd_data(data, tracks):
|
||||
|
||||
if 'artist' in data:
|
||||
artist_kwargs['name'] = data['artist']
|
||||
albumartist_kwargs['name'] = data['artist']
|
||||
|
||||
if 'albumartist' in data:
|
||||
albumartist_kwargs['name'] = data['albumartist']
|
||||
|
||||
@ -131,8 +131,8 @@ def findadd(context, mpd_query):
|
||||
|
||||
|
||||
@handle_request(
|
||||
r'^list "?(?P<field>([Aa]rtist|[Aa]lbum|[Cc]omposer|[Dd]ate|[Gg]enre|'
|
||||
r'[Pp]erformer))"?'
|
||||
r'^list "?(?P<field>([Aa]rtist|[Aa]lbumartist|[Aa]lbum|[Cc]omposer|'
|
||||
r'[Dd]ate|[Gg]enre|[Pp]erformer))"?'
|
||||
r'( (?P<mpd_query>.*))?$')
|
||||
def list_(context, field, mpd_query=None):
|
||||
"""
|
||||
@ -141,7 +141,7 @@ def list_(context, field, mpd_query=None):
|
||||
``list {TYPE} [ARTIST]``
|
||||
|
||||
Lists all tags of the specified type. ``TYPE`` should be ``album``,
|
||||
``artist``, ``date``, or ``genre``.
|
||||
``artist``, ``albumartist``, ``date``, or ``genre``.
|
||||
|
||||
``ARTIST`` is an optional parameter when type is ``album``,
|
||||
``date``, or ``genre``. This filters the result list by an artist.
|
||||
@ -223,6 +223,8 @@ def list_(context, field, mpd_query=None):
|
||||
return
|
||||
if field == 'artist':
|
||||
return _list_artist(context, query)
|
||||
if field == 'albumartist':
|
||||
return _list_albumartist(context, query)
|
||||
elif field == 'album':
|
||||
return _list_album(context, query)
|
||||
elif field == 'composer':
|
||||
@ -245,6 +247,17 @@ def _list_artist(context, query):
|
||||
return artists
|
||||
|
||||
|
||||
def _list_albumartist(context, query):
|
||||
albumartists = set()
|
||||
results = context.core.library.find_exact(**query).get()
|
||||
for track in _get_tracks(results):
|
||||
if track.album:
|
||||
for artist in track.album.artists:
|
||||
if artist.name:
|
||||
albumartists.add(('AlbumArtist', artist.name))
|
||||
return albumartists
|
||||
|
||||
|
||||
def _list_album(context, query):
|
||||
albums = set()
|
||||
results = context.core.library.find_exact(**query).get()
|
||||
|
||||
@ -47,9 +47,6 @@ def track_to_mpd_format(track, position=None):
|
||||
track.track_no, track.album.num_tracks)))
|
||||
else:
|
||||
result.append(('Track', track.track_no))
|
||||
if track.album is not None and track.album.artists:
|
||||
artists = artists_to_mpd_format(track.album.artists)
|
||||
result.append(('AlbumArtist', artists))
|
||||
if position is not None and tlid is not None:
|
||||
result.append(('Pos', position))
|
||||
result.append(('Id', tlid))
|
||||
@ -58,6 +55,8 @@ def track_to_mpd_format(track, position=None):
|
||||
# FIXME don't use first and best artist?
|
||||
# FIXME don't duplicate following code?
|
||||
if track.album is not None and track.album.artists:
|
||||
artists = artists_to_mpd_format(track.album.artists)
|
||||
result.append(('AlbumArtist', artists))
|
||||
artists = filter(
|
||||
lambda a: a.musicbrainz_id is not None, track.album.artists)
|
||||
if artists:
|
||||
@ -262,7 +261,7 @@ def query_from_mpd_search_format(mpd_query):
|
||||
m = MPD_SEARCH_QUERY_PART_RE.match(query_part)
|
||||
field = m.groupdict()['field'].lower()
|
||||
if field == 'title':
|
||||
field = 'track'
|
||||
field = 'track_name'
|
||||
elif field == 'track':
|
||||
field = 'track_no'
|
||||
elif field in ('file', 'filename'):
|
||||
|
||||
@ -41,7 +41,7 @@ def _format_dependency(dep_info):
|
||||
lines.append('%s: not found' % dep_info['name'])
|
||||
else:
|
||||
if 'path' in dep_info:
|
||||
source = ' from %s' % os.path.dirname(dep_info['path'])
|
||||
source = ' from %s' % dep_info['path']
|
||||
else:
|
||||
source = ''
|
||||
lines.append('%s: %s%s' % (
|
||||
@ -75,7 +75,7 @@ def python_info():
|
||||
'name': 'Python',
|
||||
'version': '%s %s' % (
|
||||
platform.python_implementation(), platform.python_version()),
|
||||
'path': platform.__file__,
|
||||
'path': os.path.dirname(platform.__file__),
|
||||
}
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@ def gstreamer_info():
|
||||
return {
|
||||
'name': 'GStreamer',
|
||||
'version': '.'.join(map(str, gst.get_gst_version())),
|
||||
'path': gst.__file__,
|
||||
'path': os.path.dirname(gst.__file__),
|
||||
'other': '\n'.join(other),
|
||||
}
|
||||
|
||||
|
||||
@ -45,10 +45,14 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
artists=[artists[3]], album=albums[2],
|
||||
date='2003', length=4000, track_no=3),
|
||||
Track(
|
||||
uri='local:track:path4', name='track4', genre='genre1',
|
||||
uri='local:track:path4', name='track4',
|
||||
artists=[artists[2]], album=albums[3],
|
||||
date='2004', length=60000, track_no=4),
|
||||
Track(
|
||||
uri='local:track:path5', name='track6', genre='genre1',
|
||||
album=albums[3], length=4000, composers=[artists[4]]),
|
||||
Track(
|
||||
uri='local:track:path5', name='track5', genre='genre2',
|
||||
uri='local:track:path6', name='track6', genre='genre2',
|
||||
album=albums[3], length=4000, performers=[artists[5]]),
|
||||
]
|
||||
|
||||
@ -111,12 +115,15 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
self.assertEqual(tracks, [])
|
||||
|
||||
def test_find_exact_no_hits(self):
|
||||
result = self.library.find_exact(track=['unknown track'])
|
||||
result = self.library.find_exact(track_name=['unknown track'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.find_exact(artist=['unknown artist'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.find_exact(albumartist=['unknown albumartist'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.find_exact(composer=['unknown composer'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
@ -132,7 +139,10 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
result = self.library.find_exact(genre=['unknown genre'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.find_exact(track_no=[9])
|
||||
result = self.library.find_exact(track_no=['9'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.find_exact(track_no=['no_match'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.find_exact(uri=['fake uri'])
|
||||
@ -151,10 +161,10 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
|
||||
|
||||
def test_find_exact_track(self):
|
||||
result = self.library.find_exact(track=['track1'])
|
||||
result = self.library.find_exact(track_name=['track1'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[:1])
|
||||
|
||||
result = self.library.find_exact(track=['track2'])
|
||||
result = self.library.find_exact(track_name=['track2'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
|
||||
|
||||
def test_find_exact_artist(self):
|
||||
@ -164,6 +174,9 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
result = self.library.find_exact(artist=['artist2'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
|
||||
|
||||
result = self.library.find_exact(artist=['artist3'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[3:4])
|
||||
|
||||
def test_find_exact_composer(self):
|
||||
result = self.library.find_exact(composer=['artist5'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[3:4])
|
||||
@ -193,10 +206,10 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
self.assertEqual(list(result[0].tracks), [self.tracks[2]])
|
||||
|
||||
def test_find_exact_track_no(self):
|
||||
result = self.library.find_exact(track_no=[1])
|
||||
result = self.library.find_exact(track_no=['1'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[:1])
|
||||
|
||||
result = self.library.find_exact(track_no=[2])
|
||||
result = self.library.find_exact(track_no=['2'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
|
||||
|
||||
def test_find_exact_genre(self):
|
||||
@ -237,7 +250,8 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
|
||||
# Matches on track album artists
|
||||
result = self.library.find_exact(any=['artist3'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[2:3])
|
||||
self.assertEqual(
|
||||
list(result[0].tracks), [self.tracks[3], self.tracks[2]])
|
||||
|
||||
# Matches on track composer
|
||||
result = self.library.find_exact(any=['artist5'])
|
||||
@ -270,19 +284,22 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
test = lambda: self.library.find_exact(artist=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.find_exact(albumartist=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.find_exact(track_name=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.find_exact(composer=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.find_exact(performer=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.find_exact(track=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.find_exact(album=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.find_exact(track_no=[])
|
||||
test = lambda: self.library.find_exact(track_no=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.find_exact(genre=[''])
|
||||
@ -295,22 +312,28 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
def test_search_no_hits(self):
|
||||
result = self.library.search(track=['unknown track'])
|
||||
result = self.library.search(track_name=['unknown track'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.search(artist=['unknown artist'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.search(albumartist=['unknown albumartist'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.search(composer=['unknown composer'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.search(performer=['unknown performer'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.search(album=['unknown artist'])
|
||||
result = self.library.search(album=['unknown album'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.search(track_no=[9])
|
||||
result = self.library.search(track_no=['9'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.search(track_no=['no_match'])
|
||||
self.assertEqual(list(result[0].tracks), [])
|
||||
|
||||
result = self.library.search(genre=['unknown genre'])
|
||||
@ -333,10 +356,10 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
|
||||
|
||||
def test_search_track(self):
|
||||
result = self.library.search(track=['Rack1'])
|
||||
result = self.library.search(track_name=['Rack1'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[:1])
|
||||
|
||||
result = self.library.search(track=['Rack2'])
|
||||
result = self.library.search(track_name=['Rack2'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
|
||||
|
||||
def test_search_artist(self):
|
||||
@ -395,10 +418,10 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
|
||||
|
||||
def test_search_track_no(self):
|
||||
result = self.library.search(track_no=[1])
|
||||
result = self.library.search(track_no=['1'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[:1])
|
||||
|
||||
result = self.library.search(track_no=[2])
|
||||
result = self.library.search(track_no=['2'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
|
||||
|
||||
def test_search_any(self):
|
||||
@ -427,7 +450,8 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
|
||||
# Matches on track album artists
|
||||
result = self.library.search(any=['Tist3'])
|
||||
self.assertEqual(list(result[0].tracks), self.tracks[2:3])
|
||||
self.assertEqual(
|
||||
list(result[0].tracks), [self.tracks[3], self.tracks[2]])
|
||||
|
||||
# Matches on track genre
|
||||
result = self.library.search(any=['Enre1'])
|
||||
@ -448,13 +472,16 @@ class LocalLibraryProviderTest(unittest.TestCase):
|
||||
test = lambda: self.library.search(artist=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.search(albumartist=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.search(composer=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.search(performer=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.search(track=[''])
|
||||
test = lambda: self.library.search(track_name=[''])
|
||||
self.assertRaises(LookupError, test)
|
||||
|
||||
test = lambda: self.library.search(album=[''])
|
||||
|
||||
@ -93,28 +93,30 @@ class URItoM3UTest(unittest.TestCase):
|
||||
|
||||
expected_artists = [Artist(name='name')]
|
||||
expected_albums = [
|
||||
Album(name='albumname', artists=expected_artists, num_tracks=2)]
|
||||
Album(name='albumname', artists=expected_artists, num_tracks=2),
|
||||
Album(name='albumname', num_tracks=2),
|
||||
]
|
||||
expected_tracks = []
|
||||
|
||||
|
||||
def generate_track(path, ident):
|
||||
def generate_track(path, ident, album_id):
|
||||
uri = 'local:track:%s' % path
|
||||
track = Track(
|
||||
uri=uri, name='trackname', artists=expected_artists,
|
||||
album=expected_albums[0], track_no=1, date='2006', length=4000,
|
||||
album=expected_albums[album_id], track_no=1, date='2006', length=4000,
|
||||
last_modified=1272319626)
|
||||
expected_tracks.append(track)
|
||||
|
||||
|
||||
generate_track('song1.mp3', 6)
|
||||
generate_track('song2.mp3', 7)
|
||||
generate_track('song3.mp3', 8)
|
||||
generate_track('subdir1/song4.mp3', 2)
|
||||
generate_track('subdir1/song5.mp3', 3)
|
||||
generate_track('subdir2/song6.mp3', 4)
|
||||
generate_track('subdir2/song7.mp3', 5)
|
||||
generate_track('subdir1/subsubdir/song8.mp3', 0)
|
||||
generate_track('subdir1/subsubdir/song9.mp3', 1)
|
||||
generate_track('song1.mp3', 6, 0)
|
||||
generate_track('song2.mp3', 7, 0)
|
||||
generate_track('song3.mp3', 8, 1)
|
||||
generate_track('subdir1/song4.mp3', 2, 0)
|
||||
generate_track('subdir1/song5.mp3', 3, 0)
|
||||
generate_track('subdir2/song6.mp3', 4, 1)
|
||||
generate_track('subdir2/song7.mp3', 5, 1)
|
||||
generate_track('subdir1/subsubdir/song8.mp3', 0, 0)
|
||||
generate_track('subdir1/subsubdir/song9.mp3', 1, 1)
|
||||
|
||||
|
||||
class MPDTagCacheToTracksTest(unittest.TestCase):
|
||||
|
||||
@ -11,6 +11,7 @@ key: song8.mp3
|
||||
file: subdir1/subsubdir/song8.mp3
|
||||
Time: 4
|
||||
Artist: name
|
||||
AlbumArtist: name
|
||||
Title: trackname
|
||||
Album: albumname
|
||||
Track: 1/2
|
||||
@ -32,6 +33,7 @@ key: song4.mp3
|
||||
file: subdir1/song4.mp3
|
||||
Time: 4
|
||||
Artist: name
|
||||
AlbumArtist: name
|
||||
Title: trackname
|
||||
Album: albumname
|
||||
Track: 1/2
|
||||
@ -41,6 +43,7 @@ key: song5.mp3
|
||||
file: subdir1/song5.mp3
|
||||
Time: 4
|
||||
Artist: name
|
||||
AlbumArtist: name
|
||||
Title: trackname
|
||||
Album: albumname
|
||||
Track: 1/2
|
||||
@ -76,6 +79,7 @@ key: song1.mp3
|
||||
file: /song1.mp3
|
||||
Time: 4
|
||||
Artist: name
|
||||
AlbumArtist: name
|
||||
Title: trackname
|
||||
Album: albumname
|
||||
Track: 1/2
|
||||
@ -85,6 +89,7 @@ key: song2.mp3
|
||||
file: /song2.mp3
|
||||
Time: 4
|
||||
Artist: name
|
||||
AlbumArtist: name
|
||||
Title: trackname
|
||||
Album: albumname
|
||||
Track: 1/2
|
||||
|
||||
@ -6,6 +6,7 @@ songList begin
|
||||
key: key1
|
||||
file: /path1
|
||||
Artist: artist1
|
||||
AlbumArtist: artist1
|
||||
Title: track1
|
||||
Album: album1
|
||||
Date: 2001-02-03
|
||||
@ -14,6 +15,7 @@ Time: 4
|
||||
key: key2
|
||||
file: /path2
|
||||
Artist: artist2
|
||||
AlbumArtist: artist2
|
||||
Title: track2
|
||||
Album: album2
|
||||
Date: 2002
|
||||
@ -30,13 +32,21 @@ Track: 3
|
||||
Time: 4
|
||||
key: key4
|
||||
file: /path4
|
||||
Artist: artist3
|
||||
Title: track4
|
||||
Album: album4
|
||||
Date: 2004
|
||||
Track: 4
|
||||
Time: 60
|
||||
key: key5
|
||||
file: /path5
|
||||
Composer: artist5
|
||||
Title: track4
|
||||
Album: album4
|
||||
Genre: genre1
|
||||
Time: 4
|
||||
key: key5
|
||||
file: /path5
|
||||
key: key6
|
||||
file: /path6
|
||||
Performer: artist6
|
||||
Title: track5
|
||||
Album: album4
|
||||
|
||||
@ -7,6 +7,7 @@ key: song1.mp3
|
||||
file: /song1.mp3
|
||||
Time: 4
|
||||
Artist: name
|
||||
AlbumArtist: name
|
||||
Title: trackname
|
||||
Album: albumname
|
||||
Track: 1/2
|
||||
|
||||
@ -7,6 +7,7 @@ key: song1.mp3
|
||||
file: /song1.mp3
|
||||
Time: 4
|
||||
Artist: æøå
|
||||
AlbumArtist: æøå
|
||||
Title: æøå
|
||||
Album: æøå
|
||||
mtime: 1272319626
|
||||
|
||||
@ -398,6 +398,66 @@ class MusicDatabaseListTest(protocol.BaseTestCase):
|
||||
self.assertNotInResponse('Artist: ')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
### Albumartist
|
||||
|
||||
def test_list_albumartist_with_quotes(self):
|
||||
self.sendRequest('list "albumartist"')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_without_quotes(self):
|
||||
self.sendRequest('list albumartist')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_without_quotes_and_capitalized(self):
|
||||
self.sendRequest('list Albumartist')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_with_query_of_one_token(self):
|
||||
self.sendRequest('list "albumartist" "anartist"')
|
||||
self.assertEqualResponse(
|
||||
'ACK [2@0] {list} should be "Album" for 3 arguments')
|
||||
|
||||
def test_list_albumartist_with_unknown_field_in_query_returns_ack(self):
|
||||
self.sendRequest('list "albumartist" "foo" "bar"')
|
||||
self.assertEqualResponse('ACK [2@0] {list} not able to parse args')
|
||||
|
||||
def test_list_albumartist_by_artist(self):
|
||||
self.sendRequest('list "albumartist" "artist" "anartist"')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_by_album(self):
|
||||
self.sendRequest('list "albumartist" "album" "analbum"')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_by_full_date(self):
|
||||
self.sendRequest('list "albumartist" "date" "2001-01-01"')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_by_year(self):
|
||||
self.sendRequest('list "albumartist" "date" "2001"')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_by_genre(self):
|
||||
self.sendRequest('list "albumartist" "genre" "agenre"')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_by_artist_and_album(self):
|
||||
self.sendRequest(
|
||||
'list "albumartist" "artist" "anartist" "album" "analbum"')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_without_filter_value(self):
|
||||
self.sendRequest('list "albumartist" "artist" ""')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_list_albumartist_should_not_return_artists_without_names(self):
|
||||
self.backend.library.dummy_find_exact_result = SearchResult(
|
||||
tracks=[Track(album=Album(artists=[Artist(name='')]))])
|
||||
|
||||
self.sendRequest('list "albumartist"')
|
||||
self.assertNotInResponse('Artist: ')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
### Album
|
||||
|
||||
def test_list_album_with_quotes(self):
|
||||
|
||||
@ -20,7 +20,7 @@ class DepsTest(unittest.TestCase):
|
||||
lambda: dict(name='Platform', version='Loonix 4.0.1'),
|
||||
lambda: dict(
|
||||
name='Pykka', version='1.1',
|
||||
path='/foo/bar/baz.py', other='Quux'),
|
||||
path='/foo/bar', other='Quux'),
|
||||
lambda: dict(name='Foo'),
|
||||
lambda: dict(name='Mopidy', version='0.13', dependencies=[
|
||||
dict(name='pylast', version='0.5', dependencies=[
|
||||
@ -58,6 +58,7 @@ class DepsTest(unittest.TestCase):
|
||||
self.assertIn(platform.python_implementation(), result['version'])
|
||||
self.assertIn(platform.python_version(), result['version'])
|
||||
self.assertIn('python', result['path'])
|
||||
self.assertNotIn('platform.py', result['path'])
|
||||
|
||||
def test_gstreamer_info(self):
|
||||
result = deps.gstreamer_info()
|
||||
@ -66,6 +67,7 @@ class DepsTest(unittest.TestCase):
|
||||
self.assertEquals(
|
||||
'.'.join(map(str, gst.get_gst_version())), result['version'])
|
||||
self.assertIn('gst', result['path'])
|
||||
self.assertNotIn('__init__.py', result['path'])
|
||||
self.assertIn('Python wrapper: gst-python', result['other'])
|
||||
self.assertIn(
|
||||
'.'.join(map(str, gst.get_pygst_version())), result['other'])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user