Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def iter_event_vars(self):
""" Yield an iterator over the services eventable variables.
Yields a tuple of (variable name, data type)
"""
# pylint: disable=invalid-name
ns = '{urn:schemas-upnp-org:service-1-0}'
scpd_body = requests.get(self.base_url + self.scpd_url).text
tree = XML.fromstring(scpd_body.encode('utf-8'))
# parse the state variables to get the relevant variable types
statevars = tree.iterfind('.//{}stateVariable'.format(ns))
for state in statevars:
# We are only interested if 'sendEvents' is 'yes', i.e this
# is an eventable variable
if state.attrib['sendEvents'] == "yes":
name = state.findtext('{}name'.format(ns))
vartype = state.findtext('{}dataType'.format(ns))
yield (name, vartype)
Args:
soco (`SoCo`, optional): a `SoCo` instance to query. If `None`, a
random instance is used. Defaults to `None`.
Returns:
dict: A dict containing account instances. Each key is the
account's serial number, and each value is the related Account
instance. Accounts which have been marked as deleted are excluded.
Note:
Any existing Account instance will have its attributes updated
to those currently stored on the Sonos system.
"""
root = XML.fromstring(cls._get_account_xml(soco))
# _get_account_xml returns an ElementTree element like this:
#
#
#
# 12345678
# 1
#
#
#
#
#
#
# 1
#
#
# error code
# error string
#
#
#
#
#
#
# All that matters for our purposes is the errorCode.
# errorDescription is not required, and Sonos does not seem to use it.
# NB need to encode unicode strings before passing to ElementTree
xml_error = xml_error.encode('utf-8')
error = XML.fromstring(xml_error)
log.debug("Error %s", xml_error)
error_code = error.findtext(
'.//{urn:schemas-upnp-org:control-1-0}errorCode')
if error_code is not None:
description = self.UPNP_ERRORS.get(int(error_code), '')
raise SoCoUPnPException(
message='UPnP Error {} received: {} from {}'.format(
error_code, description, self.soco.ip_address),
error_code=error_code,
error_description=description,
error_xml=xml_error
)
else:
# Unknown error, so just return the entire response
log.error("Unknown error received from %s", self.soco.ip_address)
raise UnknownSoCoException(xml_error)
self._search_prefix_map = {}
# Tunein is a special case. It has no pmap, but supports searching
if self.service_name == "TuneIn":
self._search_prefix_map = {
'stations': 'search:station',
'shows': 'search:show',
'hosts': 'search:host',
}
return self._search_prefix_map
if self.presentation_map_uri is None:
# Assume not searchable?
return self._search_prefix_map
log.info('Fetching presentation map from %s',
self.presentation_map_uri)
pmap = requests.get(self.presentation_map_uri, timeout=9)
pmap_root = XML.fromstring(pmap.content)
# Search translations can appear in Category or CustomCategory elements
categories = pmap_root.findall(".//SearchCategories/Category")
if categories is None:
return self._search_prefix_map
for cat in categories:
self._search_prefix_map[cat.get('id')] = cat.get('mappedId')
custom_categories = pmap_root.findall(
".//SearchCategories/CustomCategory")
for cat in custom_categories:
self._search_prefix_map[cat.get('stringId')] = cat.get('mappedId')
return self._search_prefix_map
:param max_items: The maximum number of returned items
:type max_items: int
"""
# Check input
if search_type not in ['artists', 'albums', 'tracks', 'playlists']:
message = 'The requested search {} is not valid'\
.format(search_type)
raise ValueError(message)
# Transform search: tracks -> tracksearch
search_type = '{}earch'.format(search_type)
# Perform search
body = self._search_body(search_type, search, start, max_items)
headers = _get_header('search')
response = requests.post(self._url, headers=headers, data=body)
self._check_for_errors(response)
result_dom = XML.fromstring(response.text.encode('utf-8'))
search_result = result_dom.find('.//' + ns_tag('', 'searchResult'))
search_numbers = {}
for element in ['index', 'count', 'total']:
search_numbers[element] = \
search_result.findtext(ns_tag('', element))
out = []
if search_type == 'tracksearch':
item_name = 'mediaMetadata'
else:
item_name = 'mediaCollection'
for element in search_result.findall(ns_tag('', item_name)):
out.append(get_ms_item(element, self))
return out
#
#
#
# out arg value
# ... other out args and their values go here, if any
#
#
#
# Get all tags in order. Elementree (in python 2.x) seems to prefer to
# be fed bytes, rather than unicode
xml_response = xml_response.encode('utf-8')
tree = XML.fromstring(xml_response)
# Get the first child of the tag which will be
# <{actionNameResponse}> (depends on what actionName is). Turn the
# children of this into a {tagname, content} dict. XML unescaping
# is carried out for us by elementree.
action_response = tree.find(
".//{http://schemas.xmlsoap.org/soap/envelope/}Body")[0]
return {i.tag: i.text or "" for i in action_response}