Merge branch 'develop' into feature/mpris-frontend
This commit is contained in:
commit
99e80f3f7b
@ -12,6 +12,19 @@ v0.6.0 (in development)
|
||||
|
||||
- Pykka 0.12.3 or greater is required.
|
||||
|
||||
- All config, data, and cache locations are now based on the XDG spec.
|
||||
|
||||
- This means that your settings file will need to be moved from
|
||||
``~/.mopidy/settings.py`` to ``~/.config/mopidy/settings.py``.
|
||||
- Your Spotify cache will now be stored in ``~/.cache/mopidy`` instead of
|
||||
``~/.mopidy/spotify_cache``, this matches Spotify's own behaviour for their
|
||||
Linux client.
|
||||
- The local backend's ``tag_cache`` should now be in
|
||||
``~/.local/share/mopidy/tag_cache``, likewise your playlists will be in
|
||||
``~/.local/share/mopidy/playlists``.
|
||||
- The local client now tries to lookup where your music is via XDG, it will
|
||||
fall-back to ``~/music`` or use whatever setting you set manually.
|
||||
|
||||
**Changes**
|
||||
|
||||
- Replace :attr:`mopidy.backends.base.Backend.uri_handlers` with
|
||||
@ -22,7 +35,7 @@ v0.6.0 (in development)
|
||||
ad hoc events the Last.fm scrobbler has already been using for some time.
|
||||
- Replaced all of the MPD network code that was provided by asyncore with
|
||||
custom stack. This change was made to facilitate the future support of the
|
||||
`idle` command, and to reduce the number of event loops being used.
|
||||
``idle`` command, and to reduce the number of event loops being used.
|
||||
- Fix metadata update in Shoutcast streaming (Fixes: :issue:`122`)
|
||||
|
||||
|
||||
|
||||
@ -3,10 +3,18 @@ import sys
|
||||
if not (2, 6) <= sys.version_info < (3,):
|
||||
sys.exit(u'Mopidy requires Python >= 2.6, < 3')
|
||||
|
||||
import glib
|
||||
import os
|
||||
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
VERSION = (0, 6, 0)
|
||||
|
||||
DATA_PATH = os.path.join(glib.get_user_data_dir(), 'mopidy')
|
||||
CACHE_PATH = os.path.join(glib.get_user_cache_dir(), 'mopidy')
|
||||
SETTINGS_PATH = os.path.join(glib.get_user_config_dir(), 'mopidy')
|
||||
SETTINGS_FILE = os.path.join(SETTINGS_PATH, 'settings.py')
|
||||
|
||||
def get_version():
|
||||
try:
|
||||
return get_git_version()
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import glob
|
||||
import glib
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
@ -6,7 +7,7 @@ import shutil
|
||||
from pykka.actor import ThreadingActor
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy import settings, DATA_PATH
|
||||
from mopidy.backends.base import (Backend, CurrentPlaylistController,
|
||||
LibraryController, BaseLibraryProvider, PlaybackController,
|
||||
BasePlaybackProvider, StoredPlaylistsController,
|
||||
@ -18,6 +19,14 @@ from .translator import parse_m3u, parse_mpd_tag_cache
|
||||
|
||||
logger = logging.getLogger(u'mopidy.backends.local')
|
||||
|
||||
DEFAULT_PLAYLIST_PATH = os.path.join(DATA_PATH, 'playlists')
|
||||
DEFAULT_TAG_CACHE_FILE = os.path.join(DATA_PATH, 'tag_cache')
|
||||
DEFAULT_MUSIC_PATH = glib.get_user_special_dir(glib.USER_DIRECTORY_MUSIC)
|
||||
|
||||
if not DEFAULT_MUSIC_PATH or DEFAULT_MUSIC_PATH == os.path.expanduser(u'~'):
|
||||
DEFAULT_MUSIC_PATH = os.path.expanduser(u'~/music')
|
||||
|
||||
|
||||
class LocalBackend(ThreadingActor, Backend):
|
||||
"""
|
||||
A backend for playing music from a local music archive.
|
||||
@ -96,7 +105,7 @@ class LocalPlaybackProvider(BasePlaybackProvider):
|
||||
class LocalStoredPlaylistsProvider(BaseStoredPlaylistsProvider):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LocalStoredPlaylistsProvider, self).__init__(*args, **kwargs)
|
||||
self._folder = settings.LOCAL_PLAYLIST_PATH
|
||||
self._folder = settings.LOCAL_PLAYLIST_PATH or DEFAULT_PLAYLIST_PATH
|
||||
self.refresh()
|
||||
|
||||
def lookup(self, uri):
|
||||
@ -173,8 +182,8 @@ class LocalLibraryProvider(BaseLibraryProvider):
|
||||
self.refresh()
|
||||
|
||||
def refresh(self, uri=None):
|
||||
tag_cache = settings.LOCAL_TAG_CACHE_FILE
|
||||
music_folder = settings.LOCAL_MUSIC_PATH
|
||||
tag_cache = settings.LOCAL_TAG_CACHE_FILE or DEFAULT_TAG_CACHE_FILE
|
||||
music_folder = settings.LOCAL_MUSIC_PATH or DEFAULT_MUSIC_PATH
|
||||
|
||||
tracks = parse_mpd_tag_cache(tag_cache, music_folder)
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import glib
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
@ -6,7 +7,7 @@ from spotify.manager import SpotifySessionManager as PyspotifySessionManager
|
||||
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import get_version, settings
|
||||
from mopidy import get_version, settings, CACHE_PATH
|
||||
from mopidy.backends.base import Backend
|
||||
from mopidy.backends.spotify import BITRATES
|
||||
from mopidy.backends.spotify.container_manager import SpotifyContainerManager
|
||||
@ -21,9 +22,10 @@ logger = logging.getLogger('mopidy.backends.spotify.session_manager')
|
||||
# pylint: disable = R0901
|
||||
# SpotifySessionManager: Too many ancestors (9/7)
|
||||
|
||||
|
||||
class SpotifySessionManager(BaseThread, PyspotifySessionManager):
|
||||
cache_location = settings.SPOTIFY_CACHE_PATH
|
||||
settings_location = settings.SPOTIFY_CACHE_PATH
|
||||
cache_location = settings.SPOTIFY_CACHE_PATH or CACHE_PATH
|
||||
settings_location = settings.SPOTIFY_CACHE_PATH or CACHE_PATH
|
||||
appkey_file = os.path.join(os.path.dirname(__file__), 'spotify_appkey.key')
|
||||
user_agent = 'Mopidy %s' % get_version()
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
|
||||
@ -20,7 +21,7 @@ sys.argv[1:] = gstreamer_args
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy import (get_version, settings, OptionalDependencyError,
|
||||
SettingsError)
|
||||
SettingsError, DATA_PATH, SETTINGS_PATH, SETTINGS_FILE)
|
||||
from mopidy.gstreamer import GStreamer
|
||||
from mopidy.utils import get_class
|
||||
from mopidy.utils.log import setup_logging
|
||||
@ -37,6 +38,7 @@ def main():
|
||||
try:
|
||||
options = parse_options()
|
||||
setup_logging(options.verbosity_level, options.save_debug_log)
|
||||
check_old_folders()
|
||||
setup_settings(options.interactive)
|
||||
setup_gstreamer()
|
||||
setup_mixer()
|
||||
@ -79,9 +81,20 @@ def parse_options():
|
||||
help='list current settings')
|
||||
return parser.parse_args(args=mopidy_args)[0]
|
||||
|
||||
def check_old_folders():
|
||||
old_settings_folder = os.path.expanduser(u'~/.mopidy')
|
||||
|
||||
if not os.path.isdir(old_settings_folder):
|
||||
return
|
||||
|
||||
logger.warning(u'Old settings folder found at %s, settings.py should be '
|
||||
'moved to %s, any cache data should be deleted. See release notes '
|
||||
'for further instructions.', old_settings_folder, SETTINGS_PATH)
|
||||
|
||||
def setup_settings(interactive):
|
||||
get_or_create_folder('~/.mopidy/')
|
||||
get_or_create_file('~/.mopidy/settings.py')
|
||||
get_or_create_folder(SETTINGS_PATH)
|
||||
get_or_create_folder(DATA_PATH)
|
||||
get_or_create_file(SETTINGS_FILE)
|
||||
try:
|
||||
settings.validate(interactive)
|
||||
except SettingsError, e:
|
||||
|
||||
@ -4,7 +4,7 @@ Available settings and their default values.
|
||||
.. warning::
|
||||
|
||||
Do *not* change settings directly in :mod:`mopidy.settings`. Instead, add a
|
||||
file called ``~/.mopidy/settings.py`` and redefine settings there.
|
||||
file called ``~/.config/mopidy/settings.py`` and redefine settings there.
|
||||
"""
|
||||
|
||||
#: List of playback backends to use. See :mod:`mopidy.backends` for all
|
||||
@ -79,8 +79,9 @@ LASTFM_PASSWORD = u''
|
||||
#:
|
||||
#: Default::
|
||||
#:
|
||||
#: LOCAL_MUSIC_PATH = u'~/music'
|
||||
LOCAL_MUSIC_PATH = u'~/music'
|
||||
#: # Defaults to asking glib where music is stored, fallback is ~/music
|
||||
#: LOCAL_MUSIC_PATH = None
|
||||
LOCAL_MUSIC_PATH = None
|
||||
|
||||
#: Path to playlist folder with m3u files for local music.
|
||||
#:
|
||||
@ -88,8 +89,8 @@ LOCAL_MUSIC_PATH = u'~/music'
|
||||
#:
|
||||
#: Default::
|
||||
#:
|
||||
#: LOCAL_PLAYLIST_PATH = u'~/.mopidy/playlists'
|
||||
LOCAL_PLAYLIST_PATH = u'~/.mopidy/playlists'
|
||||
#: LOCAL_PLAYLIST_PATH = None # Implies $XDG_DATA_DIR/mopidy/playlists
|
||||
LOCAL_PLAYLIST_PATH = None
|
||||
|
||||
#: Path to tag cache for local music.
|
||||
#:
|
||||
@ -97,8 +98,8 @@ LOCAL_PLAYLIST_PATH = u'~/.mopidy/playlists'
|
||||
#:
|
||||
#: Default::
|
||||
#:
|
||||
#: LOCAL_TAG_CACHE_FILE = u'~/.mopidy/tag_cache'
|
||||
LOCAL_TAG_CACHE_FILE = u'~/.mopidy/tag_cache'
|
||||
#: LOCAL_TAG_CACHE_FILE = None # Implies $XDG_DATA_DIR/mopidy/tag_cache
|
||||
LOCAL_TAG_CACHE_FILE = None
|
||||
|
||||
#: Sound mixer to use. See :mod:`mopidy.mixers` for all available mixers.
|
||||
#:
|
||||
@ -238,7 +239,7 @@ SHOUTCAST_OUTPUT_ENCODER = u'lame mode=stereo bitrate=320'
|
||||
#: Path to the Spotify cache.
|
||||
#:
|
||||
#: Used by :mod:`mopidy.backends.spotify`.
|
||||
SPOTIFY_CACHE_PATH = u'~/.mopidy/spotify_cache'
|
||||
SPOTIFY_CACHE_PATH = None
|
||||
|
||||
#: Your Spotify Premium username.
|
||||
#:
|
||||
|
||||
@ -2,12 +2,13 @@
|
||||
from __future__ import absolute_import
|
||||
from copy import copy
|
||||
import getpass
|
||||
import glib
|
||||
import logging
|
||||
import os
|
||||
from pprint import pformat
|
||||
import sys
|
||||
|
||||
from mopidy import SettingsError
|
||||
from mopidy import SettingsError, SETTINGS_PATH, SETTINGS_FILE
|
||||
from mopidy.utils.log import indent
|
||||
|
||||
logger = logging.getLogger('mopidy.utils.settings')
|
||||
@ -20,11 +21,9 @@ class SettingsProxy(object):
|
||||
self.runtime = {}
|
||||
|
||||
def _get_local_settings(self):
|
||||
dotdir = os.path.expanduser(u'~/.mopidy/')
|
||||
settings_file = os.path.join(dotdir, u'settings.py')
|
||||
if not os.path.isfile(settings_file):
|
||||
if not os.path.isfile(SETTINGS_FILE):
|
||||
return {}
|
||||
sys.path.insert(0, dotdir)
|
||||
sys.path.insert(0, SETTINGS_PATH)
|
||||
# pylint: disable = F0401
|
||||
import settings as local_settings_module
|
||||
# pylint: enable = F0401
|
||||
|
||||
Loading…
Reference in New Issue
Block a user