Merge pull request #404 from jodal/feature/better-startup-messages
Better startup messages
This commit is contained in:
commit
f8e77e2414
@ -236,8 +236,10 @@ def filter_enabled_extensions(raw_config, extensions):
|
||||
else:
|
||||
disabled_names.append(extension.ext_name)
|
||||
|
||||
logging.info('Enabled extensions: %s', ', '.join(enabled_names))
|
||||
logging.info('Disabled extensions: %s', ', '.join(disabled_names))
|
||||
logging.info(
|
||||
'Enabled extensions: %s', ', '.join(enabled_names) or 'none')
|
||||
logging.info(
|
||||
'Disabled extensions: %s', ', '.join(disabled_names) or 'none')
|
||||
return enabled_extensions
|
||||
|
||||
|
||||
@ -310,7 +312,6 @@ def validate_config(raw_config, schemas, extensions=None):
|
||||
|
||||
def create_file_structures():
|
||||
path.get_or_create_dir('$XDG_DATA_DIR/mopidy')
|
||||
path.get_or_create_dir('$XDG_CONFIG_DIR/mopidy')
|
||||
path.get_or_create_file('$XDG_CONFIG_DIR/mopidy/mopidy.conf')
|
||||
|
||||
|
||||
@ -325,12 +326,19 @@ def stop_audio():
|
||||
|
||||
|
||||
def setup_backends(config, extensions, audio):
|
||||
logger.info('Starting Mopidy backends')
|
||||
backends = []
|
||||
backend_classes = []
|
||||
for extension in extensions:
|
||||
for backend_class in extension.get_backend_classes():
|
||||
backend = backend_class.start(config=config, audio=audio).proxy()
|
||||
backends.append(backend)
|
||||
backend_classes.extend(extension.get_backend_classes())
|
||||
|
||||
logger.info(
|
||||
'Starting Mopidy backends: %s',
|
||||
', '.join(b.__name__ for b in backend_classes) or 'none')
|
||||
|
||||
backends = []
|
||||
for backend_class in backend_classes:
|
||||
backend = backend_class.start(config=config, audio=audio).proxy()
|
||||
backends.append(backend)
|
||||
|
||||
return backends
|
||||
|
||||
|
||||
@ -352,10 +360,16 @@ def stop_core():
|
||||
|
||||
|
||||
def setup_frontends(config, extensions, core):
|
||||
logger.info('Starting Mopidy frontends')
|
||||
frontend_classes = []
|
||||
for extension in extensions:
|
||||
for frontend_class in extension.get_frontend_classes():
|
||||
frontend_class.start(config=config, core=core)
|
||||
frontend_classes.extend(extension.get_frontend_classes())
|
||||
|
||||
logger.info(
|
||||
'Starting Mopidy frontends: %s',
|
||||
', '.join(f.__name__ for f in frontend_classes) or 'none')
|
||||
|
||||
for frontend_class in frontend_classes:
|
||||
frontend_class.start(config=config, core=core)
|
||||
|
||||
|
||||
def stop_frontends(extensions):
|
||||
|
||||
@ -9,8 +9,8 @@ default_config = """
|
||||
[local]
|
||||
enabled = true
|
||||
media_dir = $XDG_MUSIC_DIR
|
||||
playlists_dir = $XDG_DATA_DIR/mopidy/playlists
|
||||
tag_cache_file = $XDG_DATA_DIR/mopidy/tag_cache
|
||||
playlists_dir = $XDG_DATA_DIR/mopidy/local/playlists
|
||||
tag_cache_file = $XDG_DATA_DIR/mopidy/local/tag_cache
|
||||
"""
|
||||
|
||||
__doc__ = """A backend for playing music from a local music archive.
|
||||
|
||||
@ -5,6 +5,7 @@ import logging
|
||||
import pykka
|
||||
|
||||
from mopidy.backends import base
|
||||
from mopidy.utils import encoding, path
|
||||
|
||||
from .library import LocalLibraryProvider
|
||||
from .playlists import LocalPlaylistsProvider
|
||||
@ -18,8 +19,32 @@ class LocalBackend(pykka.ThreadingActor, base.Backend):
|
||||
|
||||
self.config = config
|
||||
|
||||
self.create_dirs_and_files()
|
||||
|
||||
self.library = LocalLibraryProvider(backend=self)
|
||||
self.playback = base.BasePlaybackProvider(audio=audio, backend=self)
|
||||
self.playlists = LocalPlaylistsProvider(backend=self)
|
||||
|
||||
self.uri_schemes = ['file']
|
||||
|
||||
def create_dirs_and_files(self):
|
||||
try:
|
||||
path.get_or_create_dir(self.config['local']['media_dir'])
|
||||
except EnvironmentError as error:
|
||||
logger.warning(
|
||||
'Could not create local media dir: %s',
|
||||
encoding.locale_decode(error))
|
||||
|
||||
try:
|
||||
path.get_or_create_dir(self.config['local']['playlists_dir'])
|
||||
except EnvironmentError as error:
|
||||
logger.warning(
|
||||
'Could not create local playlists dir: %s',
|
||||
encoding.locale_decode(error))
|
||||
|
||||
try:
|
||||
path.get_or_create_file(self.config['local']['tag_cache_file'])
|
||||
except EnvironmentError as error:
|
||||
logger.warning(
|
||||
'Could not create empty tag cache file: %s',
|
||||
encoding.locale_decode(error))
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from mopidy.backends import base
|
||||
from mopidy.models import Album, SearchResult
|
||||
|
||||
@ -19,15 +18,19 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
|
||||
self.refresh()
|
||||
|
||||
def refresh(self, uri=None):
|
||||
tracks = parse_mpd_tag_cache(self._tag_cache_file, self._media_dir)
|
||||
|
||||
logger.info(
|
||||
'Loading tracks from %s using %s',
|
||||
logger.debug(
|
||||
'Loading local tracks from %s using %s',
|
||||
self._media_dir, self._tag_cache_file)
|
||||
|
||||
tracks = parse_mpd_tag_cache(self._tag_cache_file, self._media_dir)
|
||||
|
||||
for track in tracks:
|
||||
self._uri_mapping[track.uri] = track
|
||||
|
||||
logger.info(
|
||||
'Loaded %d local tracks from %s using %s',
|
||||
len(tracks), self._media_dir, self._tag_cache_file)
|
||||
|
||||
def lookup(self, uri):
|
||||
try:
|
||||
return [self._uri_mapping[uri]]
|
||||
|
||||
@ -42,8 +42,6 @@ class LocalPlaylistsProvider(base.BasePlaylistsProvider):
|
||||
return playlist
|
||||
|
||||
def refresh(self):
|
||||
logger.info('Loading playlists from %s', self._playlists_dir)
|
||||
|
||||
playlists = []
|
||||
|
||||
for m3u in glob.glob(os.path.join(self._playlists_dir, '*.m3u')):
|
||||
@ -65,6 +63,10 @@ class LocalPlaylistsProvider(base.BasePlaylistsProvider):
|
||||
self.playlists = playlists
|
||||
listener.BackendListener.send('playlists_loaded')
|
||||
|
||||
logger.info(
|
||||
'Loaded %d local playlists from %s',
|
||||
len(playlists), self._playlists_dir)
|
||||
|
||||
def save(self, playlist):
|
||||
assert playlist.uri, 'Cannot save playlist without URI'
|
||||
|
||||
|
||||
@ -182,7 +182,7 @@ class SpotifySessionManager(process.BaseThread, PyspotifySessionManager):
|
||||
bitrate=self.bitrate, username=self.username))
|
||||
playlists = filter(None, playlists)
|
||||
self.backend.playlists.playlists = playlists
|
||||
logger.info('Loaded %d Spotify playlist(s)', len(playlists))
|
||||
logger.info('Loaded %d Spotify playlists', len(playlists))
|
||||
BackendListener.send('playlists_loaded')
|
||||
|
||||
def logout(self):
|
||||
|
||||
@ -93,7 +93,7 @@ class MprisObject(dbus.service.Object):
|
||||
mainloop = dbus.mainloop.glib.DBusGMainLoop()
|
||||
bus_name = dbus.service.BusName(
|
||||
BUS_NAME, dbus.SessionBus(mainloop=mainloop))
|
||||
logger.info('Connected to D-Bus')
|
||||
logger.info('MPRIS server connected to D-Bus')
|
||||
return bus_name
|
||||
|
||||
def get_playlist_id(self, playlist_uri):
|
||||
|
||||
@ -32,7 +32,7 @@ class ScrobblerFrontend(pykka.ThreadingActor, CoreListener):
|
||||
api_key=API_KEY, api_secret=API_SECRET,
|
||||
username=self.config['scrobbler']['username'],
|
||||
password_hash=pylast.md5(self.config['scrobbler']['password']))
|
||||
logger.info('Connected to Last.fm')
|
||||
logger.info('Scrobbler connected to Last.fm')
|
||||
except (pylast.NetworkError, pylast.MalformedResponseError,
|
||||
pylast.WSError) as e:
|
||||
logger.error('Error during Last.fm setup: %s', e)
|
||||
|
||||
@ -39,12 +39,13 @@ def get_or_create_dir(dir_path):
|
||||
return dir_path
|
||||
|
||||
|
||||
def get_or_create_file(filename):
|
||||
filename = expand_path(filename)
|
||||
if not os.path.isfile(filename):
|
||||
logger.info('Creating file %s', filename)
|
||||
open(filename, 'w')
|
||||
return filename
|
||||
def get_or_create_file(file_path):
|
||||
file_path = expand_path(file_path)
|
||||
get_or_create_dir(os.path.dirname(file_path))
|
||||
if not os.path.isfile(file_path):
|
||||
logger.info('Creating file %s', file_path)
|
||||
open(file_path, 'w').close()
|
||||
return file_path
|
||||
|
||||
|
||||
def path_to_uri(*paths):
|
||||
|
||||
@ -24,7 +24,6 @@ class GetOrCreateDirTest(unittest.TestCase):
|
||||
def test_creating_dir(self):
|
||||
dir_path = os.path.join(self.parent, 'test')
|
||||
self.assert_(not os.path.exists(dir_path))
|
||||
self.assert_(not os.path.isdir(dir_path))
|
||||
created = path.get_or_create_dir(dir_path)
|
||||
self.assert_(os.path.exists(dir_path))
|
||||
self.assert_(os.path.isdir(dir_path))
|
||||
@ -34,9 +33,7 @@ class GetOrCreateDirTest(unittest.TestCase):
|
||||
level2_dir = os.path.join(self.parent, 'test')
|
||||
level3_dir = os.path.join(self.parent, 'test', 'test')
|
||||
self.assert_(not os.path.exists(level2_dir))
|
||||
self.assert_(not os.path.isdir(level2_dir))
|
||||
self.assert_(not os.path.exists(level3_dir))
|
||||
self.assert_(not os.path.isdir(level3_dir))
|
||||
created = path.get_or_create_dir(level3_dir)
|
||||
self.assert_(os.path.exists(level2_dir))
|
||||
self.assert_(os.path.isdir(level2_dir))
|
||||
@ -57,6 +54,47 @@ class GetOrCreateDirTest(unittest.TestCase):
|
||||
self.assertRaises(OSError, path.get_or_create_dir, dir_path)
|
||||
|
||||
|
||||
class GetOrCreateFileTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.parent = tempfile.mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.isdir(self.parent):
|
||||
shutil.rmtree(self.parent)
|
||||
|
||||
def test_creating_file(self):
|
||||
file_path = os.path.join(self.parent, 'test')
|
||||
self.assert_(not os.path.exists(file_path))
|
||||
created = path.get_or_create_file(file_path)
|
||||
self.assert_(os.path.exists(file_path))
|
||||
self.assert_(os.path.isfile(file_path))
|
||||
self.assertEqual(created, file_path)
|
||||
|
||||
def test_creating_nested_file(self):
|
||||
level2_dir = os.path.join(self.parent, 'test')
|
||||
file_path = os.path.join(self.parent, 'test', 'test')
|
||||
self.assert_(not os.path.exists(level2_dir))
|
||||
self.assert_(not os.path.exists(file_path))
|
||||
created = path.get_or_create_file(file_path)
|
||||
self.assert_(os.path.exists(level2_dir))
|
||||
self.assert_(os.path.isdir(level2_dir))
|
||||
self.assert_(os.path.exists(file_path))
|
||||
self.assert_(os.path.isfile(file_path))
|
||||
self.assertEqual(created, file_path)
|
||||
|
||||
def test_creating_existing_file(self):
|
||||
file_path = os.path.join(self.parent, 'test')
|
||||
path.get_or_create_file(file_path)
|
||||
created = path.get_or_create_file(file_path)
|
||||
self.assert_(os.path.exists(file_path))
|
||||
self.assert_(os.path.isfile(file_path))
|
||||
self.assertEqual(created, file_path)
|
||||
|
||||
def test_create_file_with_name_of_existing_dir_throws_ioerror(self):
|
||||
conflicting_dir = os.path.join(self.parent)
|
||||
self.assertRaises(IOError, path.get_or_create_file, conflicting_dir)
|
||||
|
||||
|
||||
class PathToFileURITest(unittest.TestCase):
|
||||
def test_simple_path(self):
|
||||
if sys.platform == 'win32':
|
||||
|
||||
Loading…
Reference in New Issue
Block a user