Advertise MPD with Avahi
A rudimentary implementation to resolve #39, ignoring dbus errors (just restart), name collisions (choose a fresh name), etc.
This commit is contained in:
parent
c0bfb5dfd3
commit
ac2e413ec0
@ -23,6 +23,8 @@ class Extension(ext.Extension):
|
||||
schema['password'] = config.Secret(optional=True)
|
||||
schema['max_connections'] = config.Integer(minimum=1)
|
||||
schema['connection_timeout'] = config.Integer(minimum=1)
|
||||
schema['zeroconf_enabled'] = config.Boolean()
|
||||
schema['zeroconf_name'] = config.String()
|
||||
return schema
|
||||
|
||||
def validate_environment(self):
|
||||
|
||||
@ -17,6 +17,9 @@ class MpdFrontend(pykka.ThreadingActor, CoreListener):
|
||||
super(MpdFrontend, self).__init__()
|
||||
hostname = network.format_hostname(config['mpd']['hostname'])
|
||||
port = config['mpd']['port']
|
||||
self.config = config
|
||||
self.hostname = hostname
|
||||
self.port = port
|
||||
|
||||
try:
|
||||
network.Server(
|
||||
@ -36,8 +39,31 @@ class MpdFrontend(pykka.ThreadingActor, CoreListener):
|
||||
|
||||
logger.info('MPD server running at [%s]:%s', hostname, port)
|
||||
|
||||
def on_start(self):
|
||||
try:
|
||||
if self.config['mpd']['zeroconf_enabled']:
|
||||
name = self.config['mpd']['zeroconf_name']
|
||||
import re
|
||||
lo = re.search('(?<![.\d])(127|0)[.]', self.hostname)
|
||||
hostname = "" if lo else self.hostname
|
||||
|
||||
from zeroconf import Zeroconf
|
||||
self.service = Zeroconf(
|
||||
stype="_mpd._tcp",
|
||||
name=name, port=self.port, host=hostname)
|
||||
self.service.publish()
|
||||
|
||||
logger.info('Registered with Avahi as %s', name)
|
||||
except Exception as e:
|
||||
logger.warning('Avahi registration failed (%s)', e)
|
||||
|
||||
def on_stop(self):
|
||||
process.stop_actors_by_class(session.MpdSession)
|
||||
try:
|
||||
if self.service:
|
||||
self.service.unpublish()
|
||||
except Exception as e:
|
||||
logger.warning('Avahi unregistration failed (%s)', e)
|
||||
|
||||
def send_idle(self, subsystem):
|
||||
listeners = pykka.ActorRegistry.get_by_class(session.MpdSession)
|
||||
|
||||
@ -5,3 +5,5 @@ port = 6600
|
||||
password =
|
||||
max_connections = 20
|
||||
connection_timeout = 60
|
||||
zeroconf_enabled = true
|
||||
zeroconf_name = Mopidy
|
||||
|
||||
42
mopidy/frontends/mpd/zeroconf.py
Normal file
42
mopidy/frontends/mpd/zeroconf.py
Normal file
@ -0,0 +1,42 @@
|
||||
import dbus
|
||||
|
||||
__all__ = ["Zeroconf"]
|
||||
|
||||
|
||||
class Zeroconf:
|
||||
"""A simple class to publish a network service with zeroconf using
|
||||
avahi.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, name, port, stype="_http._tcp",
|
||||
domain="", host="", text=""):
|
||||
self.name = name
|
||||
self.stype = stype
|
||||
self.domain = domain
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.text = text
|
||||
|
||||
def publish(self):
|
||||
bus = dbus.SystemBus()
|
||||
server = dbus.Interface(
|
||||
bus.get_object(
|
||||
"org.freedesktop.Avahi",
|
||||
"/"),
|
||||
"org.freedesktop.Avahi.Server")
|
||||
|
||||
g = dbus.Interface(
|
||||
bus.get_object("org.freedesktop.Avahi",
|
||||
server.EntryGroupNew()),
|
||||
"org.freedesktop.Avahi.EntryGroup")
|
||||
|
||||
g.AddService(-1, -1, dbus.UInt32(0),
|
||||
self.name, self.stype, self.domain, self.host,
|
||||
dbus.UInt16(self.port), self.text)
|
||||
|
||||
g.Commit()
|
||||
self.group = g
|
||||
|
||||
def unpublish(self):
|
||||
self.group.Reset()
|
||||
Loading…
Reference in New Issue
Block a user