Source code for soco.plugins.sharelink

"""ShareLink Plugin."""

import re

from ..plugins import SoCoPlugin
from ..exceptions import SoCoException


[docs]class ShareClass: """Base class for supported services."""
[docs] def canonical_uri(self, uri): """Recognize a share link and return its canonical representation. Args: uri (str): A URI like "https://tidal.com/browse/album/157273956". Returns: str: The canonical URI or None if not recognized. """ raise NotImplementedError
[docs] def service_number(self): """Return the service number. Returns: int: A number identifying the supported music service. """ raise NotImplementedError
[docs] @staticmethod def magic(): """Return magic. Returns: dict: Magic prefix/key/class values for each share type. """ return { "album": { "prefix": "x-rincon-cpcontainer:1004206c", "key": "00040000", "class": "object.container.album.musicAlbum", }, "track": { "prefix": "", "key": "00032020", "class": "object.item.audioItem.musicTrack", }, "playlist": { "prefix": "x-rincon-cpcontainer:1006206c", "key": "1006206c", "class": "object.container.playlistContainer", }, }
[docs] def extract(self, uri): """Extract the share type and encoded URI from a share link. Returns: share_type: The shared type, like "album" or "track". encoded_uri: An escaped URI with a service-specific format. """ raise NotImplementedError
[docs]class SpotifyShare(ShareClass): """Spotify share class."""
[docs] def canonical_uri(self, uri): match = re.search(r"spotify.*[:/](album|track|playlist)[:/](\w+)", uri) if match: return "spotify:" + match.group(1) + ":" + match.group(2) return None
[docs] def service_number(self): return 2311
[docs] def extract(self, uri): spotify_uri = self.canonical_uri(uri) share_type = spotify_uri.split(":")[1] encoded_uri = spotify_uri.replace(":", "%3a") return (share_type, encoded_uri)
[docs]class SpotifyUSShare(SpotifyShare): """Spotify US share class."""
[docs] def service_number(self): return 3079
[docs]class TIDALShare(ShareClass): """TIDAL share class."""
[docs] def canonical_uri(self, uri): match = re.search(r"https://tidal.*[:/](album|track|playlist)[:/]([\w-]+)", uri) if match: return "tidal:" + match.group(1) + ":" + match.group(2) return None
[docs] def service_number(self): return 44551
[docs] def extract(self, uri): tidal_uri = self.canonical_uri(uri) share_type = tidal_uri.split(":")[1] encoded_uri = tidal_uri.replace("tidal:", "").replace(":", "%2f") return (share_type, encoded_uri)
[docs]class DeezerShare(ShareClass): """Deezer share class."""
[docs] def canonical_uri(self, uri): match = re.search( r"https://www.deezer.*[:/](album|track|playlist)[:/]([\w-]+)", uri ) if match: return "deezer:" + match.group(1) + ":" + match.group(2) return None
[docs] def service_number(self): return 519
[docs] def extract(self, uri): deezer_uri = self.canonical_uri(uri) share_type = deezer_uri.split(":")[1] encoded_uri = deezer_uri.replace("deezer:", "").replace(":", "-") return (share_type, encoded_uri)
[docs]class ShareLinkPlugin(SoCoPlugin): """A SoCo plugin for playing Spotify/Tidal share links.""" def __init__(self, soco): """Initialize the plugin.""" super().__init__(soco) self.services = [ SpotifyShare(), SpotifyUSShare(), TIDALShare(), DeezerShare(), ] @property def name(self): return "ShareLink Plugin"