Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
monkeypatch.setattr('soco.config.SOCO_CLASS', Mock())
# Fake return value for select
monkeypatch.setattr(
'select.select', Mock(return_value = ([sock], 1, 1)))
# set timeout
TIMEOUT = 2
discover(timeout=TIMEOUT)
# 9 packets in total should be sent (3 to default, 3 to
# 192.168.1.15 and 3 to 192.168.1.15)
assert sock.sendto.call_count == 9
# select called with the relevant timeout
select.select.assert_called_with(
[sock, sock, sock], [], [], min(TIMEOUT, 0.1))
# SoCo should be created with the IP address received
config.SOCO_CLASS.assert_called_with(IP_ADDR)
# Now test include_visible parameter. include_invisible=True should
# result in calling SoCo.all_zones etc
# Reset gethostbyname, to always return the same value
monkeypatch.setattr('socket.gethostbyname',
Mock(return_value='192.168.1.15'))
config.SOCO_CLASS.return_value = Mock(
all_zones='ALL', visible_zones='VISIBLE')
assert discover(include_invisible=True) == 'ALL'
assert discover(include_invisible=False) == 'VISIBLE'
# if select does not return within timeout SoCo should not be called
# at all
# simulate no data being returned within timeout
select.select.return_value = (0, 1, 1)
discover(timeout=1)
# result in calling SoCo.all_zones etc
# Reset gethostbyname, to always return the same value
monkeypatch.setattr('socket.gethostbyname',
Mock(return_value='192.168.1.15'))
config.SOCO_CLASS.return_value = Mock(
all_zones='ALL', visible_zones='VISIBLE')
assert discover(include_invisible=True) == 'ALL'
assert discover(include_invisible=False) == 'VISIBLE'
# if select does not return within timeout SoCo should not be called
# at all
# simulate no data being returned within timeout
select.select.return_value = (0, 1, 1)
discover(timeout=1)
# Check no SoCo instance created
config.SOCO_CLASS.assert_not_called
def parse_zone_group_member(member_element):
"""Parse a ZoneGroupMember or Satellite element from Zone Group
State, create a SoCo instance for the member, set basic attributes
and return it."""
# Create a SoCo instance for each member. Because SoCo
# instances are singletons, this is cheap if they have already
# been created, and useful if they haven't. We can then
# update various properties for that instance.
member_attribs = member_element.attrib
ip_addr = member_attribs['Location'].\
split('//')[1].split(':')[0]
zone = config.SOCO_CLASS(ip_addr)
# uid doesn't change, but it's not harmful to (re)set it, in case
# the zone is as yet unseen.
zone._uid = member_attribs['UUID']
zone._player_name = member_attribs['ZoneName']
# add the zone to the set of all members, and to the set
# of visible members if appropriate
is_visible = (member_attribs.get('Invisible') != '1')
if is_visible:
self._visible_zones.add(zone)
self._all_zones.add(zone)
return zone
def parse_zone_group_member(member_element):
""" Parse a ZoneGroupMember or Satellite element from Zone Group
State, create a SoCo instance for the member, set basic attributes
and return it. """
# Create a SoCo instance for each member. Because SoCo
# instances are singletons, this is cheap if they have already
# been created, and useful if they haven't. We can then
# update various properties for that instance.
member_attribs = member_element.attrib
ip_addr = member_attribs['Location'].\
split('//')[1].split(':')[0]
zone = config.SOCO_CLASS(ip_addr)
# uid doesn't change, but it's not harmful to (re)set it, in case
# the zone is as yet unseen.
zone._uid = member_attribs['UUID']
zone._player_name = member_attribs['ZoneName']
# add the zone to the set of all members, and to the set
# of visible members if appropriate
is_visible = False if member_attribs.get(
'Invisible') == '1' else True
if is_visible:
self._visible_zones.add(zone)
self._all_zones.add(zone)
return zone
# X-RINCON-BOOTSEQ: 3
# X-RINCON-HOUSEHOLD: Sonos_7O********************R7eU
if response:
for _sock in response:
data, addr = _sock.recvfrom(1024)
_LOG.debug(
'Received discovery response from %s: "%s"', addr, data
)
if b"Sonos" in data:
# Now we have an IP, we can build a SoCo instance and query
# that player for the topology to find the other players.
# It is much more efficient to rely upon the Zone
# Player's ability to find the others, than to wait for
# query responses from them ourselves.
zone = config.SOCO_CLASS(addr[0])
if include_invisible:
return zone.all_zones
else:
return zone.visible_zones
def any_soco():
"""Return any visible soco device, for when it doesn't matter which.
Try to obtain an existing instance, or use `discover` if necessary.
Note that this assumes that the existing instance has not left
the network.
Returns:
SoCo: A `SoCo` instance (or subclass if `config.SOCO_CLASS` is set,
or `None` if no instances are found
"""
cls = config.SOCO_CLASS
# pylint: disable=no-member, protected-access
try:
# Try to get the first pre-existing soco instance we know about,
# as long as it is visible (i.e. not a bridge etc). Otherwise,
# perform discovery (again, excluding invisibles) and return one of
# those
device = next(d for d in cls._instances[cls._class_group].values()
if d.is_visible)
except (KeyError, StopIteration):
devices = discover()
return None if devices is None else devices.pop()
return device
result = self.contentDirectory.GetAlbumArtistDisplayOption()
return result['AlbumArtistDisplayOption']
# definition section
RADIO_STATIONS = 0
RADIO_SHOWS = 1
NS = {'dc': '{http://purl.org/dc/elements/1.1/}',
'upnp': '{urn:schemas-upnp-org:metadata-1-0/upnp/}',
'': '{urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/}'}
# Valid play modes
PLAY_MODES = ('NORMAL', 'SHUFFLE_NOREPEAT', 'SHUFFLE', 'REPEAT_ALL')
if config.SOCO_CLASS is None:
config.SOCO_CLASS = SoCo
return result['AlbumArtistDisplayOption']
# definition section
RADIO_STATIONS = 0
RADIO_SHOWS = 1
NS = {'dc': '{http://purl.org/dc/elements/1.1/}',
'upnp': '{urn:schemas-upnp-org:metadata-1-0/upnp/}',
'': '{urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/}'}
# Valid play modes
PLAY_MODES = ('NORMAL', 'SHUFFLE_NOREPEAT', 'SHUFFLE', 'REPEAT_ALL')
if config.SOCO_CLASS is None:
config.SOCO_CLASS = SoCo