Merge pull request #1443 from tkem/fix/1428

Fix #1428: Add m3u/base_dir confval.
This commit is contained in:
Stein Magnus Jodal 2016-02-14 12:14:21 +01:00
commit 69a52bf031
6 changed files with 49 additions and 2 deletions

View File

@ -55,6 +55,9 @@ Local backend
M3U backend
-----------
- Add :confval:`m3u/base_dir` for resolving relative paths in M3U
files. (Fixes: :issue:`1428`, PR: :issue:`1442`)
- Derive track name from file name for non-extended M3U
playlists. (Fixes: :issue:`1364`, PR: :issue:`1369`)

View File

@ -55,6 +55,12 @@ See :ref:`config` for general help on configuring Mopidy.
Path to directory with M3U files. Unset by default, in which case the
extension's data dir is used to store playlists.
.. confval:: m3u/base_dir
Path to base directory for resolving relative paths in M3U files.
If not set, relative paths are resolved based on the M3U file's
location.
.. confval:: m3u/default_encoding
Text encoding used for files with extension ``.m3u``. Default is

View File

@ -21,6 +21,7 @@ class Extension(ext.Extension):
def get_config_schema(self):
schema = super(Extension, self).get_config_schema()
schema['base_dir'] = config.Path(optional=True)
schema['default_encoding'] = config.String()
schema['default_extension'] = config.String(choices=['.m3u', '.m3u8'])
schema['playlists_dir'] = config.Path(optional=True)

View File

@ -1,5 +1,6 @@
[m3u]
enabled = true
playlists_dir =
base_dir = $XDG_MUSIC_DIR
default_encoding = latin-1
default_extension = .m3u8

View File

@ -60,6 +60,7 @@ class M3UPlaylistsProvider(backend.PlaylistsProvider):
self._playlists_dir = Extension.get_data_dir(config)
else:
self._playlists_dir = ext_config['playlists_dir']
self._base_dir = ext_config['base_dir'] or self._playlists_dir
self._default_encoding = ext_config['default_encoding']
self._default_extension = ext_config['default_extension']
@ -97,7 +98,7 @@ class M3UPlaylistsProvider(backend.PlaylistsProvider):
path = translator.uri_to_path(uri)
try:
with self._open(path, 'r') as fp:
items = translator.load_items(fp, self._playlists_dir)
items = translator.load_items(fp, self._base_dir)
except EnvironmentError as e:
log_environment_error('Error reading playlist %s' % uri, e)
else:
@ -107,7 +108,7 @@ class M3UPlaylistsProvider(backend.PlaylistsProvider):
path = translator.uri_to_path(uri)
try:
with self._open(path, 'r') as fp:
items = translator.load_items(fp, self._playlists_dir)
items = translator.load_items(fp, self._base_dir)
mtime = os.path.getmtime(self._abspath(path))
except EnvironmentError as e:
log_environment_error('Error reading playlist %s' % uri, e)

View File

@ -24,6 +24,7 @@ class M3UPlaylistsProviderTest(unittest.TestCase):
config = {
'm3u': {
'enabled': True,
'base_dir': None,
'default_encoding': 'latin-1',
'default_extension': '.m3u',
'playlists_dir': path_to_data_dir(''),
@ -33,6 +34,7 @@ class M3UPlaylistsProviderTest(unittest.TestCase):
def setUp(self): # noqa: N802
self.config['m3u']['playlists_dir'] = tempfile.mkdtemp()
self.playlists_dir = self.config['m3u']['playlists_dir']
self.base_dir = self.config['m3u']['base_dir'] or self.playlists_dir
audio = dummy_audio.create_proxy()
backend = M3UBackend.start(
@ -261,6 +263,32 @@ class M3UPlaylistsProviderTest(unittest.TestCase):
self.assertEqual(playlist.name, result.name)
self.assertEqual(track.uri, result.tracks[0].uri)
def test_playlist_with_absolute_path(self):
track = Track(uri='/tmp/test.mp3')
filepath = b'/tmp/test.mp3'
playlist = self.core.playlists.create('test')
playlist = playlist.replace(tracks=[track])
playlist = self.core.playlists.save(playlist)
self.assertEqual(len(self.core.playlists.as_list()), 1)
result = self.core.playlists.lookup('m3u:test.m3u')
self.assertEqual('m3u:test.m3u', result.uri)
self.assertEqual(playlist.name, result.name)
self.assertEqual('file://' + filepath, result.tracks[0].uri)
def test_playlist_with_relative_path(self):
track = Track(uri='test.mp3')
filepath = os.path.join(self.base_dir, b'test.mp3')
playlist = self.core.playlists.create('test')
playlist = playlist.replace(tracks=[track])
playlist = self.core.playlists.save(playlist)
self.assertEqual(len(self.core.playlists.as_list()), 1)
result = self.core.playlists.lookup('m3u:test.m3u')
self.assertEqual('m3u:test.m3u', result.uri)
self.assertEqual(playlist.name, result.name)
self.assertEqual('file://' + filepath, result.tracks[0].uri)
def test_playlist_sort_order(self):
def check_order(playlists, names):
self.assertEqual(names, [playlist.name for playlist in playlists])
@ -303,6 +331,13 @@ class M3UPlaylistsProviderTest(unittest.TestCase):
self.assertIsNone(item_refs)
class M3UPlaylistsProviderBaseDirectoryTest(M3UPlaylistsProviderTest):
def setUp(self): # noqa: N802
self.config['m3u']['base_dir'] = tempfile.mkdtemp()
super(M3UPlaylistsProviderBaseDirectoryTest, self).setUp()
class DeprecatedM3UPlaylistsProviderTest(M3UPlaylistsProviderTest):
def run(self, result=None):