1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
import logging
import pykka
from mopidy import exceptions, listener, zeroconf
from mopidy.core import CoreListener
from mopidy_mpd import network, session, uri_mapper
logger = logging.getLogger(__name__)
_CORE_EVENTS_TO_IDLE_SUBSYSTEMS = {
"track_playback_paused": None,
"track_playback_resumed": None,
"track_playback_started": None,
"track_playback_ended": None,
"playback_state_changed": "player",
"tracklist_changed": "playlist",
"playlists_loaded": "stored_playlist",
"playlist_changed": "stored_playlist",
"playlist_deleted": "stored_playlist",
"options_changed": "options",
"volume_changed": "mixer",
"mute_changed": "output",
"seeked": "player",
"stream_title_changed": "playlist",
}
class MpdFrontend(pykka.ThreadingActor, CoreListener):
def __init__(self, config, core):
super().__init__()
self.hostname = network.format_hostname(config["mpd"]["hostname"])
self.port = config["mpd"]["port"]
self.uri_map = uri_mapper.MpdUriMapper(core)
self.zeroconf_name = config["mpd"]["zeroconf"]
self.zeroconf_service = None
self.server = self._setup_server(config, core)
def _setup_server(self, config, core):
try:
server = network.Server(
self.hostname,
self.port,
protocol=session.MpdSession,
protocol_kwargs={
"config": config,
"core": core,
"uri_map": self.uri_map,
},
max_connections=config["mpd"]["max_connections"],
timeout=config["mpd"]["connection_timeout"],
)
except OSError as exc:
raise exceptions.FrontendError(f"MPD server startup failed: {exc}")
logger.info(
f"MPD server running at {network.format_address(server.address)}"
)
return server
def on_start(self):
if self.zeroconf_name and not network.is_unix_socket(
self.server.server_socket
):
self.zeroconf_service = zeroconf.Zeroconf(
name=self.zeroconf_name, stype="_mpd._tcp", port=self.port
)
self.zeroconf_service.publish()
def on_stop(self):
if self.zeroconf_service:
self.zeroconf_service.unpublish()
session_actors = pykka.ActorRegistry.get_by_class(session.MpdSession)
for session_actor in session_actors:
session_actor.stop()
self.server.stop()
def on_event(self, event, **kwargs):
if event not in _CORE_EVENTS_TO_IDLE_SUBSYSTEMS:
logger.warning(
"Got unexpected event: %s(%s)", event, ", ".join(kwargs)
)
else:
self.send_idle(_CORE_EVENTS_TO_IDLE_SUBSYSTEMS[event])
def send_idle(self, subsystem):
if subsystem:
listener.send(session.MpdSession, subsystem)
|