/
actor.py
88 lines (70 loc) · 2.84 KB
/
actor.py
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
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}") from 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)