-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdowload_playlist_spotify_tidal.py
More file actions
146 lines (122 loc) · 5 KB
/
dowload_playlist_spotify_tidal.py
File metadata and controls
146 lines (122 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
146
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
from youtubedownloader import download_tracklist
import csv
from keys import *
import tidalapi
import json
import os
import win32clipboard # part of pywin32
def process_playlist_and_save(tracks, playlist_id, platform, start_idx, end_idx):
"""Process tracks from start_idx to end_idx and save to CSV, return trackstring."""
playlist_data = []
trackstring_lines = []
# Adjust indices to 0-based and ensure they are within bounds
start_idx = max(1, start_idx) - 1 # Convert to 0-based index
end_idx = min(len(tracks), end_idx) - 1 # Ensure end_idx doesn't exceed track count
for idx, track in enumerate(tracks[start_idx:end_idx + 1], start=start_idx + 1):
if platform == "spotify":
title = track["track"]["name"]
artists = ", ".join([artist["name"] for artist in track["track"]["artists"]])
else: # tidal
title = track.name
artists = ", ".join([artist.name for artist in track.artists])
playlist_data.append([idx, artists, title])
trackstring_lines.append(f"{idx}. {artists} - {title}")
trackstring = "\n".join(trackstring_lines)
output_file = f"{platform}_playlist_{playlist_id}.csv"
with open(output_file, mode="w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["#", "Artists", "Title",])
writer.writerows(playlist_data)
print(f"Exported {len(playlist_data)} tracks to {output_file}")
print("\n--- Trackstring ---\n")
print(trackstring)
return trackstring
def main_spotify(playlist_url, start_idx, end_idx):
# Authenticate
auth_manager = SpotifyClientCredentials(client_id=SPOTIPY_CLIENT_ID, client_secret=SPOTIPY_CLIENT_SECRET)
sp = spotipy.Spotify(auth_manager=auth_manager)
# Extract playlist ID
playlist_id = playlist_url.split("/")[-1].split("?")[0]
# Fetch playlist tracks
results = sp.playlist_tracks(playlist_id)
tracks = results["items"]
# If playlist has more than 100 tracks, fetch more
while results["next"]:
results = sp.next(results)
tracks.extend(results["items"])
return process_playlist_and_save(tracks, playlist_id, "spotify", start_idx, end_idx)
def main_tidal(playlist_url, start_idx, end_idx):
# Extract playlist ID
playlist_id = playlist_url.split("/")[-1].split("?")[0]
TOKEN_FILE = "tidal_token.json"
def save_token(session):
"""Save current session tokens to file."""
data = {
"token_type": session.token_type,
"access_token": session.access_token,
"refresh_token": session.refresh_token,
}
tmp_file = TOKEN_FILE + ".tmp"
with open(tmp_file, "w", encoding="utf-8") as f:
json.dump(data, f)
os.replace(tmp_file, TOKEN_FILE)
def load_session():
s = tidalapi.Session()
try:
if os.path.exists(TOKEN_FILE):
with open(TOKEN_FILE, "r", encoding="utf-8") as f:
d = json.load(f)
s.load_oauth_session(
d["token_type"],
d["access_token"],
d["refresh_token"],
)
print("✅ Logged in using saved token")
return s
except Exception as e:
print(f"⚠️ Token load failed: {e}")
# First time or failed load
print("🔑 First-time login...")
s.login_oauth_simple()
save_token(s)
print("✅ Logged in and token saved")
return s
# Usage
session = load_session()
playlist = session.playlist(playlist_id)
tracks = playlist.tracks()
return process_playlist_and_save(tracks, playlist_id, "tidal", start_idx, end_idx)
def main():
win32clipboard.OpenClipboard()
playlist_url = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
mix_title = playlist_url
mix_url = playlist_url
timestamp_regex = r"\d{1,2}\. " # 1 or 2 digits, followed by a dot and a space
# Define track range (modify these values as needed)
start_idx = 1 # Starting track number (1-based)
end_idx = 20 # Ending track number (1-based)
if "spotify" in playlist_url:
print("Fetching Spotify playlist...")
try:
trackstring = main_spotify(playlist_url, start_idx, end_idx)
except:
print("Error retrieving Spotify playlist")
elif "tidal" in playlist_url:
print("Fetching Tidal playlist...")
try:
trackstring = main_tidal(playlist_url, start_idx, end_idx)
except:
print("Error retrieving Tidal playlist")
else:
print(f"Unsupported playlist URL. [{playlist_url}] Please provide a Spotify or Tidal playlist URL.")
return
try:
download_tracklist(trackstring, timestamp_regex, mix_title, mix_url)
except Exception as e:
print(f"Error downloading tracklist: {e}")
return
if __name__ == "__main__":
main()