Skip to content

Commit

Permalink
Merge 38bbaee into f9c09a8
Browse files Browse the repository at this point in the history
  • Loading branch information
jodal committed Oct 27, 2013
2 parents f9c09a8 + 38bbaee commit 310ae7f
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 14 deletions.
6 changes: 3 additions & 3 deletions mopidy/frontends/mpd/protocol/music_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@


QUERY_RE = (
r'(?P<mpd_query>("?([Aa]lbum|[Aa]rtist|[Dd]ate|[Ff]ile|[Ff]ilename|'
r'[Tt]itle|[Aa]ny)"? "[^"]*"\s?)+)$')
r'(?P<mpd_query>("?([Aa]lbum|[Aa]rtist|[Aa]lbumartist|[Dd]ate|[Ff]ile|'
r'[Ff]ilename|[Tt]itle|[Aa]ny)"? "[^"]*"\s?)+)$')


def _get_field(field, search_results):
Expand Down Expand Up @@ -91,7 +91,7 @@ def find(context, mpd_query):
return
results = context.core.library.find_exact(**query).get()
result_tracks = []
if 'artist' not in query:
if 'artist' not in query and 'albumartist' not in query:
result_tracks += [_artist_as_track(a) for a in _get_artists(results)]
if 'album' not in query:
result_tracks += [_album_as_track(a) for a in _get_albums(results)]
Expand Down
53 changes: 42 additions & 11 deletions mopidy/frontends/mpd/translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,46 @@ def query_from_mpd_list_format(field, mpd_query):
raise MpdArgError('not able to parse args', command='list')


# XXX The regexps below should be refactored to reuse common patterns here
# and in mopidy.frontends.mpd.protocol.music_db.QUERY_RE.

MPD_SEARCH_QUERY_RE = re.compile(r"""
\b # Only begin matching at word bundaries
"? # Optional quote around the field type
(?: # A non-capturing group for the field type
[Aa]lbum
| [Aa]rtist
| [Aa]lbumartist
| [Dd]ate
| [Ff]ile
| [Ff]ilename
| [Tt]itle
| [Aa]ny
)
"? # End of optional quote around the field type
\s # A single space
"[^"]+" # Matching a quoted search string
""", re.VERBOSE)

MPD_SEARCH_QUERY_PART_RE = re.compile(r"""
\b # Only begin matching at word bundaries
"? # Optional quote around the field type
(?P<field>( # A capturing group for the field type
[Aa]lbum
| [Aa]rtist
| [Aa]lbumartist
| [Dd]ate
| [Ff]ile
| [Ff]ilename
| [Tt]itle
| [Aa]ny
))
"? # End of optional quote around the field type
\s # A single space
"(?P<what>[^"]+)" # Capturing a quoted search string
""", re.VERBOSE)


def query_from_mpd_search_format(mpd_query):
"""
Parses an MPD ``search`` or ``find`` query and converts it to the Mopidy
Expand All @@ -187,24 +227,15 @@ def query_from_mpd_search_format(mpd_query):
:param mpd_query: the MPD search query
:type mpd_query: string
"""
# XXX The regexps below should be refactored to reuse common patterns here
# and in mopidy.frontends.mpd.protocol.music_db.
query_pattern = (
r'"?(?:[Aa]lbum|[Aa]rtist|[Dd]ate|[Ff]ile|[Ff]ilename|'
r'[Tt]itle|[Aa]ny)"? "[^"]+"')
query_parts = re.findall(query_pattern, mpd_query)
query_part_pattern = (
r'"?(?P<field>([Aa]lbum|[Aa]rtist|[Dd]ate|[Ff]ile|[Ff]ilename|'
r'[Tt]itle|[Aa]ny))"? "(?P<what>[^"]+)"')
query_parts = MPD_SEARCH_QUERY_RE.findall(mpd_query)
query = {}
for query_part in query_parts:
m = re.match(query_part_pattern, query_part)
m = MPD_SEARCH_QUERY_PART_RE.match(query_part)
field = m.groupdict()['field'].lower()
if field == 'title':
field = 'track'
elif field in ('file', 'filename'):
field = 'uri'
field = str(field) # Needed for kwargs keys on OS X and Windows
what = m.groupdict()['what']
if not what:
raise ValueError
Expand Down
40 changes: 40 additions & 0 deletions tests/frontends/mpd/protocol/music_db_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,26 @@ def test_find_artist_does_not_include_fake_artist_tracks(self):

self.assertInResponse('OK')

def test_find_albumartist_does_not_include_fake_artist_tracks(self):
self.backend.library.dummy_find_exact_result = SearchResult(
albums=[Album(uri='dummy:album:a', name='A', date='2001')],
artists=[Artist(uri='dummy:artist:b', name='B')],
tracks=[Track(uri='dummy:track:c', name='C')])

self.sendRequest('find "albumartist" "foo"')

self.assertNotInResponse('file: dummy:artist:b')
self.assertNotInResponse('Title: Artist: B')

self.assertInResponse('file: dummy:album:a')
self.assertInResponse('Title: Album: A')
self.assertInResponse('Date: 2001')

self.assertInResponse('file: dummy:track:c')
self.assertInResponse('Title: C')

self.assertInResponse('OK')

def test_find_artist_and_album_does_not_include_fake_tracks(self):
self.backend.library.dummy_find_exact_result = SearchResult(
albums=[Album(uri='dummy:album:a', name='A', date='2001')],
Expand Down Expand Up @@ -211,6 +231,14 @@ def test_find_artist_without_quotes(self):
self.sendRequest('find artist "what"')
self.assertInResponse('OK')

def test_find_albumartist(self):
self.sendRequest('find "albumartist" "what"')
self.assertInResponse('OK')

def test_find_albumartist_without_quotes(self):
self.sendRequest('find albumartist "what"')
self.assertInResponse('OK')

def test_find_filename(self):
self.sendRequest('find "filename" "afilename"')
self.assertInResponse('OK')
Expand Down Expand Up @@ -545,6 +573,18 @@ def test_search_artist_without_filter_value(self):
self.sendRequest('search "artist" ""')
self.assertInResponse('OK')

def test_search_albumartist(self):
self.sendRequest('search "albumartist" "analbumartist"')
self.assertInResponse('OK')

def test_search_albumartist_without_quotes(self):
self.sendRequest('search albumartist "analbumartist"')
self.assertInResponse('OK')

def test_search_albumartist_without_filter_value(self):
self.sendRequest('search "albumartist" ""')
self.assertInResponse('OK')

def test_search_filename(self):
self.sendRequest('search "filename" "afilename"')
self.assertInResponse('OK')
Expand Down

0 comments on commit 310ae7f

Please sign in to comment.