Merge branch 'develop' of https://github.com/mopidy/mopidy into fix/310-persist-mopidy-state-between-runs
This commit is contained in:
commit
bc981355bc
@ -95,7 +95,7 @@ MPD frontend
|
||||
|
||||
- Start ``songid`` counting at 1 instead of 0 to match the original MPD server.
|
||||
|
||||
- Idle events are now emitted on ``seekeded`` events. This fix means that
|
||||
- Idle events are now emitted on ``seeked`` events. This fix means that
|
||||
clients relying on ``idle`` events now get notified about seeks.
|
||||
(Fixes: :issue:`1331` :issue:`1347`)
|
||||
|
||||
|
||||
29
docs/conf.py
29
docs/conf.py
@ -15,7 +15,6 @@ sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/../'))
|
||||
|
||||
|
||||
class Mock(object):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
@ -27,39 +26,21 @@ class Mock(object):
|
||||
|
||||
@classmethod
|
||||
def __getattr__(self, name):
|
||||
if name in ('__file__', '__path__'):
|
||||
return '/dev/null'
|
||||
elif name == 'get_system_config_dirs':
|
||||
# glib.get_system_config_dirs()
|
||||
return tuple
|
||||
elif name == 'get_user_config_dir':
|
||||
# glib.get_user_config_dir()
|
||||
if name == 'get_system_config_dirs': # GLib.get_system_config_dirs()
|
||||
return list
|
||||
elif name == 'get_user_config_dir': # GLib.get_user_config_dir()
|
||||
return str
|
||||
elif (name[0] == name[0].upper() and
|
||||
# gst.Caps
|
||||
not name.startswith('Caps') and
|
||||
# gst.PadTemplate
|
||||
not name.startswith('PadTemplate') and
|
||||
# dbus.String()
|
||||
not name == 'String'):
|
||||
return type(name, (), {})
|
||||
else:
|
||||
return Mock()
|
||||
|
||||
|
||||
MOCK_MODULES = [
|
||||
'dbus',
|
||||
'dbus.mainloop',
|
||||
'dbus.mainloop.glib',
|
||||
'dbus.service',
|
||||
'glib',
|
||||
'gobject',
|
||||
'gst',
|
||||
'gst.pbutils',
|
||||
'pygst',
|
||||
'mopidy.internal.gi',
|
||||
'pykka',
|
||||
'pykka.actor',
|
||||
'pykka.future',
|
||||
'pykka.registry',
|
||||
]
|
||||
for mod_name in MOCK_MODULES:
|
||||
sys.modules[mod_name] = Mock()
|
||||
|
||||
@ -7,14 +7,13 @@ import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from gi.repository import GLib, GObject
|
||||
|
||||
import pykka
|
||||
|
||||
from mopidy import config as config_lib, exceptions
|
||||
from mopidy.audio import Audio
|
||||
from mopidy.core import Core
|
||||
from mopidy.internal import deps, process, timer, versioning
|
||||
from mopidy.internal.gi import GLib, GObject
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -627,7 +627,7 @@ class TracklistController(object):
|
||||
|
||||
def _mark_played(self, tl_track):
|
||||
"""Internal method for :class:`mopidy.core.PlaybackController`."""
|
||||
if self.consume and tl_track is not None:
|
||||
if self.get_consume() and tl_track is not None:
|
||||
self.remove({'tlid': [tl_track.tlid]})
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -7,8 +7,7 @@ import textwrap
|
||||
try:
|
||||
import gi
|
||||
gi.require_version('Gst', '1.0')
|
||||
gi.require_version('GstPbutils', '1.0')
|
||||
from gi.repository import GLib, GObject, Gst, GstPbutils
|
||||
from gi.repository import GLib, GObject, Gst
|
||||
except ImportError:
|
||||
print(textwrap.dedent("""
|
||||
ERROR: A GObject Python package was not found.
|
||||
@ -22,7 +21,9 @@ except ImportError:
|
||||
"""))
|
||||
raise
|
||||
else:
|
||||
Gst.is_initialized() or Gst.init()
|
||||
Gst.init([])
|
||||
gi.require_version('GstPbutils', '1.0')
|
||||
from gi.repository import GstPbutils
|
||||
|
||||
|
||||
REQUIRED_GST_VERSION = (1, 2, 3)
|
||||
|
||||
@ -7,11 +7,10 @@ import socket
|
||||
import sys
|
||||
import threading
|
||||
|
||||
from gi.repository import GObject
|
||||
|
||||
import pykka
|
||||
|
||||
from mopidy.internal import encoding
|
||||
from mopidy.internal.gi import GObject
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -4,8 +4,7 @@ import logging
|
||||
import signal
|
||||
import threading
|
||||
|
||||
from pykka import ActorDeadError
|
||||
from pykka.registry import ActorRegistry
|
||||
import pykka
|
||||
|
||||
from mopidy.compat import thread
|
||||
|
||||
@ -31,14 +30,14 @@ def exit_handler(signum, frame):
|
||||
|
||||
|
||||
def stop_actors_by_class(klass):
|
||||
actors = ActorRegistry.get_by_class(klass)
|
||||
actors = pykka.ActorRegistry.get_by_class(klass)
|
||||
logger.debug('Stopping %d instance(s) of %s', len(actors), klass.__name__)
|
||||
for actor in actors:
|
||||
actor.stop()
|
||||
|
||||
|
||||
def stop_remaining_actors():
|
||||
num_actors = len(ActorRegistry.get_all())
|
||||
num_actors = len(pykka.ActorRegistry.get_all())
|
||||
while num_actors:
|
||||
logger.error(
|
||||
'There are actor threads still running, this is probably a bug')
|
||||
@ -47,8 +46,8 @@ def stop_remaining_actors():
|
||||
num_actors, threading.active_count() - num_actors,
|
||||
', '.join([t.name for t in threading.enumerate()]))
|
||||
logger.debug('Stopping %d actor(s)...', num_actors)
|
||||
ActorRegistry.stop_all()
|
||||
num_actors = len(ActorRegistry.get_all())
|
||||
pykka.ActorRegistry.stop_all()
|
||||
num_actors = len(pykka.ActorRegistry.get_all())
|
||||
logger.debug('All actors stopped.')
|
||||
|
||||
|
||||
@ -67,7 +66,7 @@ class BaseThread(threading.Thread):
|
||||
logger.info('Interrupted by user')
|
||||
except ImportError as e:
|
||||
logger.error(e)
|
||||
except ActorDeadError as e:
|
||||
except pykka.ActorDeadError as e:
|
||||
logger.warning(e)
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
|
||||
@ -232,21 +232,6 @@ class TestPreviousHandling(BaseTest):
|
||||
self.assertIn(tl_tracks[1], self.core.tracklist.tl_tracks)
|
||||
|
||||
|
||||
class TestPlayUnknownHandling(BaseTest):
|
||||
|
||||
tracks = [Track(uri='unknown:a', length=1234),
|
||||
Track(uri='dummy:b', length=1234)]
|
||||
|
||||
# TODO: move to UnplayableTest?
|
||||
def test_play_skips_to_next_on_track_without_playback_backend(self):
|
||||
self.core.playback.play()
|
||||
|
||||
self.replay_events()
|
||||
|
||||
current_track = self.core.playback.get_current_track()
|
||||
self.assertEqual(current_track, self.tracks[1])
|
||||
|
||||
|
||||
class OnAboutToFinishTest(BaseTest):
|
||||
|
||||
def test_on_about_to_finish_keeps_finished_track_in_tracklist(self):
|
||||
@ -622,14 +607,26 @@ class EventEmissionTest(BaseTest):
|
||||
listener_mock.send.mock_calls)
|
||||
|
||||
|
||||
class UnplayableURITest(BaseTest):
|
||||
class TestUnplayableURI(BaseTest):
|
||||
|
||||
tracks = [
|
||||
Track(uri='unplayable://'),
|
||||
Track(uri='dummy:b'),
|
||||
]
|
||||
|
||||
def setUp(self): # noqa: N802
|
||||
super(UnplayableURITest, self).setUp()
|
||||
self.core.tracklist.clear()
|
||||
tl_tracks = self.core.tracklist.add([Track(uri='unplayable://')])
|
||||
super(TestUnplayableURI, self).setUp()
|
||||
tl_tracks = self.core.tracklist.get_tl_tracks()
|
||||
self.core.playback._set_current_tl_track(tl_tracks[0])
|
||||
|
||||
def test_play_skips_to_next_if_track_is_unplayable(self):
|
||||
self.core.playback.play()
|
||||
|
||||
self.replay_events()
|
||||
|
||||
current_track = self.core.playback.get_current_track()
|
||||
self.assertEqual(current_track, self.tracks[1])
|
||||
|
||||
def test_pause_changes_state_even_if_track_is_unplayable(self):
|
||||
self.core.playback.pause()
|
||||
self.assertEqual(self.core.playback.state, core.PlaybackState.PAUSED)
|
||||
@ -769,7 +766,7 @@ class TestStream(BaseTest):
|
||||
self.assertEqual(self.playback.get_stream_title(), None)
|
||||
|
||||
|
||||
class BackendSelectionTest(unittest.TestCase):
|
||||
class TestBackendSelection(unittest.TestCase):
|
||||
|
||||
def setUp(self): # noqa: N802
|
||||
config = {
|
||||
@ -918,7 +915,7 @@ class BackendSelectionTest(unittest.TestCase):
|
||||
self.playback2.get_time_position.assert_called_once_with()
|
||||
|
||||
|
||||
class CorePlaybackWithOldBackendTest(unittest.TestCase):
|
||||
class TestCorePlaybackWithOldBackend(unittest.TestCase):
|
||||
|
||||
def test_type_error_from_old_backend_does_not_crash_core(self):
|
||||
config = {
|
||||
@ -941,7 +938,7 @@ class CorePlaybackWithOldBackendTest(unittest.TestCase):
|
||||
b.playback.play.assert_called_once_with()
|
||||
|
||||
|
||||
class Bug1177RegressionTest(unittest.TestCase):
|
||||
class TestBug1177Regression(unittest.TestCase):
|
||||
def test(self):
|
||||
config = {
|
||||
'core': {
|
||||
|
||||
@ -5,13 +5,12 @@ import logging
|
||||
import socket
|
||||
import unittest
|
||||
|
||||
from gi.repository import GObject
|
||||
|
||||
from mock import Mock, call, patch, sentinel
|
||||
|
||||
import pykka
|
||||
|
||||
from mopidy.internal import network
|
||||
from mopidy.internal.gi import GObject
|
||||
|
||||
from tests import any_int, any_unicode
|
||||
|
||||
|
||||
@ -4,11 +4,10 @@ import errno
|
||||
import socket
|
||||
import unittest
|
||||
|
||||
from gi.repository import GObject
|
||||
|
||||
from mock import Mock, patch, sentinel
|
||||
|
||||
from mopidy.internal import network
|
||||
from mopidy.internal.gi import GObject
|
||||
|
||||
from tests import any_int
|
||||
|
||||
|
||||
@ -7,10 +7,9 @@ import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
from mopidy import compat, exceptions
|
||||
from mopidy.internal import path
|
||||
from mopidy.internal.gi import GLib
|
||||
|
||||
import tests
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user