mpd: Use new config system
This commit is contained in:
parent
8a8a78e025
commit
c452f0115a
@ -5,7 +5,6 @@ import sys
|
||||
|
||||
import pykka
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.core import CoreListener
|
||||
from mopidy.frontends.mpd import session
|
||||
from mopidy.utils import encoding, network, process
|
||||
@ -16,17 +15,21 @@ logger = logging.getLogger('mopidy.frontends.mpd')
|
||||
class MpdFrontend(pykka.ThreadingActor, CoreListener):
|
||||
def __init__(self, config, core):
|
||||
super(MpdFrontend, self).__init__()
|
||||
hostname = network.format_hostname(settings.MPD_SERVER_HOSTNAME)
|
||||
port = settings.MPD_SERVER_PORT
|
||||
hostname = network.format_hostname(config['mpd']['hostname'])
|
||||
port = config['mpd']['port']
|
||||
|
||||
# NOTE kwargs dict keys must be bytestrings to work on Python < 2.6.5
|
||||
# See https://github.com/mopidy/mopidy/issues/302 for details.
|
||||
try:
|
||||
network.Server(
|
||||
hostname, port,
|
||||
protocol=session.MpdSession, protocol_kwargs={b'core': core},
|
||||
max_connections=settings.MPD_SERVER_MAX_CONNECTIONS,
|
||||
timeout=settings.MPD_SERVER_CONNECTION_TIMEOUT)
|
||||
protocol=session.MpdSession,
|
||||
protocol_kwargs={
|
||||
b'config': config,
|
||||
b'core': core,
|
||||
},
|
||||
max_connections=config['mpd']['max_connections'],
|
||||
timeout=config['mpd']['connection_timeout'])
|
||||
except IOError as error:
|
||||
logger.error(
|
||||
'MPD server startup failed: %s',
|
||||
|
||||
@ -5,7 +5,6 @@ import re
|
||||
|
||||
import pykka
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.frontends.mpd import exceptions, protocol
|
||||
|
||||
logger = logging.getLogger('mopidy.frontends.mpd.dispatcher')
|
||||
@ -22,13 +21,15 @@ class MpdDispatcher(object):
|
||||
|
||||
_noidle = re.compile(r'^noidle$')
|
||||
|
||||
def __init__(self, session=None, core=None):
|
||||
def __init__(self, session=None, config=None, core=None):
|
||||
self.config = config
|
||||
self.authenticated = False
|
||||
self.command_list_receiving = False
|
||||
self.command_list_ok = False
|
||||
self.command_list = []
|
||||
self.command_list_index = None
|
||||
self.context = MpdContext(self, session=session, core=core)
|
||||
self.context = MpdContext(
|
||||
self, session=session, config=config, core=core)
|
||||
|
||||
def handle_request(self, request, current_command_list_index=None):
|
||||
"""Dispatch incoming requests to the correct handler."""
|
||||
@ -82,7 +83,7 @@ class MpdDispatcher(object):
|
||||
def _authenticate_filter(self, request, response, filter_chain):
|
||||
if self.authenticated:
|
||||
return self._call_next_filter(request, response, filter_chain)
|
||||
elif settings.MPD_SERVER_PASSWORD is None:
|
||||
elif self.config['mpd']['password'] is None:
|
||||
self.authenticated = True
|
||||
return self._call_next_filter(request, response, filter_chain)
|
||||
else:
|
||||
@ -223,6 +224,9 @@ class MpdContext(object):
|
||||
#: The current :class:`mopidy.frontends.mpd.MpdSession`.
|
||||
session = None
|
||||
|
||||
#: The Mopidy configuration.
|
||||
config = None
|
||||
|
||||
#: The Mopidy core API. An instance of :class:`mopidy.core.Core`.
|
||||
core = None
|
||||
|
||||
@ -232,9 +236,10 @@ class MpdContext(object):
|
||||
#: The subsytems that we want to be notified about in idle mode.
|
||||
subscriptions = None
|
||||
|
||||
def __init__(self, dispatcher, session=None, core=None):
|
||||
def __init__(self, dispatcher, session=None, config=None, core=None):
|
||||
self.dispatcher = dispatcher
|
||||
self.session = session
|
||||
self.config = config
|
||||
self.core = core
|
||||
self.events = set()
|
||||
self.subscriptions = set()
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.frontends.mpd.protocol import handle_request
|
||||
from mopidy.frontends.mpd.exceptions import (
|
||||
MpdPasswordError, MpdPermissionError)
|
||||
@ -40,7 +39,7 @@ def password_(context, password):
|
||||
This is used for authentication with the server. ``PASSWORD`` is
|
||||
simply the plaintext password.
|
||||
"""
|
||||
if password == settings.MPD_SERVER_PASSWORD:
|
||||
if password == context.config['mpd']['password']:
|
||||
context.dispatcher.authenticated = True
|
||||
else:
|
||||
raise MpdPasswordError('incorrect password', command='password')
|
||||
|
||||
@ -18,9 +18,10 @@ class MpdSession(network.LineProtocol):
|
||||
encoding = protocol.ENCODING
|
||||
delimiter = r'\r?\n'
|
||||
|
||||
def __init__(self, connection, core=None):
|
||||
def __init__(self, connection, config=None, core=None):
|
||||
super(MpdSession, self).__init__(connection)
|
||||
self.dispatcher = dispatcher.MpdDispatcher(session=self, core=core)
|
||||
self.dispatcher = dispatcher.MpdDispatcher(
|
||||
session=self, config=config, core=core)
|
||||
|
||||
def on_start(self):
|
||||
logger.info('New MPD connection from [%s]:%s', self.host, self.port)
|
||||
|
||||
@ -5,7 +5,6 @@ import re
|
||||
import shlex
|
||||
import urllib
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.frontends.mpd import protocol
|
||||
from mopidy.frontends.mpd.exceptions import MpdArgError
|
||||
from mopidy.models import TlTrack
|
||||
@ -216,12 +215,14 @@ def query_from_mpd_search_format(mpd_query):
|
||||
return query
|
||||
|
||||
|
||||
def tracks_to_tag_cache_format(tracks):
|
||||
def tracks_to_tag_cache_format(tracks, music_path):
|
||||
"""
|
||||
Format list of tracks for output to MPD tag cache
|
||||
|
||||
:param tracks: the tracks
|
||||
:type tracks: list of :class:`mopidy.models.Track`
|
||||
:param music_path: the path to the music dir
|
||||
:type music_path: string
|
||||
:rtype: list of lists of two-tuples
|
||||
"""
|
||||
result = [
|
||||
@ -231,14 +232,15 @@ def tracks_to_tag_cache_format(tracks):
|
||||
('info_end',)
|
||||
]
|
||||
tracks.sort(key=lambda t: t.uri)
|
||||
_add_to_tag_cache(result, *tracks_to_directory_tree(tracks))
|
||||
folders, files = tracks_to_directory_tree(tracks, music_path)
|
||||
_add_to_tag_cache(result, folders, files, music_path)
|
||||
return result
|
||||
|
||||
|
||||
def _add_to_tag_cache(result, folders, files):
|
||||
base_path = settings.LOCAL_MUSIC_PATH.encode('utf-8')
|
||||
def _add_to_tag_cache(result, folders, files, music_path):
|
||||
base_path = music_path.encode('utf-8')
|
||||
|
||||
for path, entry in folders.items():
|
||||
for path, (entry_folders, entry_files) in folders.items():
|
||||
try:
|
||||
text_path = path.decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
@ -247,7 +249,7 @@ def _add_to_tag_cache(result, folders, files):
|
||||
result.append(('directory', text_path))
|
||||
result.append(('mtime', get_mtime(os.path.join(base_path, path))))
|
||||
result.append(('begin', name))
|
||||
_add_to_tag_cache(result, *entry)
|
||||
_add_to_tag_cache(result, entry_folders, entry_files, music_path)
|
||||
result.append(('end', name))
|
||||
|
||||
result.append(('songList begin',))
|
||||
@ -273,7 +275,7 @@ def _add_to_tag_cache(result, folders, files):
|
||||
result.append(('songList end',))
|
||||
|
||||
|
||||
def tracks_to_directory_tree(tracks):
|
||||
def tracks_to_directory_tree(tracks, music_path):
|
||||
directories = ({}, [])
|
||||
|
||||
for track in tracks:
|
||||
@ -282,8 +284,7 @@ def tracks_to_directory_tree(tracks):
|
||||
|
||||
absolute_track_dir_path = os.path.dirname(uri_to_path(track.uri))
|
||||
relative_track_dir_path = re.sub(
|
||||
'^' + re.escape(settings.LOCAL_MUSIC_PATH), b'',
|
||||
absolute_track_dir_path)
|
||||
'^' + re.escape(music_path), b'', absolute_track_dir_path)
|
||||
|
||||
for part in split_path(relative_track_dir_path):
|
||||
path = os.path.join(path, part)
|
||||
|
||||
@ -42,6 +42,7 @@ from mopidy.utils import log, path, versioning
|
||||
|
||||
def main():
|
||||
options = parse_options()
|
||||
config = {} # TODO Read config from new config system
|
||||
|
||||
log.setup_root_logger()
|
||||
log.setup_console_logging(options.verbosity_level)
|
||||
@ -67,7 +68,8 @@ def main():
|
||||
|
||||
logging.info('Done scanning; writing tag cache...')
|
||||
|
||||
for row in mpd_translator.tracks_to_tag_cache_format(tracks):
|
||||
for row in mpd_translator.tracks_to_tag_cache_format(
|
||||
tracks, config['mpd']['music_path']):
|
||||
if len(row) == 1:
|
||||
print ('%s' % row).encode('utf-8')
|
||||
else:
|
||||
|
||||
@ -13,9 +13,14 @@ from tests import unittest
|
||||
|
||||
class MpdDispatcherTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
config = {
|
||||
'mpd': {
|
||||
'password': None,
|
||||
}
|
||||
}
|
||||
self.backend = dummy.create_dummy_backend_proxy()
|
||||
self.core = core.Core.start(backends=[self.backend]).proxy()
|
||||
self.dispatcher = MpdDispatcher()
|
||||
self.dispatcher = MpdDispatcher(config=config)
|
||||
|
||||
def tearDown(self):
|
||||
pykka.ActorRegistry.stop_all()
|
||||
|
||||
@ -23,12 +23,20 @@ class MockConnection(mock.Mock):
|
||||
|
||||
|
||||
class BaseTestCase(unittest.TestCase):
|
||||
def get_config(self):
|
||||
return {
|
||||
'mpd': {
|
||||
'password': None,
|
||||
}
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
self.backend = dummy.create_dummy_backend_proxy()
|
||||
self.core = core.Core.start(backends=[self.backend]).proxy()
|
||||
|
||||
self.connection = MockConnection()
|
||||
self.session = session.MpdSession(self.connection, core=self.core)
|
||||
self.session = session.MpdSession(
|
||||
self.connection, config=self.get_config(), core=self.core)
|
||||
self.dispatcher = self.session.dispatcher
|
||||
self.context = self.dispatcher.context
|
||||
|
||||
|
||||
@ -1,63 +1,56 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from mopidy import settings
|
||||
|
||||
from tests.frontends.mpd import protocol
|
||||
|
||||
|
||||
class AuthenticationTest(protocol.BaseTestCase):
|
||||
def test_authentication_with_valid_password_is_accepted(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'topsecret'
|
||||
class AuthenticationActiveTest(protocol.BaseTestCase):
|
||||
def get_config(self):
|
||||
config = super(AuthenticationActiveTest, self).get_config()
|
||||
config['mpd']['password'] = 'topsecret'
|
||||
return config
|
||||
|
||||
def test_authentication_with_valid_password_is_accepted(self):
|
||||
self.sendRequest('password "topsecret"')
|
||||
self.assertTrue(self.dispatcher.authenticated)
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_authentication_with_invalid_password_is_not_accepted(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'topsecret'
|
||||
|
||||
self.sendRequest('password "secret"')
|
||||
self.assertFalse(self.dispatcher.authenticated)
|
||||
self.assertEqualResponse('ACK [3@0] {password} incorrect password')
|
||||
|
||||
def test_authentication_with_anything_when_password_check_turned_off(self):
|
||||
settings.MPD_SERVER_PASSWORD = None
|
||||
|
||||
self.sendRequest('any request at all')
|
||||
self.assertTrue(self.dispatcher.authenticated)
|
||||
self.assertEqualResponse('ACK [5@0] {} unknown command "any"')
|
||||
|
||||
def test_anything_when_not_authenticated_should_fail(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'topsecret'
|
||||
|
||||
self.sendRequest('any request at all')
|
||||
self.assertFalse(self.dispatcher.authenticated)
|
||||
self.assertEqualResponse(
|
||||
u'ACK [4@0] {any} you don\'t have permission for "any"')
|
||||
|
||||
def test_close_is_allowed_without_authentication(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'topsecret'
|
||||
|
||||
self.sendRequest('close')
|
||||
self.assertFalse(self.dispatcher.authenticated)
|
||||
|
||||
def test_commands_is_allowed_without_authentication(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'topsecret'
|
||||
|
||||
self.sendRequest('commands')
|
||||
self.assertFalse(self.dispatcher.authenticated)
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_notcommands_is_allowed_without_authentication(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'topsecret'
|
||||
|
||||
self.sendRequest('notcommands')
|
||||
self.assertFalse(self.dispatcher.authenticated)
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_ping_is_allowed_without_authentication(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'topsecret'
|
||||
|
||||
self.sendRequest('ping')
|
||||
self.assertFalse(self.dispatcher.authenticated)
|
||||
self.assertInResponse('OK')
|
||||
|
||||
|
||||
class AuthenticationInactiveTest(protocol.BaseTestCase):
|
||||
def test_authentication_with_anything_when_password_check_turned_off(self):
|
||||
self.sendRequest('any request at all')
|
||||
self.assertTrue(self.dispatcher.authenticated)
|
||||
self.assertEqualResponse('ACK [5@0] {} unknown command "any"')
|
||||
|
||||
def test_any_password_is_not_accepted_when_password_check_turned_off(self):
|
||||
self.sendRequest('password "secret"')
|
||||
self.assertEqualResponse('ACK [3@0] {password} incorrect password')
|
||||
|
||||
@ -2,8 +2,6 @@ from __future__ import unicode_literals
|
||||
|
||||
from mock import patch
|
||||
|
||||
from mopidy import settings
|
||||
|
||||
from tests.frontends.mpd import protocol
|
||||
|
||||
|
||||
@ -26,21 +24,6 @@ class ConnectionHandlerTest(protocol.BaseTestCase):
|
||||
self.assertEqualResponse(
|
||||
'ACK [4@0] {kill} you don\'t have permission for "kill"')
|
||||
|
||||
def test_valid_password_is_accepted(self):
|
||||
settings.MPD_SERVER_PASSWORD = 'topsecret'
|
||||
self.sendRequest('password "topsecret"')
|
||||
self.assertEqualResponse('OK')
|
||||
|
||||
def test_invalid_password_is_not_accepted(self):
|
||||
settings.MPD_SERVER_PASSWORD = 'topsecret'
|
||||
self.sendRequest('password "secret"')
|
||||
self.assertEqualResponse('ACK [3@0] {password} incorrect password')
|
||||
|
||||
def test_any_password_is_not_accepted_when_password_check_turned_off(self):
|
||||
settings.MPD_SERVER_PASSWORD = None
|
||||
self.sendRequest('password "secret"')
|
||||
self.assertEqualResponse('ACK [3@0] {password} incorrect password')
|
||||
|
||||
def test_ping(self):
|
||||
self.sendRequest('ping')
|
||||
self.assertEqualResponse('OK')
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from mopidy import settings
|
||||
|
||||
from tests.frontends.mpd import protocol
|
||||
|
||||
|
||||
@ -29,19 +27,6 @@ class ReflectionHandlerTest(protocol.BaseTestCase):
|
||||
self.assertNotInResponse('command: sticker')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_commands_show_less_if_auth_required_and_not_authed(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'secret'
|
||||
self.sendRequest('commands')
|
||||
# Not requiring auth
|
||||
self.assertInResponse('command: close')
|
||||
self.assertInResponse('command: commands')
|
||||
self.assertInResponse('command: notcommands')
|
||||
self.assertInResponse('command: password')
|
||||
self.assertInResponse('command: ping')
|
||||
# Requiring auth
|
||||
self.assertNotInResponse('command: play')
|
||||
self.assertNotInResponse('command: status')
|
||||
|
||||
def test_decoders(self):
|
||||
self.sendRequest('decoders')
|
||||
self.assertInResponse('OK')
|
||||
@ -53,8 +38,35 @@ class ReflectionHandlerTest(protocol.BaseTestCase):
|
||||
self.assertInResponse('command: kill')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_tagtypes(self):
|
||||
self.sendRequest('tagtypes')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_urlhandlers(self):
|
||||
self.sendRequest('urlhandlers')
|
||||
self.assertInResponse('OK')
|
||||
self.assertInResponse('handler: dummy')
|
||||
|
||||
|
||||
class ReflectionWhenNotAuthedTest(protocol.BaseTestCase):
|
||||
def get_config(self):
|
||||
config = super(ReflectionWhenNotAuthedTest, self).get_config()
|
||||
config['mpd']['password'] = 'topsecret'
|
||||
return config
|
||||
|
||||
def test_commands_show_less_if_auth_required_and_not_authed(self):
|
||||
self.sendRequest('commands')
|
||||
# Not requiring auth
|
||||
self.assertInResponse('command: close')
|
||||
self.assertInResponse('command: commands')
|
||||
self.assertInResponse('command: notcommands')
|
||||
self.assertInResponse('command: password')
|
||||
self.assertInResponse('command: ping')
|
||||
# Requiring auth
|
||||
self.assertNotInResponse('command: play')
|
||||
self.assertNotInResponse('command: status')
|
||||
|
||||
def test_notcommands_returns_more_if_auth_required_and_not_authed(self):
|
||||
settings.MPD_SERVER_PASSWORD = u'secret'
|
||||
self.sendRequest('notcommands')
|
||||
# Not requiring auth
|
||||
self.assertNotInResponse('command: close')
|
||||
@ -65,12 +77,3 @@ class ReflectionHandlerTest(protocol.BaseTestCase):
|
||||
# Requiring auth
|
||||
self.assertInResponse('command: play')
|
||||
self.assertInResponse('command: status')
|
||||
|
||||
def test_tagtypes(self):
|
||||
self.sendRequest('tagtypes')
|
||||
self.assertInResponse('OK')
|
||||
|
||||
def test_urlhandlers(self):
|
||||
self.sendRequest('urlhandlers')
|
||||
self.assertInResponse('OK')
|
||||
self.assertInResponse('handler: dummy')
|
||||
|
||||
@ -3,7 +3,6 @@ from __future__ import unicode_literals
|
||||
import datetime
|
||||
import os
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.utils.path import mtime, uri_to_path
|
||||
from mopidy.frontends.mpd import translator, protocol
|
||||
from mopidy.models import Album, Artist, TlTrack, Playlist, Track
|
||||
@ -24,11 +23,10 @@ class TrackMpdFormatTest(unittest.TestCase):
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
settings.LOCAL_MUSIC_PATH = '/dir/subdir'
|
||||
self.music_path = '/dir/subdir'
|
||||
mtime.set_fake_time(1234567)
|
||||
|
||||
def tearDown(self):
|
||||
settings.runtime.clear()
|
||||
mtime.undo_fake()
|
||||
|
||||
def test_track_to_mpd_format_for_empty_track(self):
|
||||
@ -137,15 +135,14 @@ class QueryFromMpdListFormatTest(unittest.TestCase):
|
||||
|
||||
class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
settings.LOCAL_MUSIC_PATH = '/dir/subdir'
|
||||
self.music_path = '/dir/subdir'
|
||||
mtime.set_fake_time(1234567)
|
||||
|
||||
def tearDown(self):
|
||||
settings.runtime.clear()
|
||||
mtime.undo_fake()
|
||||
|
||||
def translate(self, track):
|
||||
base_path = settings.LOCAL_MUSIC_PATH.encode('utf-8')
|
||||
base_path = self.music_path.encode('utf-8')
|
||||
result = dict(translator.track_to_mpd_format(track))
|
||||
result['file'] = uri_to_path(result['file'])[len(base_path) + 1:]
|
||||
result['key'] = os.path.basename(result['file'])
|
||||
@ -177,11 +174,11 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
self.fail("Couldn't find end %s in result" % directory)
|
||||
|
||||
def test_empty_tag_cache_has_header(self):
|
||||
result = translator.tracks_to_tag_cache_format([])
|
||||
result = translator.tracks_to_tag_cache_format([], self.music_path)
|
||||
result = self.consume_headers(result)
|
||||
|
||||
def test_empty_tag_cache_has_song_list(self):
|
||||
result = translator.tracks_to_tag_cache_format([])
|
||||
result = translator.tracks_to_tag_cache_format([], self.music_path)
|
||||
result = self.consume_headers(result)
|
||||
song_list, result = self.consume_song_list(result)
|
||||
|
||||
@ -190,12 +187,12 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
|
||||
def test_tag_cache_has_header(self):
|
||||
track = Track(uri='file:///dir/subdir/song.mp3')
|
||||
result = translator.tracks_to_tag_cache_format([track])
|
||||
result = translator.tracks_to_tag_cache_format([track], self.music_path)
|
||||
result = self.consume_headers(result)
|
||||
|
||||
def test_tag_cache_has_song_list(self):
|
||||
track = Track(uri='file:///dir/subdir/song.mp3')
|
||||
result = translator.tracks_to_tag_cache_format([track])
|
||||
result = translator.tracks_to_tag_cache_format([track], self.music_path)
|
||||
result = self.consume_headers(result)
|
||||
song_list, result = self.consume_song_list(result)
|
||||
|
||||
@ -205,7 +202,7 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
def test_tag_cache_has_formated_track(self):
|
||||
track = Track(uri='file:///dir/subdir/song.mp3')
|
||||
formated = self.translate(track)
|
||||
result = translator.tracks_to_tag_cache_format([track])
|
||||
result = translator.tracks_to_tag_cache_format([track], self.music_path)
|
||||
|
||||
result = self.consume_headers(result)
|
||||
song_list, result = self.consume_song_list(result)
|
||||
@ -216,7 +213,7 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
def test_tag_cache_has_formated_track_with_key_and_mtime(self):
|
||||
track = Track(uri='file:///dir/subdir/song.mp3')
|
||||
formated = self.translate(track)
|
||||
result = translator.tracks_to_tag_cache_format([track])
|
||||
result = translator.tracks_to_tag_cache_format([track], self.music_path)
|
||||
|
||||
result = self.consume_headers(result)
|
||||
song_list, result = self.consume_song_list(result)
|
||||
@ -227,7 +224,7 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
def test_tag_cache_suports_directories(self):
|
||||
track = Track(uri='file:///dir/subdir/folder/song.mp3')
|
||||
formated = self.translate(track)
|
||||
result = translator.tracks_to_tag_cache_format([track])
|
||||
result = translator.tracks_to_tag_cache_format([track], self.music_path)
|
||||
|
||||
result = self.consume_headers(result)
|
||||
folder, result = self.consume_directory(result)
|
||||
@ -241,7 +238,7 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
|
||||
def test_tag_cache_diretory_header_is_right(self):
|
||||
track = Track(uri='file:///dir/subdir/folder/sub/song.mp3')
|
||||
result = translator.tracks_to_tag_cache_format([track])
|
||||
result = translator.tracks_to_tag_cache_format([track], self.music_path)
|
||||
|
||||
result = self.consume_headers(result)
|
||||
folder, result = self.consume_directory(result)
|
||||
@ -253,7 +250,7 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
def test_tag_cache_suports_sub_directories(self):
|
||||
track = Track(uri='file:///dir/subdir/folder/sub/song.mp3')
|
||||
formated = self.translate(track)
|
||||
result = translator.tracks_to_tag_cache_format([track])
|
||||
result = translator.tracks_to_tag_cache_format([track], self.music_path)
|
||||
|
||||
result = self.consume_headers(result)
|
||||
|
||||
@ -281,7 +278,7 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
formated.extend(self.translate(tracks[0]))
|
||||
formated.extend(self.translate(tracks[1]))
|
||||
|
||||
result = translator.tracks_to_tag_cache_format(tracks)
|
||||
result = translator.tracks_to_tag_cache_format(tracks, self.music_path)
|
||||
|
||||
result = self.consume_headers(result)
|
||||
song_list, result = self.consume_song_list(result)
|
||||
@ -299,7 +296,7 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
formated.append(self.translate(tracks[0]))
|
||||
formated.append(self.translate(tracks[1]))
|
||||
|
||||
result = translator.tracks_to_tag_cache_format(tracks)
|
||||
result = translator.tracks_to_tag_cache_format(tracks, self.music_path)
|
||||
|
||||
result = self.consume_headers(result)
|
||||
folder, result = self.consume_directory(result)
|
||||
@ -315,13 +312,10 @@ class TracksToTagCacheFormatTest(unittest.TestCase):
|
||||
|
||||
class TracksToDirectoryTreeTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
settings.LOCAL_MUSIC_PATH = '/root/'
|
||||
|
||||
def tearDown(self):
|
||||
settings.runtime.clear()
|
||||
self.music_path = '/root/'
|
||||
|
||||
def test_no_tracks_gives_emtpy_tree(self):
|
||||
tree = translator.tracks_to_directory_tree([])
|
||||
tree = translator.tracks_to_directory_tree([], self.music_path)
|
||||
self.assertEqual(tree, ({}, []))
|
||||
|
||||
def test_top_level_files(self):
|
||||
@ -330,18 +324,18 @@ class TracksToDirectoryTreeTest(unittest.TestCase):
|
||||
Track(uri='file:///root/file2.mp3'),
|
||||
Track(uri='file:///root/file3.mp3'),
|
||||
]
|
||||
tree = translator.tracks_to_directory_tree(tracks)
|
||||
tree = translator.tracks_to_directory_tree(tracks, self.music_path)
|
||||
self.assertEqual(tree, ({}, tracks))
|
||||
|
||||
def test_single_file_in_subdir(self):
|
||||
tracks = [Track(uri='file:///root/dir/file1.mp3')]
|
||||
tree = translator.tracks_to_directory_tree(tracks)
|
||||
tree = translator.tracks_to_directory_tree(tracks, self.music_path)
|
||||
expected = ({'dir': ({}, tracks)}, [])
|
||||
self.assertEqual(tree, expected)
|
||||
|
||||
def test_single_file_in_sub_subdir(self):
|
||||
tracks = [Track(uri='file:///root/dir1/dir2/file1.mp3')]
|
||||
tree = translator.tracks_to_directory_tree(tracks)
|
||||
tree = translator.tracks_to_directory_tree(tracks, self.music_path)
|
||||
expected = ({'dir1': ({'dir1/dir2': ({}, tracks)}, [])}, [])
|
||||
self.assertEqual(tree, expected)
|
||||
|
||||
@ -353,7 +347,7 @@ class TracksToDirectoryTreeTest(unittest.TestCase):
|
||||
Track(uri='file:///root/dir2/file4.mp3'),
|
||||
Track(uri='file:///root/dir2/sub/file5.mp3'),
|
||||
]
|
||||
tree = translator.tracks_to_directory_tree(tracks)
|
||||
tree = translator.tracks_to_directory_tree(tracks, self.music_path)
|
||||
expected = (
|
||||
{
|
||||
'dir1': ({}, [tracks[1], tracks[2]]),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user