From 039fc4b6816835bed2fe99ea6a90977edc9b6685 Mon Sep 17 00:00:00 2001 From: nathanharper Date: Wed, 22 Jan 2014 04:09:25 -0500 Subject: [PATCH 1/2] refactored mpd.protocol.music_db regex got quote backreference working, eliminated need for the non-capturing pattern, fixed problem with quoted fields. --- mopidy/mpd/protocol/music_db.py | 35 +++++++++-------------------- tests/mpd/protocol/test_music_db.py | 2 +- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/mopidy/mpd/protocol/music_db.py b/mopidy/mpd/protocol/music_db.py index 58681557..e821af6b 100644 --- a/mopidy/mpd/protocol/music_db.py +++ b/mopidy/mpd/protocol/music_db.py @@ -62,30 +62,15 @@ SEARCH_QUERY = r""" $ """ -# TODO Would be nice to get ("?)...\1 working for the quotes here -SEARCH_PAIR_WITHOUT_GROUPS = r""" +SEARCH_PAIR_WITH_GROUPS = r""" + ("?) # Optional quote around the field type \b # Only begin matching at word bundaries - "? # Optional quote around the field type - (?: # A non-capturing group for the field type + ( # A capturing group for the field type """ + SEARCH_FIELDS + """ ) - "? # End of optional quote around the field type + \\1 # End of optional quote around the field type \ # A single space - "[^"]+" # Matching a quoted search string -""" -SEARCH_PAIR_WITHOUT_GROUPS_RE = re.compile( - SEARCH_PAIR_WITHOUT_GROUPS, flags=(re.UNICODE | re.VERBOSE)) - -# TODO Would be nice to get ("?)...\1 working for the quotes here -SEARCH_PAIR_WITH_GROUPS = r""" - \b # Only begin matching at word bundaries - "? # Optional quote around the field type - (?P( # A capturing group for the field type -""" + SEARCH_FIELDS + """ - )) - "? # End of optional quote around the field type - \ # A single space - "(?P[^"]+)" # Capturing a quoted search string + "([^"]+)" # Capturing a quoted search string """ SEARCH_PAIR_WITH_GROUPS_RE = re.compile( SEARCH_PAIR_WITH_GROUPS, flags=(re.UNICODE | re.VERBOSE)) @@ -99,18 +84,18 @@ def _query_from_mpd_search_format(mpd_query): :param mpd_query: the MPD search query :type mpd_query: string """ - pairs = SEARCH_PAIR_WITHOUT_GROUPS_RE.findall(mpd_query) + matches = SEARCH_PAIR_WITH_GROUPS_RE.findall(mpd_query) query = {} - for pair in pairs: - m = SEARCH_PAIR_WITH_GROUPS_RE.match(pair) - field = m.groupdict()['field'].lower() + # discard first field, which just captures optional quote + for _, field, what in matches: + field = field.lower() if field == 'title': field = 'track_name' elif field == 'track': field = 'track_no' elif field in ('file', 'filename'): field = 'uri' - what = m.groupdict()['what'] + if not what: raise ValueError if field in query: diff --git a/tests/mpd/protocol/test_music_db.py b/tests/mpd/protocol/test_music_db.py index 8d74fb95..bb36f3e2 100644 --- a/tests/mpd/protocol/test_music_db.py +++ b/tests/mpd/protocol/test_music_db.py @@ -12,7 +12,7 @@ from tests.mpd import protocol class QueryFromMpdSearchFormatTest(unittest.TestCase): def test_dates_are_extracted(self): result = music_db._query_from_mpd_search_format( - 'Date "1974-01-02" Date "1975"') + 'Date "1974-01-02" "Date" "1975"') self.assertEqual(result['date'][0], '1974-01-02') self.assertEqual(result['date'][1], '1975') From 3a184f9ddd55816b1c9d3bfa72b429d1e8ecbf77 Mon Sep 17 00:00:00 2001 From: nathanharper Date: Wed, 22 Jan 2014 04:30:27 -0500 Subject: [PATCH 2/2] decouple mpd.protocol module from config structure removed reference to password from protocol, moved it to Context class. --- mopidy/mpd/dispatcher.py | 7 ++++--- mopidy/mpd/protocol/connection.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/mopidy/mpd/dispatcher.py b/mopidy/mpd/dispatcher.py index 6aeace9d..0a916408 100644 --- a/mopidy/mpd/dispatcher.py +++ b/mopidy/mpd/dispatcher.py @@ -229,8 +229,8 @@ class MpdContext(object): #: The current :class:`mopidy.mpd.MpdSession`. session = None - #: The Mopidy configuration. - config = None + #: The MPD password + password = None #: The Mopidy core API. An instance of :class:`mopidy.core.Core`. core = None @@ -246,7 +246,8 @@ class MpdContext(object): def __init__(self, dispatcher, session=None, config=None, core=None): self.dispatcher = dispatcher self.session = session - self.config = config + if config is not None: + self.password = config['mpd']['password'] self.core = core self.events = set() self.subscriptions = set() diff --git a/mopidy/mpd/protocol/connection.py b/mopidy/mpd/protocol/connection.py index a6f9ffcb..41ee9e6a 100644 --- a/mopidy/mpd/protocol/connection.py +++ b/mopidy/mpd/protocol/connection.py @@ -39,7 +39,7 @@ def password(context, password): This is used for authentication with the server. ``PASSWORD`` is simply the plaintext password. """ - if password == context.config['mpd']['password']: + if password == context.password: context.dispatcher.authenticated = True else: raise MpdPasswordError('incorrect password')