def create_image(uri): uri = Uri.from_uri(uri) if uri is None: return None return Image.from_id(uri.code)
def track_uri(self, callback=None): """Requests the track stream URI. :param callback: Callback to trigger on a successful response :type callback: function :return: decorate wrapper if no callback is provided, otherwise returns the `Request` object. :rtype: function or `spotify.core.request.Request` """ def on_track_uri(response): def on_track_key(key): if callback: callback(response, EncryptedStream(self.sp, key)) self.sp.trackKeyQueue.put(on_track_key) files = {} for file in self.files: files[file.format] = file log.debug("[%s] File format found: %s", self.uri, file.format) request = self.build("sp/track_uri2", self.uri.to_id(), Uri.from_gid(None, files.get(7).file_id)) return self.request_wrapper(request, on_track_uri)
def get_object_key(self, content_type, internal): group, type = self.get_schema_key(content_type) if group is None or type is None: return None, None uri = Uri.from_gid(type, internal.gid) return "hm://%s/%s" % (group, uri.type), uri.to_id()
def parse(cls, sp, data, parser): return Artist(sp, { 'name': data.get('name'), 'gid': Uri.from_uri(data.get('uri')).to_gid(), 'portrait': [ { 'imageUri': data.get('imageUri') } ] }, parser.MercuryJSON, parser)
def parse(cls, sp, data, parser): if type(data) is not dict: data = etree_convert(data) return Playlist(sp, { 'uri': Uri.from_uri(data.get('uri')), 'attributes': { 'name': data.get('name') }, 'image': data.get('image') }, parser.XML, parser)
def parse(cls, sp, data, parser): if type(data) is not dict: data = etree_convert(data) return Image(sp, { 'file_id': Uri.from_id('image', data.get('file_id')).to_gid(size=40), 'size': convert(data.get('size'), long), 'width': convert(data.get('width'), long), 'height': convert(data.get('height'), long) }, parser.XML, parser)
def reply_mercury_json(self, data): self.response_type = Parser.MercuryJSON if self.multi is None: self.multi = True data = json.loads(data) for item in data: uri = Uri.from_uri(item.get('uri')) yield uri.type, item
def playlists(self, username, start=0, count=100, callback=None): if count > 100: raise ValueError("You may only request up to 100 playlists at once") request = HermesRequest(self.sp, { 'method': 'GET', 'uri': 'hm://playlist/user/%s/rootlist?from=%s&length=%s' % (self.uri_quote(username), start, count) }, Playlist, defaults={ 'uri': Uri.from_uri('spotify:user:%s:rootlist' % username) }) return self.request_wrapper(request, callback)
def parse(cls, sp, data, parser): image = data.get('image') if not image: return None image_id = image[image.rfind('/') + 1:] return Image(sp, { 'file_id': Uri.from_id('image', image_id).to_gid(size=40), 'size': 0 }, parser.Tunigo, parser)
def parse(cls, sp, data, parser): image_uri = data.get('imageUri') if not image_uri: return None image_id = image_uri[image_uri.rfind('/') + 1:] return Image(sp, { 'file_id': Uri.from_id('image', image_id).to_gid(size=40), 'size': 0 }, parser.MercuryJSON, parser)
def parse(cls, sp, data, parser): image_uri = None if data.get('image'): image_uri = 'spotify:image:' + data.get('image') return Playlist(sp, { 'uri': Uri.from_uri(data.get('uri')), 'attributes': { 'name': data.get('title') }, 'image': image_uri }, parser.Tunigo, parser)
def playlist(self, uri, start=0, count=100, callback=None): if type(uri) is Uri: uri = str(uri) parts = [self.uri_quote(p) for p in uri.split(':')] request = HermesRequest(self.sp, { 'method': 'GET', 'uri': 'hm://playlist/%s?from=%s&length=%s' % ('/'.join(parts[1:]), start, count) }, Playlist, defaults={ 'uri': Uri.from_uri(uri) }) return self.request_wrapper(request, callback)
def playlist(self, uri, start=0, count=100, callback=None): if type(uri) is Uri: uri = str(uri) parts = [self.uri_quote(p) for p in uri.split(":")] request = HermesRequest( self.sp, {"method": "GET", "uri": "hm://playlist/%s?from=%s&length=%s" % ("/".join(parts[1:]), start, count)}, Playlist, defaults={"uri": Uri.from_uri(uri)}, ) return self.request_wrapper(request, callback)
def parse(cls, sp, data, parser): if type(data) is not dict: data = etree_convert(data) uri = Uri.from_id('artist', data.get('id')) return Artist(sp, { 'gid': uri.to_gid(), 'uri': uri, 'name': data.get('name'), 'portrait': cls.get_portraits(data), 'popularity': float(data.get('popularity')) if data.get('popularity') else None, 'restriction': data.get('restrictions') }, parser.XML, parser)
def playlists(self, username, start=0, count=100, callback=None): if count > 100: raise ValueError("You may only request up to 100 playlists at once") request = HermesRequest( self.sp, { "method": "GET", "uri": "hm://playlist/user/%s/rootlist?from=%s&length=%s" % (self.uri_quote(username), start, count), }, Playlist, defaults={"uri": Uri.from_uri("spotify:user:%s:rootlist" % username)}, ) return self.request_wrapper(request, callback)
def parse(cls, sp, data, parser): return Album(sp, { 'gid': Uri.from_uri(data.get('uri')).to_gid(), 'name': data.get('albumName'), 'artist': [ { 'artistName': data.get('artistName') } ], 'cover': [ { 'image': data.get('image') } ], }, parser.Tunigo, parser)
def parse(cls, sp, data, parser): return Album(sp, { 'name': data.get('name'), 'gid': Uri.from_uri(data.get('uri')).to_gid(), 'artist': [ { 'uri': data.get('artistUri'), 'name': data.get('artistName') } ], 'cover': [ { 'imageUri': data.get('imageUri'), } ] }, parser.MercuryJSON, parser)
def parse(cls, sp, data, parser): if type(data) is not dict: data = etree_convert(data, { 'artist-id': ('artist-id', 'artist') }) uri = Uri.from_id('track', data.get('id')) return Track(sp, { 'gid': uri.to_gid(), 'uri': uri, 'name': data.get('title'), 'artist': [ { '$source': 'node', 'id': artist.get('artist-id'), 'name': artist.get('artist') } for artist in data.get('artist', []) ], 'album': { '$source': 'node', 'id': data.get('album-id'), 'name': data.get('album'), 'artist-id': data.get('album-artist-id'), 'artist-name': data.get('album-artist'), 'cover': data.get('cover'), 'cover-small': data.get('cover-small'), 'cover-large': data.get('cover-large'), }, # TODO year 'number': int(data.get('track-number')), 'duration': int(data.get('length')), 'popularity': float(data.get('popularity')), 'external_id': data.get('external-ids'), 'restriction': data.get('restrictions'), 'file': data.get('files') }, parser.XML, parser)
def list(self, group=None, flat=False): if group: # Pull the code from a group URI parts = group.split(':') group = parts[2] if len(parts) == 4 else group path = [] for item in self.items: if item.uri.type == 'start-group': # Ignore groups if we are returning a flat list if flat: continue # Only return placeholders on the root level if (not group and not path) or (path and path[-1] == group): # Return group placeholder yield PlaylistItem(self.sp).dict_update({ 'uri': Uri.from_uri('spotify:group:%s:%s' % (item.uri.code, item.uri.title)), 'name': item.uri.title }) path.append(item.uri.code) continue elif item.uri.type == 'end-group': # Group close tag if path and path.pop() == group: return continue if group is None: # Ignore if we are inside a group if path and not flat: continue else: # Ignore if we aren't inside the specified group if not path or path[-1] != group: continue # Return item yield item
def parse(cls, sp, data, parser): if type(data) is not dict: data = etree_convert(data) return Album(sp, { 'gid': Uri.from_id('album', data.get('id')).to_gid(), 'name': data.get('name'), 'artist': [ { '$source': 'node', 'id': data.get('artist-id'), 'name': data.get('artist-name') } ], 'type': cls.get_type(data.get('album-type')), 'cover': cls.get_covers(data), 'popularity': convert(data.get('popularity'), float), 'restriction': data.get('restrictions'), 'external_id': data.get('external-ids') }, parser.XML, parser)
def get(self, uris, callback=None): log.debug("metadata(%s)", uris) multi = type(uris) is list if type(uris) is not list: uris = [uris] # array of "request" Objects that will be protobuf'd requests = [] h_type = "" for uri in uris: if type(uri) is not Uri: uri = Uri.from_uri(uri) if uri.type == "local": log.debug('ignoring "local" track URI: %s', uri) continue h_type = uri.type requests.append({"method": "GET", "uri": "hm://metadata/%s/%s" % (uri.type, uri.to_id())}) # Build ProtoRequest request = HermesRequest( self.sp, requests, { "vnd.spotify/metadata-artist": Artist, "vnd.spotify/metadata-album": Album, "vnd.spotify/metadata-track": Track, }, {"method": "GET", "uri": "hm://metadata/%ss" % h_type}, container="objects", multi=multi, ) return self.request_wrapper(request, callback)
def get(self, uris, callback=None): log.debug('metadata(%s)', uris) multi = type(uris) is list if type(uris) is not list: uris = [uris] # array of "request" Objects that will be protobuf'd requests = [] h_type = '' for uri in uris: if type(uri) is not Uri: uri = Uri.from_uri(uri) if uri.type == 'local': log.debug('ignoring "local" track URI: %s', uri) continue h_type = uri.type requests.append({ 'method': 'GET', 'uri': 'hm://metadata/%s/%s' % (uri.type, uri.to_id()) }) # Build ProtoRequest request = HermesRequest(self.sp, requests, { 'vnd.spotify/metadata-artist': Artist, 'vnd.spotify/metadata-album': Album, 'vnd.spotify/metadata-track': Track }, { 'method': 'GET', 'uri': 'hm://metadata/%ss' % h_type }, multi=multi) return self.request_wrapper(request, callback)
def parse(cls, sp, data, parser): if type(data) is not dict: data = etree_convert(data, {"artist-id": ("artist-id", "artist")}) uri = Uri.from_id("track", data.get("id")) return Track( sp, { "gid": uri.to_gid(), "uri": uri, "name": data.get("title"), "artist": [ {"$source": "node", "id": artist.get("artist-id"), "name": artist.get("artist")} for artist in data.get("artist", []) ], "album": { "$source": "node", "id": data.get("album-id"), "name": data.get("album"), "artist-id": data.get("album-artist-id"), "artist-name": data.get("album-artist"), "cover": data.get("cover"), "cover-small": data.get("cover-small"), "cover-large": data.get("cover-large"), }, # TODO year "number": int(data.get("track-number")), "duration": int(data.get("length")), "popularity": float(data.get("popularity")), "external_id": data.get("external-ids"), "restriction": data.get("restrictions"), "file": data.get("files"), }, parser.XML, parser, )
def from_id(cls, id): return cls(None, { 'file_id': Uri.from_id('image', id).to_gid(size=40), 'size': 3 })