34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 | @staticmethod
def get_metadata(url: str) -> Tuple[Dict[str, Any], List[Song]]:
"""
Get metadata for a playlist.
### Arguments
- url: The URL of the playlist.
### Returns
- A dictionary with metadata.
"""
spotify_client = SpotifyClient()
playlist = spotify_client.playlist(url)
if playlist is None:
raise PlaylistError("Invalid playlist URL.")
metadata = {
"name": playlist["name"],
"url": url,
"description": playlist["description"],
"author_url": playlist["external_urls"]["spotify"],
"author_name": playlist["owner"]["display_name"],
"cover_url": (
max(
playlist["images"],
key=lambda i: (
0
if i["width"] is None or i["height"] is None
else i["width"] * i["height"]
),
)["url"]
if (playlist.get("images") is not None and len(playlist["images"]) > 0)
else ""
),
}
playlist_response = spotify_client.playlist_items(url)
if playlist_response is None:
raise PlaylistError(f"Wrong playlist id: {url}")
# Get all tracks from playlist
tracks = playlist_response["items"]
while playlist_response["next"]:
playlist_response = spotify_client.next(playlist_response)
# Failed to get response, break the loop
if playlist_response is None:
break
# Add tracks to the list
tracks.extend(playlist_response["items"])
songs = []
for track_no, track in enumerate(tracks):
if not isinstance(track, dict) or track.get("track") is None:
continue
track_meta = track["track"]
if track_meta.get("is_local") or track_meta.get("type") != "track":
logger.warning(
"Skipping track: %s local tracks and %s are not supported",
track_meta.get("id"),
track_meta.get("type"),
)
continue
track_id = track_meta.get("id")
if track_id is None or track_meta.get("duration_ms") == 0:
continue
album_meta = track_meta.get("album", {})
release_date = album_meta.get("release_date")
artists = [artist["name"] for artist in track_meta.get("artists", [])]
song = Song.from_missing_data(
name=track_meta["name"],
artists=artists,
artist=artists[0],
album_id=album_meta.get("id"),
album_name=album_meta.get("name"),
album_artist=(
album_meta.get("artists", [])[0]["name"]
if album_meta.get("artists")
else None
),
album_type=album_meta.get("album_type"),
disc_number=track_meta["disc_number"],
duration=int(track_meta["duration_ms"] / 1000),
year=release_date[:4] if release_date else None,
date=release_date,
track_number=track_meta["track_number"],
tracks_count=album_meta.get("total_tracks"),
song_id=track_meta["id"],
explicit=track_meta["explicit"],
url=track_meta["external_urls"]["spotify"],
isrc=track_meta.get("external_ids", {}).get("isrc"),
cover_url=(
max(album_meta["images"], key=lambda i: i["width"] * i["height"])[
"url"
]
if (len(album_meta.get("images", [])) > 0)
else None
),
list_position=track_no + 1,
)
songs.append(song)
return metadata, songs
|