This repository was archived by the owner on Sep 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspotdl_gui.py
273 lines (217 loc) · 8.94 KB
/
spotdl_gui.py
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# NECESSARY IMPORTS
from os import system
import sys
from threading import Thread
import tkinter as tk
from tkinter import *
from tkinter import messagebox, filedialog
# Install Spotify-downloader if not installed already.
try:
import spotdl
except:
if input("Spotdl not found, download now? (y/n)").lower()[0] == 'y':
system('pip3 install -U spotdl')
else:
sys.exit()
# Install colorama if Windows OS is used and no colorama is installed already.
import os
if os.name == 'nt':
try:
import colorama
except:
print("Colorama is required for the correct display of the text colors!")
if input('Would you like to install colorama? (y/n)').lower()[0] == 'y':
system('pip3 install colorama') # NEEDED FOR WINDOWS to work with ANSI escape codes
colorama.init()
else:
sys.exit()
from spotdl import Spotdl, util
from spotdl.authorize.services import AuthorizeSpotify
from spotdl.helpers.spotify import SpotifyHelpers
class BColors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
# -- As per Spotfiy API documentation --
# Make sure that you safeguard your application Client Secret at all times.
# Be aware, for example, that if you commit your code to a public repository like GitHub
# you will need to remove the Client Secret from your code before doing so.
u_client_id = ''
u_client_secret = ''
try:
# Attempt to locate spotify secret keys from a local spotify_keys.txt file
with open("spotify_keys.txt", "r+") as keys:
contents = keys.readlines()
if contents:
contents = [key.strip() for key in contents] # Removal of newlines
try:
u_client_id = contents[0]
u_client_secret = contents[1]
print(BColors.OKGREEN + "Success: Found local spotify keys!" + BColors.ENDC)
except IndexError:
raise FileNotFoundError
else:
raise FileNotFoundError
except FileNotFoundError:
# If keys are not found, allow the user to obtain the keys from spotify
print(BColors.WARNING + "Warning: You are missing the client_id/secret which is required for the album/playlist features" + BColors.ENDC)
print(BColors.WARNING + "You can obtain these keys by creating a quick app with Spotify" + BColors.ENDC)
print("https://developer.spotify.com/dashboard/applications\n")
# User is able to proceed without keys, which will limit some features
if(input("Enter keys manually? (y/n): ").lower()[0] == "y"):
# Note: Create a first call to the /autorize endpoint to validate if an API token was retrieved?
u_client_id = input("Enter your client id:")
u_client_secret = input("Enter your client secret:")
# Keys will be saved for the future in a local text file
with open("spotify_keys.txt", "w") as keys:
keys.writelines([u_client_id + "\n", u_client_secret])
print(BColors.OKGREEN + "Success: Your keys were saved for future use!" + BColors.ENDC)
else:
print(BColors.WARNING + "Warning: Cannot Proceed Without Keys! Exiting Now..." + BColors.ENDC)
sys.exit()
except:
raise
helper_instance = SpotifyHelpers(spotify=AuthorizeSpotify(client_id=u_client_id, client_secret=u_client_secret))
# Prefill download path
from pathlib import Path
location = str(os.path.join(Path.home(), "Downloads"))
def Widgets():
# Link Box
link_label = Label(root, text="Spotify Link :", bg="#E8D579")
link_label.grid(row=1, column=0, pady=5, padx=5)
root.linkText = Entry(root, width=55, textvariable=song_link)
root.linkText.grid(row=1, column=1, pady=5, padx=5, columnspan=2)
root.linkText.focus_set()
# Directory Selector and Browse Button
destination_label = Label(root, text="Destination :", bg="#E8D579")
destination_label.grid(row=2, column=0, pady=5, padx=5)
download_Path.set(location)
root.destinationText = Entry(root, width=40, textvariable=download_Path)
root.destinationText.grid(row=2, column=1, pady=5, padx=5)
browse_B = Button(root, text="Browse", command=Browse,
width=10, bg="#05E8E0")
browse_B.grid(row=2, column=2, pady=1, padx=1)
# Download Button
Download_B = Button(root, text="Download",
command=Download, width=20, bg="#05E8E0")
Download_B.grid(row=7, column=1, pady=3, padx=3)
# Link Type Selection
linkType_label = Label(root, text="Type :", bg="#E8D579")
linkType_label.grid(row=4, column=0, pady=5, padx=5)
typeList = ['song', 'playlist', 'album', 'list']
link_type.set(typeList[0])
opt2 = tk.OptionMenu(root, link_type, *typeList)
opt2.config(width=10, bg="#05E8E0")
opt2.grid(row=4, column=1, pady=3, padx=3)
ext_label = Label(root, text="File Format :", bg="#E8D579")
ext_label.grid(row=6, column=0, pady=5, padx=5)
extList = ['mp3', 'flac', 'm4a', 'opus', 'ogg']
output_ext.set(extList[0])
opt3 = tk.OptionMenu(root, output_ext, *extList)
opt3.config(width=10, bg="#05E8E0")
opt3.grid(row=6, column=1, pady=3, padx=3)
# Log Level Selection
log_label = Label(root, text="Log Level :", bg="#E8D579")
log_label.grid(row=5, column=0, pady=5, padx=5)
logList = ["INFO", "DEBUG", "WARNING", "ERROR"]
log.set(logList[0])
opt = tk.OptionMenu(root, log, *logList)
opt.config(width=10, bg="#05E8E0")
opt.grid(row=5, column=1, pady=3, padx=3)
# State of the Script (Downloading/Completed Download)
global log_widget
log_widget = Text(master=root, height=1, width=50)
log_widget.grid(row=8, columnspan=3, padx=3, pady=3)
log_widget.configure(state='disabled')
# Function for getting the logs.
def logs():
print(util.install_logger(level=log.get()))
# Running logs function on a different thread. Else, the UI would freeze.
printLog = Thread(target=logs)
# Prints downloading onto the status widget.
def logwrite_begin():
log_widget.configure(state='normal')
log_widget.insert(END, 'Downloading, Check Console For Logs/Progress')
log_widget.configure(state='disabled')
# Prints download complete onto the status widget.
def logwrite_end():
log_widget.configure(state='normal')
log_widget.delete(1.0, END)
log_widget.insert(
END, "Download Complete, Check Console for Logs/Errors.")
log_widget.configure(state='disabled')
# Function for the browse button.
def Browse():
download_Directory = filedialog.askdirectory(
initialdir="YOUR DIRECTORY PATH")
download_Path.set(download_Directory)
# Function for downloading a single track.
def song():
logwrite_begin()
printLog.start()
def download():
spotdl_instance.download_track(song_link.get())
logwrite_end()
downloader = Thread(target=download)
downloader.start()
# Function for downloading an album.
def album():
logwrite_begin()
printLog.start()
alb = helper_instance.fetch_album(song_link.get())
helper_instance.write_album_tracks(alb, './album_tracks.txt')
def download():
spotdl_instance.download_tracks_from_file('album_tracks.txt')
logwrite_end()
downloader = Thread(target=download)
downloader.start()
# Function for downloading a Playlist.
def playlist():
logwrite_begin()
printLog.start()
playlist = helper_instance.fetch_playlist(song_link.get())
helper_instance.write_playlist_tracks(playlist, '.\playlist_tracks.txt')
def download():
spotdl_instance.download_tracks_from_file('playlist_tracks.txt')
logwrite_end()
downloader = Thread(target=download)
downloader.start()
# Function for downloading a list of songs from a .txt file.
def textlist():
logwrite_begin()
printLog.start()
def download():
spotdl_instance.download_tracks_from_file(song_link.get())
logwrite_end()
downloader = Thread(target=download)
downloader.start()
# Function for the download button.
def Download():
global spotdl_instance
spotdl_instance = Spotdl(args={'output_file': download_Path.get(),
'output_ext': output_ext.get()})
if link_type.get() == 'song':
song()
elif link_type.get() == 'list':
textlist()
elif link_type.get() == 'playlist':
playlist()
elif link_type.get() == 'album':
album()
root = tk.Tk()
root.geometry("440x250")
root.resizable(False, False)
root.title("Spotify-Downloader")
root.config(background="#000000")
song_link = StringVar()
download_Path = StringVar()
log = StringVar()
output_ext = StringVar()
link_type = StringVar()
Widgets()
root.mainloop()