1
# -*- coding: utf-8 -*-
2
# pylint: disable=R0913,W0142
9
from ..compat import quote_plus
10
from . import SoCoPlugin
16
class SpotifyTrack(object):
18
""" Class that represents a Spotify track
20
usage example: SpotifyTrack('spotify:track:20DfkHC5grnKNJCzZQB6KC') """
22
def __init__(self, spotify_uri):
24
self.data['spotify_uri'] = spotify_uri
27
def spotify_uri(self):
28
""" The track's Spotify URI """
29
return self.data['spotify_uri']
32
def spotify_uri(self, uri):
33
""" Set the track's Spotify URI """
34
self.data['spotify_uri'] = uri
38
""" The album's URI """
39
return self.data['album_uri']
42
def album_uri(self, uri):
43
""" Set the album's URI """
44
self.data['album_uri'] = uri
48
""" The track's title """
49
return self.data['title']
52
def title(self, title):
53
""" Set the track's title """
54
self.data['title'] = title.encode('utf-8')
57
def didl_metadata(self):
59
if ('spotify_uri' in self.data and 'title' in self.data and
60
'album_uri' in self.data):
63
<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/"
64
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
65
xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/"
66
xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">
67
<item id="{0}" parentID="{1}" restricted="true">
68
<dc:title>{2}</dc:title>
69
<upnp:class>object.item.audioItem.musicTrack</upnp:class>
71
nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">
72
SA_RINCON2311_X_#Svc2311-0-Token
75
</DIDL-Lite>""".format(quote_plus(self.data['spotify_uri']),
76
quote_plus(self.data['album_uri']),
77
quote_plus(self.data['title']))
78
didl_metadata = didl_metadata.encode('utf-8')
79
return XML.fromstring(didl_metadata)
85
""" Sonos-Spotify URI """
86
if 'spotify_uri' in self.data:
87
track = self.data['spotify_uri']
88
track = track.encode('utf-8')
89
track = quote_plus(track)
90
return 'x-sonos-spotify:' + track
95
""" Checks if necessary track data is available """
96
return 'title' in self.data and 'didl_metadata' in self.data
99
class SpotifyAlbum(object):
101
""" Class that represents a Spotifyalbum
103
usage example: SpotifyAlbum('spotify:album:6a50SaJpvdWDp13t0wUcPU') """
105
def __init__(self, spotify_uri):
107
self.data['spotify_uri'] = spotify_uri
110
def spotify_uri(self):
111
""" The album's Spotify URI """
112
return self.data['spotify_uri']
115
def spotify_uri(self, uri):
116
""" Set the album's Spotify URI """
117
self.data['spotify_uri'] = uri
120
def artist_uri(self):
121
""" The artist's URI """
122
return self.data['artist_uri']
125
def artist_uri(self, artist_uri):
126
""" Set the artist's URI """
127
self.data['artist_uri'] = artist_uri
131
""" The album's title """
132
return self.data['title']
135
def title(self, title):
136
""" Set the album's title """
137
self.data['title'] = title.encode('utf-8')
141
""" Sonos-Spotify URI """
142
if 'spotify_uri' in self.data:
143
album = self.data['spotify_uri']
144
album = album.encode('utf-8')
145
album = quote_plus(album)
146
return "x-rincon-cpcontainer:" + album
151
def didl_metadata(self):
152
""" DIDL Metadata """
155
<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/"
156
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
157
xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/"
158
xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">
159
<item id="{0}" parentID="{1}" restricted="true">
160
<dc:title>{2}</dc:title>
161
<upnp:class>object.container.album.musicAlbum</upnp:class>
163
nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">
164
SA_RINCON2311_X_#Svc2311-0-Token
167
</DIDL-Lite>""".format(quote_plus(self.data['spotify_uri']),
168
quote_plus(self.data['artist_uri']),
169
quote_plus(self.data['title']))
170
didl_metadata = didl_metadata.encode('utf-8')
171
return XML.fromstring(didl_metadata)
176
""" Checks if necessary album data is available """
177
return ('spotify_uri' in self.data and
178
'artist' in self.data and
179
'title' in self.data)
182
class Spotify(SoCoPlugin):
184
""" Class that implements spotify plugin"""
187
api_lookup_url = 'http://ws.spotify.com/lookup/1/.json'
189
def __init__(self, soco):
190
""" Initialize the plugin"""
191
super(Spotify, self).__init__(soco)
195
return 'Spotify plugin'
197
def _add_track_metadata(self, spotify_track):
198
""" Adds metadata by using the spotify public API """
199
track = SpotifyTrack(spotify_track.spotify_uri)
200
params = {'uri': spotify_track.spotify_uri}
201
res = requests.get(self.api_lookup_url, params=params)
205
track.title = data['track']['name']
206
track.album_uri = data['track']['album']['href']
210
def _add_album_metadata(self, spotify_album):
211
""" Adds metadata by using the spotify public API """
212
album = SpotifyAlbum(spotify_album.spotify_uri)
213
params = {'uri': spotify_album.spotify_uri}
214
res = requests.get(self.api_lookup_url, params=params)
218
album.title = data['album']['name']
219
album.artist_uri = data['album']['artist-id']
223
def add_track_to_queue(self, spotify_track):
224
""" Add a spotify track to the queue using the SpotifyTrack class"""
225
if not spotify_track.satisfied():
226
spotify_track = self._add_track_metadata(spotify_track)
228
return self.soco.add_to_queue(spotify_track)
230
def add_album_to_queue(self, spotify_album):
231
""" Add a spotify album to the queue using the SpotifyAlbum class """
232
if not spotify_album.satisfied():
233
spotify_album = self._add_album_metadata(spotify_album)
235
return self.soco.add_to_queue(spotify_album)