diff -Nru mopidy-mpd-3.0.0/CHANGELOG.rst mopidy-mpd-3.1.0/CHANGELOG.rst --- mopidy-mpd-3.0.0/CHANGELOG.rst 2019-12-22 16:15:17.000000000 +0000 +++ mopidy-mpd-3.1.0/CHANGELOG.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -********* -Changelog -********* - - -v3.0.0 (2019-12-22) -=================== - -- Depend on final release of Mopidy 3.0.0. - -- Minor documentation improvements. - - -v3.0.0rc1 (2019-12-21) -====================== - -Initial release which extracts the Mopidy-MPD extension from Mopidy core. - -This is an alpha release because it depends on the pre-releases of Mopidy 3.0. - -Changes since Mopidy 2.3: - -- Improved the ``swap`` command to swap the tracks without rebuilding - the full tracklist. diff -Nru mopidy-mpd-3.0.0/.circleci/config.yml mopidy-mpd-3.1.0/.circleci/config.yml --- mopidy-mpd-3.0.0/.circleci/config.yml 2019-12-22 09:08:26.000000000 +0000 +++ mopidy-mpd-3.1.0/.circleci/config.yml 2020-12-05 01:59:58.000000000 +0000 @@ -7,6 +7,7 @@ version: 2 test: jobs: + - py39 - py38 - py37 - black @@ -14,9 +15,9 @@ - flake8 jobs: - py38: &test-template + py39: &test-template docker: - - image: mopidy/ci-python:3.8 + - image: mopidy/ci-python:3.9 steps: - checkout - restore_cache: @@ -39,6 +40,11 @@ - store_test_results: path: test-results + py38: + <<: *test-template + docker: + - image: mopidy/ci-python:3.8 + py37: <<: *test-template docker: diff -Nru mopidy-mpd-3.0.0/debian/changelog mopidy-mpd-3.1.0/debian/changelog --- mopidy-mpd-3.0.0/debian/changelog 2020-01-08 08:37:03.000000000 +0000 +++ mopidy-mpd-3.1.0/debian/changelog 2020-12-26 16:33:35.000000000 +0000 @@ -1,3 +1,19 @@ +mopidy-mpd (3.1.0-1) unstable; urgency=medium + + [ Debian Janitor ] + * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, + Repository-Browse. + * Update standards version to 4.5.0, no changes needed. + + [ Stein Magnus Jodal ] + * New upstream release + * d/watch: Use HTTPS + * d/control: Set Rules-Requires-Root to no + * d/rules: Remove changelog override + * d/control: Fix too long line + + -- Stein Magnus Jodal Sat, 26 Dec 2020 17:33:35 +0100 + mopidy-mpd (3.0.0-2) unstable; urgency=medium * Source-only upload to allow migration to testing; no changes diff -Nru mopidy-mpd-3.0.0/debian/control mopidy-mpd-3.1.0/debian/control --- mopidy-mpd-3.0.0/debian/control 2019-12-26 16:16:31.000000000 +0000 +++ mopidy-mpd-3.1.0/debian/control 2020-12-26 16:33:08.000000000 +0000 @@ -7,7 +7,8 @@ mopidy (>= 3), python3, python3-setuptools, -Standards-Version: 4.4.1 +Standards-Version: 4.5.0 +Rules-Requires-Root: no Homepage: https://mopidy.com/ Vcs-Git: https://salsa.debian.org/mopidy-team/mopidy-mpd.git Vcs-Browser: https://salsa.debian.org/mopidy-team/mopidy-mpd @@ -21,4 +22,5 @@ and more. You can edit the playlist from any phone, tablet, or computer using a variety of MPD and web clients. . - This package provides a Mopidy extension for controlling Mopidy from MPD clients. + This package provides a Mopidy extension for controlling Mopidy from MPD + clients. diff -Nru mopidy-mpd-3.0.0/debian/rules mopidy-mpd-3.1.0/debian/rules --- mopidy-mpd-3.0.0/debian/rules 2019-12-26 16:11:58.000000000 +0000 +++ mopidy-mpd-3.1.0/debian/rules 2020-12-26 16:32:42.000000000 +0000 @@ -7,6 +7,3 @@ %: dh $@ --with python3 --buildsystem=pybuild - -override_dh_installchangelogs: - dh_installchangelogs CHANGELOG.rst diff -Nru mopidy-mpd-3.0.0/debian/upstream/metadata mopidy-mpd-3.1.0/debian/upstream/metadata --- mopidy-mpd-3.0.0/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ mopidy-mpd-3.1.0/debian/upstream/metadata 2020-12-02 21:40:10.000000000 +0000 @@ -0,0 +1,5 @@ +--- +Bug-Database: https://github.com/mopidy/mopidy-mpd/issues +Bug-Submit: https://github.com/mopidy/mopidy-mpd/issues/new +Repository: https://github.com/mopidy/mopidy-mpd.git +Repository-Browse: https://github.com/mopidy/mopidy-mpd diff -Nru mopidy-mpd-3.0.0/debian/watch mopidy-mpd-3.1.0/debian/watch --- mopidy-mpd-3.0.0/debian/watch 2019-12-26 16:17:32.000000000 +0000 +++ mopidy-mpd-3.1.0/debian/watch 2020-12-26 16:32:16.000000000 +0000 @@ -1,3 +1,3 @@ version=3 opts=uversionmangle=s/(rc|a|b|c)/~$1/ \ -http://pypi.debian.net/Mopidy-MPD/Mopidy-MPD-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) +https://pypi.debian.net/Mopidy-MPD/Mopidy-MPD-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) diff -Nru mopidy-mpd-3.0.0/.github/workflows/release.yml mopidy-mpd-3.1.0/.github/workflows/release.yml --- mopidy-mpd-3.0.0/.github/workflows/release.yml 1970-01-01 00:00:00.000000000 +0000 +++ mopidy-mpd-3.1.0/.github/workflows/release.yml 2020-12-05 01:59:58.000000000 +0000 @@ -0,0 +1,23 @@ +name: Release + +on: + release: + types: [published] + +jobs: + release: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '3.9' + - name: "Install dependencies" + run: python3 -m pip install wheel + - name: "Build package" + run: python3 setup.py sdist bdist_wheel + - uses: pypa/gh-action-pypi-publish@v1.4.1 + with: + user: __token__ + password: ${{ secrets.PYPI_TOKEN }} diff -Nru mopidy-mpd-3.0.0/mopidy_mpd/dispatcher.py mopidy-mpd-3.1.0/mopidy_mpd/dispatcher.py --- mopidy-mpd-3.0.0/mopidy_mpd/dispatcher.py 2019-12-22 09:08:26.000000000 +0000 +++ mopidy-mpd-3.1.0/mopidy_mpd/dispatcher.py 2020-12-05 01:59:58.000000000 +0000 @@ -305,6 +305,9 @@ while path_and_futures: base_path, future = path_and_futures.pop() for ref in future.get(): + if ref.name is None or ref.uri is None: + continue + path = "/".join([base_path, ref.name.replace("/", "")]) path = self._uri_map.insert(path, ref.uri) diff -Nru mopidy-mpd-3.0.0/mopidy_mpd/protocol/music_db.py mopidy-mpd-3.1.0/mopidy_mpd/protocol/music_db.py --- mopidy-mpd-3.0.0/mopidy_mpd/protocol/music_db.py 2019-12-22 09:08:26.000000000 +0000 +++ mopidy-mpd-3.1.0/mopidy_mpd/protocol/music_db.py 2020-12-05 01:59:58.000000000 +0000 @@ -259,12 +259,12 @@ """ params = list(args) if not params: - raise exceptions.MpdArgError("incorrect arguments") + raise exceptions.MpdArgError('too few arguments for "list"') - field = params.pop(0).lower() - field = _LIST_MAPPING.get(field) + field_arg = params.pop(0).lower() + field = _LIST_MAPPING.get(field_arg) if field is None: - raise exceptions.MpdArgError("incorrect arguments") + raise exceptions.MpdArgError(f"Unknown tag type: {field_arg}") query = None if len(params) == 1: @@ -274,11 +274,9 @@ query = {"artist": params} else: try: - query = _query_from_mpd_search_parameters(params, _LIST_MAPPING) + query = _query_from_mpd_search_parameters(params, _SEARCH_MAPPING) except exceptions.MpdArgError as exc: - exc.message = ( # noqa B306: Our own exception - "not able to parse args" - ) + exc.message = "Unknown filter type" # noqa B306: Our own exception raise except ValueError: return @@ -307,7 +305,7 @@ result = [] for path, track_ref in context.browse(uri, lookup=False): if not track_ref: - result.append(("directory", path)) + result.append(("directory", path.lstrip("/"))) else: result.append(("file", track_ref.uri)) @@ -336,7 +334,7 @@ result = [] for path, lookup_future in context.browse(uri): if not lookup_future: - result.append(("directory", path)) + result.append(("directory", path.lstrip("/"))) else: for tracks in lookup_future.get().values(): for track in tracks: diff -Nru mopidy-mpd-3.0.0/Mopidy_MPD.egg-info/PKG-INFO mopidy-mpd-3.1.0/Mopidy_MPD.egg-info/PKG-INFO --- mopidy-mpd-3.0.0/Mopidy_MPD.egg-info/PKG-INFO 2019-12-22 16:16:19.000000000 +0000 +++ mopidy-mpd-3.1.0/Mopidy_MPD.egg-info/PKG-INFO 2020-12-05 02:00:04.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Mopidy-MPD -Version: 3.0.0 +Version: 3.1.0 Summary: Mopidy extension for controlling Mopidy from MPD clients Home-page: https://github.com/mopidy/mopidy-mpd Author: Stein Magnus Jodal @@ -173,7 +173,7 @@ - `Source code `_ - `Issue tracker `_ - - `Changelog `_ + - `Changelog `_ Credits @@ -194,6 +194,7 @@ Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Multimedia :: Sound/Audio :: Players Requires-Python: >=3.7 Provides-Extra: lint diff -Nru mopidy-mpd-3.0.0/Mopidy_MPD.egg-info/SOURCES.txt mopidy-mpd-3.1.0/Mopidy_MPD.egg-info/SOURCES.txt --- mopidy-mpd-3.0.0/Mopidy_MPD.egg-info/SOURCES.txt 2019-12-22 16:16:19.000000000 +0000 +++ mopidy-mpd-3.1.0/Mopidy_MPD.egg-info/SOURCES.txt 2020-12-05 02:00:04.000000000 +0000 @@ -1,4 +1,3 @@ -CHANGELOG.rst LICENSE MANIFEST.in README.rst @@ -7,6 +6,7 @@ setup.py tox.ini .circleci/config.yml +.github/workflows/release.yml Mopidy_MPD.egg-info/PKG-INFO Mopidy_MPD.egg-info/SOURCES.txt Mopidy_MPD.egg-info/dependency_links.txt diff -Nru mopidy-mpd-3.0.0/PKG-INFO mopidy-mpd-3.1.0/PKG-INFO --- mopidy-mpd-3.0.0/PKG-INFO 2019-12-22 16:16:19.000000000 +0000 +++ mopidy-mpd-3.1.0/PKG-INFO 2020-12-05 02:00:04.985046600 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Mopidy-MPD -Version: 3.0.0 +Version: 3.1.0 Summary: Mopidy extension for controlling Mopidy from MPD clients Home-page: https://github.com/mopidy/mopidy-mpd Author: Stein Magnus Jodal @@ -173,7 +173,7 @@ - `Source code `_ - `Issue tracker `_ - - `Changelog `_ + - `Changelog `_ Credits @@ -194,6 +194,7 @@ Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Multimedia :: Sound/Audio :: Players Requires-Python: >=3.7 Provides-Extra: lint diff -Nru mopidy-mpd-3.0.0/README.rst mopidy-mpd-3.1.0/README.rst --- mopidy-mpd-3.0.0/README.rst 2019-12-22 16:14:24.000000000 +0000 +++ mopidy-mpd-3.1.0/README.rst 2020-12-05 01:59:58.000000000 +0000 @@ -165,7 +165,7 @@ - `Source code `_ - `Issue tracker `_ -- `Changelog `_ +- `Changelog `_ Credits diff -Nru mopidy-mpd-3.0.0/setup.cfg mopidy-mpd-3.1.0/setup.cfg --- mopidy-mpd-3.0.0/setup.cfg 2019-12-22 16:16:19.000000000 +0000 +++ mopidy-mpd-3.1.0/setup.cfg 2020-12-05 02:00:04.985046600 +0000 @@ -1,6 +1,6 @@ [metadata] name = Mopidy-MPD -version = 3.0.0 +version = 3.1.0 url = https://github.com/mopidy/mopidy-mpd author = Stein Magnus Jodal author_email = stein.magnus@jodal.no @@ -16,6 +16,7 @@ Programming Language :: Python :: 3 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 Topic :: Multimedia :: Sound/Audio :: Players [options] diff -Nru mopidy-mpd-3.0.0/tests/dummy_audio.py mopidy-mpd-3.1.0/tests/dummy_audio.py --- mopidy-mpd-3.0.0/tests/dummy_audio.py 2019-12-22 09:08:27.000000000 +0000 +++ mopidy-mpd-3.1.0/tests/dummy_audio.py 2020-12-05 01:59:58.000000000 +0000 @@ -28,7 +28,7 @@ self._tags = {} self._bad_uris = set() - def set_uri(self, uri, live_stream=False): + def set_uri(self, uri, live_stream=False, download=False): assert self._uri is None, "prepare change not called before set" self._position = 0 self._uri = uri diff -Nru mopidy-mpd-3.0.0/tests/protocol/test_music_db.py mopidy-mpd-3.1.0/tests/protocol/test_music_db.py --- mopidy-mpd-3.0.0/tests/protocol/test_music_db.py 2019-12-22 09:08:27.000000000 +0000 +++ mopidy-mpd-3.1.0/tests/protocol/test_music_db.py 2020-12-05 01:59:58.000000000 +0000 @@ -179,10 +179,10 @@ self.send_request("listall") self.assertInResponse("file: dummy:/a") - self.assertInResponse("directory: /dummy/foo") - self.assertInResponse("directory: /dummy/album") - self.assertInResponse("directory: /dummy/artist") - self.assertInResponse("directory: /dummy/pl") + self.assertInResponse("directory: dummy/foo") + self.assertInResponse("directory: dummy/album") + self.assertInResponse("directory: dummy/artist") + self.assertInResponse("directory: dummy/pl") self.assertInResponse("file: dummy:/foo/b") self.assertInResponse("OK") @@ -203,7 +203,7 @@ self.send_request('listall "/dummy/foo"') self.assertNotInResponse("file: dummy:/a") - self.assertInResponse("directory: /dummy/foo") + self.assertInResponse("directory: dummy/foo") self.assertInResponse("file: dummy:/foo/b") self.assertInResponse("OK") @@ -245,8 +245,8 @@ } self.send_request("listall") - self.assertInResponse("directory: /dummy/a") - self.assertInResponse("directory: /dummy/a [2]") + self.assertInResponse("directory: dummy/a") + self.assertInResponse("directory: dummy/a [2]") def test_listallinfo_without_uri(self): tracks = [ @@ -269,10 +269,10 @@ self.assertInResponse("file: dummy:/a") self.assertInResponse("Title: a") - self.assertInResponse("directory: /dummy/foo") - self.assertInResponse("directory: /dummy/album") - self.assertInResponse("directory: /dummy/artist") - self.assertInResponse("directory: /dummy/pl") + self.assertInResponse("directory: dummy/foo") + self.assertInResponse("directory: dummy/album") + self.assertInResponse("directory: dummy/artist") + self.assertInResponse("directory: dummy/pl") self.assertInResponse("file: dummy:/foo/b") self.assertInResponse("Title: b") self.assertInResponse("OK") @@ -295,7 +295,7 @@ self.assertNotInResponse("file: dummy:/a") self.assertNotInResponse("Title: a") - self.assertInResponse("directory: /dummy/foo") + self.assertInResponse("directory: dummy/foo") self.assertInResponse("file: dummy:/foo/b") self.assertInResponse("Title: b") self.assertInResponse("OK") @@ -338,8 +338,8 @@ } self.send_request("listallinfo") - self.assertInResponse("directory: /dummy/a") - self.assertInResponse("directory: /dummy/a [2]") + self.assertInResponse("directory: dummy/a") + self.assertInResponse("directory: dummy/a [2]") def test_listfiles(self): self.send_request("listfiles") @@ -733,7 +733,13 @@ def test_list_foo_returns_ack(self): self.send_request('list "foo"') - self.assertEqualResponse("ACK [2@0] {list} incorrect arguments") + self.assertEqualResponse("ACK [2@0] {list} Unknown tag type: foo") + + def test_list_without_type_returns_ack(self): + self.send_request("list") + self.assertEqualResponse( + 'ACK [2@0] {list} too few arguments for "list"' + ) # Track title @@ -741,6 +747,10 @@ self.send_request('list "title"') self.assertInResponse("OK") + def test_list_title_by_title(self): + self.send_request('list "title" "title" "atitle"') + self.assertInResponse("OK") + # Artist def test_list_artist_with_quotes(self): @@ -763,7 +773,7 @@ def test_list_artist_with_unknown_field_in_query_returns_ack(self): self.send_request('list "artist" "foo" "bar"') - self.assertEqualResponse("ACK [2@0] {list} not able to parse args") + self.assertEqualResponse("ACK [2@0] {list} Unknown filter type") def test_list_artist_by_artist(self): self.send_request('list "artist" "artist" "anartist"') @@ -824,7 +834,7 @@ def test_list_albumartist_with_unknown_field_in_query_returns_ack(self): self.send_request('list "albumartist" "foo" "bar"') - self.assertEqualResponse("ACK [2@0] {list} not able to parse args") + self.assertEqualResponse("ACK [2@0] {list} Unknown filter type") def test_list_albumartist_by_artist(self): self.send_request('list "albumartist" "artist" "anartist"') @@ -890,7 +900,7 @@ def test_list_composer_with_unknown_field_in_query_returns_ack(self): self.send_request('list "composer" "foo" "bar"') - self.assertEqualResponse("ACK [2@0] {list} not able to parse args") + self.assertEqualResponse("ACK [2@0] {list} Unknown filter type") def test_list_composer_by_artist(self): self.send_request('list "composer" "artist" "anartist"') @@ -956,7 +966,7 @@ def test_list_performer_with_unknown_field_in_query_returns_ack(self): self.send_request('list "performer" "foo" "bar"') - self.assertEqualResponse("ACK [2@0] {list} not able to parse args") + self.assertEqualResponse("ACK [2@0] {list} Unknown filter type") def test_list_performer_by_artist(self): self.send_request('list "performer" "artist" "anartist"') diff -Nru mopidy-mpd-3.0.0/tests/test_dispatcher.py mopidy-mpd-3.1.0/tests/test_dispatcher.py --- mopidy-mpd-3.0.0/tests/test_dispatcher.py 2019-12-22 09:08:27.000000000 +0000 +++ mopidy-mpd-3.1.0/tests/test_dispatcher.py 2020-12-05 01:59:58.000000000 +0000 @@ -1,10 +1,13 @@ import unittest import pykka +import pytest from mopidy import core -from mopidy_mpd.dispatcher import MpdDispatcher +from mopidy.models import Ref +from mopidy_mpd.dispatcher import MpdContext, MpdDispatcher from mopidy_mpd.exceptions import MpdAckError +from mopidy_mpd.uri_mapper import MpdUriMapper from tests import dummy_backend @@ -39,3 +42,71 @@ result[0] == 'ACK [0@0] {disabled} "disabled" has been disabled in the server' ) + + +@pytest.fixture +def a_track(): + return Ref.track(uri="dummy:/a", name="a") + + +@pytest.fixture +def b_track(): + return Ref.track(uri="dummy:/foo/b", name="b") + + +@pytest.fixture +def backend_to_browse(a_track, b_track): + backend = dummy_backend.create_proxy() + backend.library.dummy_browse_result = { + "dummy:/": [a_track, Ref.directory(uri="dummy:/foo", name="foo")], + "dummy:/foo": [b_track], + } + return backend + + +@pytest.fixture +def mpd_context(backend_to_browse): + mopidy_core = core.Core.start(backends=[backend_to_browse]).proxy() + uri_map = MpdUriMapper(mopidy_core) + return MpdContext(None, core=mopidy_core, uri_map=uri_map) + + +class TestMpdContext: + @classmethod + def teardown_class(cls): + pykka.ActorRegistry.stop_all() + + def test_browse_root(self, mpd_context, a_track): + results = mpd_context.browse("dummy", recursive=False, lookup=False) + + assert [("/dummy/a", a_track), ("/dummy/foo", None)] == list(results) + + def test_browse_root_recursive(self, mpd_context, a_track, b_track): + results = mpd_context.browse("dummy", recursive=True, lookup=False) + + assert [ + ("/dummy", None), + ("/dummy/a", a_track), + ("/dummy/foo", None), + ("/dummy/foo/b", b_track), + ] == list(results) + + @pytest.mark.parametrize( + "bad_ref", + [ + Ref.track(uri="dummy:/x"), + Ref.track(name="x"), + Ref.directory(uri="dummy:/y"), + Ref.directory(name="y"), + ], + ) + def test_browse_skips_bad_refs( + self, backend_to_browse, a_track, bad_ref, mpd_context + ): + backend_to_browse.library.dummy_browse_result = { + "dummy:/": [bad_ref, a_track], + } + + results = mpd_context.browse("dummy", recursive=False, lookup=False) + + assert [("/dummy/a", a_track)] == list(results) diff -Nru mopidy-mpd-3.0.0/tests/test_status.py mopidy-mpd-3.1.0/tests/test_status.py --- mopidy-mpd-3.0.0/tests/test_status.py 2019-12-22 09:08:27.000000000 +0000 +++ mopidy-mpd-3.1.0/tests/test_status.py 2020-12-05 01:59:58.000000000 +0000 @@ -27,7 +27,10 @@ self.backend = dummy_backend.create_proxy(audio=self.audio) self.core = core.Core.start( - config, audio=self.audio, mixer=self.mixer, backends=[self.backend], + config, + audio=self.audio, + mixer=self.mixer, + backends=[self.backend], ).proxy() self.dispatcher = dispatcher.MpdDispatcher(core=self.core) diff -Nru mopidy-mpd-3.0.0/tox.ini mopidy-mpd-3.1.0/tox.ini --- mopidy-mpd-3.0.0/tox.ini 2019-12-22 09:08:27.000000000 +0000 +++ mopidy-mpd-3.1.0/tox.ini 2020-12-05 01:59:58.000000000 +0000 @@ -1,5 +1,5 @@ [tox] -envlist = py37, py38, black, check-manifest, flake8 +envlist = py37, py38, py39, black, check-manifest, flake8 [testenv] sitepackages = true