Skip to content

Commit 9481c1c

Browse files
committed
have get_metadata_4_track() call new get_ext_metadata()
TODO: parsing a successful response always returns a 400 response
1 parent 8760279 commit 9481c1c

7 files changed

Lines changed: 424 additions & 3 deletions

File tree

librespot/core.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
from librespot.proto import Keyexchange_pb2 as Keyexchange
5858
from librespot.proto import Metadata_pb2 as Metadata
5959
from librespot.proto import Playlist4External_pb2 as Playlist4External
60+
from librespot.proto.ExtendedMetadata_pb2 import EntityRequest, BatchedEntityRequest, ExtensionQuery
61+
from librespot.proto.ExtensionKind_pb2 import ExtensionKind
6062
from librespot.proto.ExplicitContentPubsub_pb2 import UserAttributesUpdate
6163
from librespot.proto.spotify.login5.v3 import Login5_pb2 as Login5
6264
from librespot.proto.spotify.login5.v3.credentials import Credentials_pb2 as Login5Credentials
@@ -190,19 +192,27 @@ def put_connect_state(self, connection_id: str,
190192
self.logger.warning("PUT state returned {}. headers: {}".format(
191193
response.status_code, response.headers))
192194

195+
def get_ext_metadata(self, extension_kind: ExtensionKind, uri: str):
196+
query = ExtensionQuery(extension_kind=extension_kind)
197+
req = EntityRequest(entity_uri=uri, query=[query,])
198+
batch = BatchedEntityRequest(entity_request=[req,])
199+
headers = CaseInsensitiveDict({"content-type": "application/x-protobuf"})
200+
response = self.send("POST", "/extended-metadata/v0/extended-metadata",
201+
headers, batch.SerializeToString())
202+
return response
203+
193204
def get_metadata_4_track(self, track: TrackId) -> Metadata.Track:
194205
"""
195206
196207
:param track: TrackId:
197208
198209
"""
199-
response = self.sendToUrl("GET", "https://spclient.wg.spotify.com",
200-
"/metadata/4/track/{}".format(track.hex_id()),
201-
None, None)
210+
response = self.get_ext_metadata(ExtensionKind.TRACK_V4, track.to_spotify_uri())
202211
ApiClient.StatusCodeException.check_status(response)
203212
body = response.content
204213
if body is None:
205214
raise RuntimeError()
215+
# TODO: update parsing of successful response
206216
proto = Metadata.Track()
207217
proto.ParseFromString(body)
208218
return proto

librespot/proto/EntityExtensionData_pb2.py

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

librespot/proto/ExtendedMetadata_pb2.py

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

librespot/proto/ExtensionKind_pb2.py

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/entity_extension_data.proto

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Extracted from: Spotify 1.2.52.442 (windows)
2+
3+
syntax = "proto3";
4+
5+
package spotify.extendedmetadata;
6+
7+
import "google/protobuf/any.proto";
8+
9+
option cc_enable_arenas = true;
10+
option java_multiple_files = true;
11+
option optimize_for = CODE_SIZE;
12+
option java_package = "com.spotify.extendedmetadata.proto";
13+
14+
message EntityExtensionDataHeader {
15+
int32 status_code = 1;
16+
string etag = 2;
17+
string locale = 3;
18+
int64 cache_ttl_in_seconds = 4;
19+
int64 offline_ttl_in_seconds = 5;
20+
}
21+
22+
message EntityExtensionData {
23+
EntityExtensionDataHeader header = 1;
24+
string entity_uri = 2;
25+
google.protobuf.Any extension_data = 3;
26+
}
27+
28+
message PlainListAssoc {
29+
repeated string entity_uri = 1;
30+
}
31+
32+
message AssocHeader {
33+
}
34+
35+
message Assoc {
36+
AssocHeader header = 1;
37+
PlainListAssoc plain_list = 2;
38+
}

proto/extended_metadata.proto

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
syntax = "proto3";
2+
3+
package spotify.extendedmetadata;
4+
5+
import "extension_kind.proto";
6+
import "entity_extension_data.proto";
7+
8+
option cc_enable_arenas = true;
9+
option java_multiple_files = true;
10+
option optimize_for = CODE_SIZE;
11+
option java_package = "com.spotify.extendedmetadata.proto";
12+
13+
message ExtensionQuery {
14+
ExtensionKind extension_kind = 1;
15+
string etag = 2;
16+
}
17+
18+
message EntityRequest {
19+
string entity_uri = 1;
20+
repeated ExtensionQuery query = 2;
21+
}
22+
23+
message BatchedEntityRequestHeader {
24+
string country = 1;
25+
string catalogue = 2;
26+
bytes task_id = 3;
27+
}
28+
29+
message BatchedEntityRequest {
30+
BatchedEntityRequestHeader header = 1;
31+
repeated EntityRequest entity_request = 2;
32+
}
33+
34+
message EntityExtensionDataArrayHeader {
35+
int32 provider_error_status = 1;
36+
int64 cache_ttl_in_seconds = 2;
37+
int64 offline_ttl_in_seconds = 3;
38+
ExtensionType extension_type = 4;
39+
}
40+
41+
message EntityExtensionDataArray {
42+
EntityExtensionDataArrayHeader header = 1;
43+
ExtensionKind extension_kind = 2;
44+
repeated EntityExtensionData extension_data = 3;
45+
}
46+
47+
message BatchedExtensionResponseHeader {
48+
}
49+
50+
message BatchedExtensionResponse {
51+
BatchedExtensionResponseHeader header = 1;
52+
repeated EntityExtensionDataArray extended_metadata = 2;
53+
}
54+
55+
enum ExtensionType {
56+
UNKNOWN = 0;
57+
GENERIC = 1;
58+
ASSOC = 2;
59+
}

0 commit comments

Comments
 (0)