return await async_get_image_url(
mass, item.album.item_id, item.album.provider, MediaType.Album
)
- elif media_type == MediaType.Album and item.artist:
+ if media_type == MediaType.Album and item.artist:
# try artist instead for albums
return await async_get_image_url(
mass, item.artist.item_id, item.artist.provider, MediaType.Artist
-"""Helper functionalities for path detection in api routes."""
+"""
+Helper functionalities for path detection in api routes.
+
+Based on the original work by nickcoutsos and synacor
+https://github.com/nickcoutsos/python-repath
+"""
import re
import urllib
import urllib.parse
if value is None:
if key["optional"]:
continue
- else:
- raise KeyError('Expected "{name}" to be defined'.format(**key))
+ raise KeyError('Expected "{name}" to be defined'.format(**key))
if isinstance(value, list):
if not key["repeat"]:
if not value:
if key["optional"]:
continue
- else:
- raise ValueError(
- 'Expected "{name}" to not be empty'.format(**key)
- )
+ raise ValueError('Expected "{name}" to not be empty'.format(**key))
for i, val in enumerate(value):
val = str(val)
strict = options.get("strict")
end = options.get("end") is not False
route = ""
- lastToken = tokens[-1]
- endsWithSlash = isinstance(lastToken, str) and lastToken.endswith("/")
+ last_token = tokens[-1]
+ ends_with_slash = isinstance(last_token, str) and last_token.endswith("/")
- PATTERNS = dict(
+ patterns = dict(
REPEAT="(?:{prefix}{capture})*",
OPTIONAL="(?:{prefix}({name}{capture}))?",
REQUIRED="{prefix}({name}{capture})",
parts["name"] = "?P<%s>" % re.escape(token["name"])
if token["repeat"]:
- parts["capture"] += PATTERNS["REPEAT"].format(**parts)
+ parts["capture"] += patterns["REPEAT"].format(**parts)
- template = PATTERNS["OPTIONAL" if token["optional"] else "REQUIRED"]
+ template = patterns["OPTIONAL" if token["optional"] else "REQUIRED"]
route += template.format(**parts)
if not strict:
- route = route[:-1] if endsWithSlash else route
+ route = route[:-1] if ends_with_slash else route
route += "(?:/(?=$))?"
if end:
route += "$"
else:
- route += "" if strict and endsWithSlash else "(?=/|$)"
+ route += "" if strict and ends_with_slash else "(?=/|$)"
return "^%s" % route
return string_to_pattern(path, keys, options)
-def compile(string):
- """Compile a string to a template function for the path."""
- return tokens_to_function(parse(string))
-
-
-def match(pattrn, requested_url_path):
+def match_pattern(pattrn, requested_url_path):
"""Return shorthand to match function."""
return re.match(pattrn, requested_url_path)
-
-
-def pattern(pathstr):
- """Return shorthand to pattern function."""
- return path_to_pattern(pathstr)
self.config = mass.config.base["web"]
self._runner = None
self.api_routes = {}
- self._discovered_servers = []
async def async_setup(self):
"""Perform async setup."""
def register_api_route(self, cmd: str, func: Awaitable):
"""Register a command(handler) to the websocket api."""
- pattern = repath.pattern(cmd)
+ pattern = repath.path_to_pattern(cmd)
self.api_routes[pattern] = func
def register_api_routes(self, cls: Any):
self.mass.config.save()
# fix discovery info
await self.mass.async_setup_discovery()
- for item in self._discovered_servers:
- if item["id"] == self.server_id:
- item["initialized"] = True
return True
@api_route("images/thumb")
return await self.__async_handle_auth(ws_client, data)
# work out handler for the given path/command
for key in self.api_routes:
- match = repath.match(key, command)
+ match = repath.match_pattern(key, command)
if match:
params = match.groupdict()
handler = self.api_routes[key]