Merge pull request #404 from jodal/feature/better-startup-messages

Better startup messages
This commit is contained in:
Thomas Adamcik 2013-04-09 04:04:40 -07:00
commit f8e77e2414
10 changed files with 115 additions and 32 deletions

View File

@ -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):

View File

@ -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.

View File

@ -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))

View File

@ -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]]

View File

@ -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'

View File

@ -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):

View File

@ -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):

View File

@ -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)

View File

@ -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):

View File

@ -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':