Introduce the new Logging Function
parent
cb9e63ab20
commit
b9c1db9372
144
scdl/scdl.py
144
scdl/scdl.py
|
@ -2,10 +2,14 @@
|
||||||
"""scdl allow you to download music from soundcloud
|
"""scdl allow you to download music from soundcloud
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
scdl.py -l <track_url> [-a | -f | -t | -p][-c][-o <offset>][--hidewarnings][--path <path>][--addtofile]
|
scdl -l <track_url> [-a | -f | -t | -p][-c][-o <offset>]\
|
||||||
scdl.py me (-s | -a | -f | -t | -p)[-c][-o <offset>][--hidewarnings][--path <path>][--addtofile]
|
[--hidewarnings][--debug | --error][--path <path>][--addtofile]
|
||||||
scdl.py -h | --help
|
|
||||||
scdl.py --version
|
scdl me (-s | -a | -f | -t | -p)[-c][-o <offset>]\
|
||||||
|
[--hidewarnings][--debug | --error][--path <path>][--addtofile]
|
||||||
|
|
||||||
|
scdl -h | --help
|
||||||
|
scdl --version
|
||||||
|
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
@ -24,6 +28,7 @@ Options:
|
||||||
--hidewarnings Hide Warnings. (use with precaution)
|
--hidewarnings Hide Warnings. (use with precaution)
|
||||||
--addtofile Add the artist name to the filename if it isn't in the filename already
|
--addtofile Add the artist name to the filename if it isn't in the filename already
|
||||||
"""
|
"""
|
||||||
|
import __init__
|
||||||
from docopt import docopt
|
from docopt import docopt
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
|
@ -40,6 +45,8 @@ import json
|
||||||
|
|
||||||
import mutagen
|
import mutagen
|
||||||
|
|
||||||
|
log_verbosity = 1 # (0 = Error ; 1 = Error && Info ; 2 = Debug && Error && Info)
|
||||||
|
arguments = None
|
||||||
token = ''
|
token = ''
|
||||||
path = ''
|
path = ''
|
||||||
offset = 0
|
offset = 0
|
||||||
|
@ -49,26 +56,40 @@ scdl_client_id = 'b45b1aa10f1ac2941910a7f0d10f8e28'
|
||||||
client = soundcloud.Client(client_id=scdl_client_id)
|
client = soundcloud.Client(client_id=scdl_client_id)
|
||||||
|
|
||||||
|
|
||||||
|
def log(str, strverbosity=1): # strverbosity (0 = Error ; 1 = Info ; 2 = Debug)
|
||||||
|
global log_verbosity
|
||||||
|
if log_verbosity >= strverbosity: # Error
|
||||||
|
print(str)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""
|
"""
|
||||||
Main function, call parse_url
|
Main function, call parse_url
|
||||||
"""
|
"""
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
print("Soundcloud Downloader")
|
|
||||||
global offset
|
global offset
|
||||||
|
global log_verbosity
|
||||||
|
global arguments
|
||||||
|
|
||||||
# import conf file
|
# import conf file
|
||||||
get_config()
|
get_config()
|
||||||
|
|
||||||
# Parse argument
|
# Parse argument
|
||||||
arguments = docopt(__doc__, version='0.1')
|
arguments = docopt(__doc__, version=__init__.__version__)
|
||||||
#print(arguments)
|
|
||||||
|
if arguments["--debug"]:
|
||||||
|
log_verbosity = 2
|
||||||
|
elif arguments["--error"]:
|
||||||
|
log_verbosity = 0
|
||||||
|
|
||||||
|
log("Soundcloud Downloader", strverbosity=1)
|
||||||
|
log(arguments, strverbosity=2)
|
||||||
|
|
||||||
if arguments["-o"] is not None:
|
if arguments["-o"] is not None:
|
||||||
try:
|
try:
|
||||||
offset = int(arguments["-o"])
|
offset = int(arguments["-o"])
|
||||||
except:
|
except:
|
||||||
print('Offset should be an Integer...')
|
log('Offset should be an Integer...', strverbosity=0)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
if arguments["--hidewarnings"]:
|
if arguments["--hidewarnings"]:
|
||||||
|
@ -78,12 +99,11 @@ def main():
|
||||||
if os.path.exists(arguments["--path"]):
|
if os.path.exists(arguments["--path"]):
|
||||||
os.chdir(arguments["--path"])
|
os.chdir(arguments["--path"])
|
||||||
else:
|
else:
|
||||||
print('Invalid path in option...')
|
log('Invalid path in arguments...', strverbosity=0)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
log('Downloading to '+os.getcwd()+'...', strverbosity=2)
|
||||||
|
|
||||||
print('Downloading to '+os.getcwd()+'...')
|
log('', strverbosity=1)
|
||||||
|
|
||||||
print('')
|
|
||||||
if arguments["-l"]:
|
if arguments["-l"]:
|
||||||
parse_url(arguments["-l"])
|
parse_url(arguments["-l"])
|
||||||
elif arguments["me"]:
|
elif arguments["me"]:
|
||||||
|
@ -108,12 +128,12 @@ def get_config():
|
||||||
token = config['scdl']['auth_token']
|
token = config['scdl']['auth_token']
|
||||||
path = config['scdl']['path']
|
path = config['scdl']['path']
|
||||||
except:
|
except:
|
||||||
print('Are you sure scdl.cfg is in $HOME/.config/scdl/ ?')
|
log('Are you sure scdl.cfg is in $HOME/.config/scdl/ ?', strverbosity=0)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
os.chdir(path)
|
os.chdir(path)
|
||||||
else:
|
else:
|
||||||
print('Invalid path in scdl.cfg...')
|
log('Invalid path in scdl.cfg...', strverbosity=0)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,13 +145,13 @@ def get_item(track_url):
|
||||||
try:
|
try:
|
||||||
item = client.get('/resolve', url=track_url)
|
item = client.get('/resolve', url=track_url)
|
||||||
except Exception:
|
except Exception:
|
||||||
print('Error resolving url, retrying...')
|
log('Error resolving url, retrying...', strverbosity=0)
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
try:
|
try:
|
||||||
item = client.get('/resolve', url=track_url)
|
item = client.get('/resolve', url=track_url)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Could not resolve url " + track_url)
|
log("Could not resolve url " + track_url, strverbosity=0)
|
||||||
print(e)
|
log(e, strverbosity=0)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
return item
|
return item
|
||||||
|
|
||||||
|
@ -140,7 +160,7 @@ def parse_url(track_url):
|
||||||
"""
|
"""
|
||||||
Detects if the URL is a track or playlists, and parses the track(s) to the track downloader
|
Detects if the URL is a track or playlists, and parses the track(s) to the track downloader
|
||||||
"""
|
"""
|
||||||
arguments = docopt(__doc__, version='0.1')
|
global arguments
|
||||||
item = get_item(track_url)
|
item = get_item(track_url)
|
||||||
|
|
||||||
if not item:
|
if not item:
|
||||||
|
@ -148,13 +168,13 @@ def parse_url(track_url):
|
||||||
elif isinstance(item, soundcloud.resource.ResourceList):
|
elif isinstance(item, soundcloud.resource.ResourceList):
|
||||||
download_all(item)
|
download_all(item)
|
||||||
elif item.kind == 'track':
|
elif item.kind == 'track':
|
||||||
print("Found a track")
|
log("Found a track", strverbosity=1)
|
||||||
download_track(item)
|
download_track(item)
|
||||||
elif item.kind == "playlist":
|
elif item.kind == "playlist":
|
||||||
print("Found a playlist")
|
log("Found a playlist", strverbosity=1)
|
||||||
download_playlist(item)
|
download_playlist(item)
|
||||||
elif item.kind == 'user':
|
elif item.kind == 'user':
|
||||||
print("Found an user profile")
|
log("Found an user profile", strverbosity=1)
|
||||||
if arguments["-f"]:
|
if arguments["-f"]:
|
||||||
download_user_favorites(item)
|
download_user_favorites(item)
|
||||||
elif arguments["-t"]:
|
elif arguments["-t"]:
|
||||||
|
@ -164,9 +184,9 @@ def parse_url(track_url):
|
||||||
elif arguments["-p"]:
|
elif arguments["-p"]:
|
||||||
download_user_playlists(item)
|
download_user_playlists(item)
|
||||||
else:
|
else:
|
||||||
print('Please provide a download type...')
|
log('Please provide a download type...', strverbosity=0)
|
||||||
else:
|
else:
|
||||||
print("Unknown item type")
|
log("Unknown item type", strverbosity=0)
|
||||||
|
|
||||||
|
|
||||||
def who_am_i():
|
def who_am_i():
|
||||||
|
@ -179,10 +199,10 @@ def who_am_i():
|
||||||
try:
|
try:
|
||||||
current_user = client.get('/me')
|
current_user = client.get('/me')
|
||||||
except:
|
except:
|
||||||
print('Invalid token...')
|
log('Invalid token...', strverbosity=0)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
print('Hello', current_user.username, '!')
|
log('Hello', current_user.username, '!', strverbosity=1)
|
||||||
print('')
|
log('', strverbosity=1)
|
||||||
return current_user
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,7 +224,7 @@ def download_all_user_tracks(user):
|
||||||
this_url = json_data[0]['track']['uri']
|
this_url = json_data[0]['track']['uri']
|
||||||
except:
|
except:
|
||||||
this_url = json_data[0]['playlist']['uri']
|
this_url = json_data[0]['playlist']['uri']
|
||||||
print('Track n°%d' % (offset))
|
log('Track n°%d' % (offset))
|
||||||
parse_url(this_url)
|
parse_url(this_url)
|
||||||
|
|
||||||
url = "https://api.sndcdn.com/e1/users/%s/sounds.json?limit=1&offset=%d&client_id=9dbef61eb005cb526480279a0cc868c4" % (user_id, offset)
|
url = "https://api.sndcdn.com/e1/users/%s/sounds.json?limit=1&offset=%d&client_id=9dbef61eb005cb526480279a0cc868c4" % (user_id, offset)
|
||||||
|
@ -224,12 +244,12 @@ def download_user_tracks(user):
|
||||||
for track in tracks:
|
for track in tracks:
|
||||||
for track in tracks:
|
for track in tracks:
|
||||||
count += 1
|
count += 1
|
||||||
print("")
|
log("", strverbosity=1)
|
||||||
print('Track n°%d' % (count))
|
log('Track n°%d' % (count), strverbosity=1)
|
||||||
download_track(track)
|
download_track(track)
|
||||||
offset += 10
|
offset += 10
|
||||||
tracks = client.get('/users/' + str(user.id) + '/tracks', limit=10, offset=offset)
|
tracks = client.get('/users/' + str(user.id) + '/tracks', limit=10, offset=offset)
|
||||||
print('All users track downloaded!')
|
log('All users track downloaded!', strverbosity=1)
|
||||||
|
|
||||||
|
|
||||||
def download_user_playlists(user):
|
def download_user_playlists(user):
|
||||||
|
@ -242,12 +262,12 @@ def download_user_playlists(user):
|
||||||
for playlist in playlists:
|
for playlist in playlists:
|
||||||
for playlist in playlists:
|
for playlist in playlists:
|
||||||
count += 1
|
count += 1
|
||||||
print("")
|
log("", strverbosity=1)
|
||||||
print('Playlist n°%d' % (count))
|
log('Playlist n°%d' % (count), strverbosity=1)
|
||||||
download_playlist(playlist)
|
download_playlist(playlist)
|
||||||
offset += 10
|
offset += 10
|
||||||
playlists = client.get('/users/' + str(user.id) + '/playlists', limit=10, offset=offset)
|
playlists = client.get('/users/' + str(user.id) + '/playlists', limit=10, offset=offset)
|
||||||
print('All users playlists downloaded!')
|
log('All users playlists downloaded!', strverbosity=1)
|
||||||
|
|
||||||
|
|
||||||
def download_user_favorites(user):
|
def download_user_favorites(user):
|
||||||
|
@ -260,12 +280,12 @@ def download_user_favorites(user):
|
||||||
for track in favorites:
|
for track in favorites:
|
||||||
for track in favorites:
|
for track in favorites:
|
||||||
count += 1
|
count += 1
|
||||||
print("")
|
log("", strverbosity=1)
|
||||||
print('Favorite n°%d' % (count))
|
log('Favorite n°%d' % (count), strverbosity=1)
|
||||||
download_track(track)
|
download_track(track)
|
||||||
offset += 10
|
offset += 10
|
||||||
favorites = client.get('/users/' + str(user.id) + '/favorites', limit=10, offset=offset)
|
favorites = client.get('/users/' + str(user.id) + '/favorites', limit=10, offset=offset)
|
||||||
print('All users favorites downloaded!')
|
log('All users favorites downloaded!', strverbosity=1)
|
||||||
|
|
||||||
|
|
||||||
def download_my_stream():
|
def download_my_stream():
|
||||||
|
@ -275,7 +295,7 @@ def download_my_stream():
|
||||||
"""
|
"""
|
||||||
client = soundcloud.Client(access_token=token, client_id=scdl_client_id)
|
client = soundcloud.Client(access_token=token, client_id=scdl_client_id)
|
||||||
activities = client.get('/me/activities')
|
activities = client.get('/me/activities')
|
||||||
print(activities)
|
log(activities, strverbosity=3)
|
||||||
|
|
||||||
|
|
||||||
def download_playlist(playlist):
|
def download_playlist(playlist):
|
||||||
|
@ -286,7 +306,7 @@ def download_playlist(playlist):
|
||||||
for track_raw in playlist.tracks:
|
for track_raw in playlist.tracks:
|
||||||
count += 1
|
count += 1
|
||||||
mp3_url = get_item(track_raw["permalink_url"])
|
mp3_url = get_item(track_raw["permalink_url"])
|
||||||
print('Track n°%d' % (count))
|
log('Track n°%d' % (count), strverbosity=1)
|
||||||
download_track(mp3_url)
|
download_track(mp3_url)
|
||||||
|
|
||||||
|
|
||||||
|
@ -295,13 +315,13 @@ def download_all(tracks):
|
||||||
Download all song of a page
|
Download all song of a page
|
||||||
Not recommended
|
Not recommended
|
||||||
"""
|
"""
|
||||||
print("NOTE: This will only download the songs of the page.(49 max)")
|
log("NOTE: This will only download the songs of the page.(49 max)", strverbosity=0)
|
||||||
print("I recommend you to provide an user link and a download type.")
|
log("I recommend you to provide an user link and a download type.", strverbosity=0)
|
||||||
count = 0
|
count = 0
|
||||||
for track in tracks:
|
for track in tracks:
|
||||||
count += 1
|
count += 1
|
||||||
print("")
|
log("", strverbosity=1)
|
||||||
print('Track n°%d' % (count))
|
log('Track n°%d' % (count), strverbosity=1)
|
||||||
download_track(track)
|
download_track(track)
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,21 +330,21 @@ def download_track(track):
|
||||||
Downloads a track
|
Downloads a track
|
||||||
"""
|
"""
|
||||||
global filename
|
global filename
|
||||||
arguments = docopt(__doc__, version='0.1')
|
global arguments
|
||||||
|
|
||||||
if track.streamable:
|
if track.streamable:
|
||||||
stream_url = client.get(track.stream_url, allow_redirects=False)
|
stream_url = client.get(track.stream_url, allow_redirects=False)
|
||||||
else:
|
else:
|
||||||
print('%s is not streamable...' % (track.title))
|
log('%s is not streamable...' % (track.title), strverbosity=0)
|
||||||
print('')
|
log('', strverbosity=1)
|
||||||
return
|
return
|
||||||
title = track.title
|
title = track.title
|
||||||
title = title.replace("–", "-")
|
title = title.replace("–", "-")
|
||||||
print("Downloading " + title)
|
log("Downloading " + title, strverbosity=1)
|
||||||
|
|
||||||
#filename
|
#filename
|
||||||
if track.downloadable:
|
if track.downloadable:
|
||||||
print('Downloading the orginal file.')
|
log('Downloading the orginal file.', strverbosity=1)
|
||||||
url = track.download_url + '?client_id=' + scdl_client_id
|
url = track.download_url + '?client_id=' + scdl_client_id
|
||||||
|
|
||||||
filename = urllib.request.urlopen(url).info()['Content-Disposition'].split('filename=')[1]
|
filename = urllib.request.urlopen(url).info()['Content-Disposition'].split('filename=')[1]
|
||||||
|
@ -338,39 +358,37 @@ def download_track(track):
|
||||||
title = ''.join(c for c in title if c not in invalid_chars)
|
title = ''.join(c for c in title if c not in invalid_chars)
|
||||||
filename = title + '.mp3'
|
filename = title + '.mp3'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Download
|
# Download
|
||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
wget.download(url, filename)
|
wget.download(url, filename)
|
||||||
print('')
|
log('', strverbosity=1)
|
||||||
if '.mp3' in filename:
|
if '.mp3' in filename:
|
||||||
try:
|
try:
|
||||||
settags(track)
|
settags(track)
|
||||||
except:
|
except:
|
||||||
print('Error trying to set the tags...')
|
log('Error trying to set the tags...', strverbosity=0)
|
||||||
else:
|
else:
|
||||||
print('This type of audio don\'t support tag...')
|
log('This type of audio don\'t support tag...', strverbosity=0)
|
||||||
else:
|
else:
|
||||||
if arguments["-c"]:
|
if arguments["-c"]:
|
||||||
print(title + " already Downloaded")
|
log(title + " already Downloaded", strverbosity=1)
|
||||||
print('')
|
log('', strverbosity=1)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
print('')
|
log('', strverbosity=1)
|
||||||
print("Music already exists ! (exiting)")
|
log("Music already exists ! (exiting)", strverbosity=0)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
print('')
|
log('', strverbosity=1)
|
||||||
print(filename + ' Downloaded.')
|
log(filename + ' Downloaded.', strverbosity=1)
|
||||||
print('')
|
log('', strverbosity=1)
|
||||||
|
|
||||||
|
|
||||||
def settags(track):
|
def settags(track):
|
||||||
"""
|
"""
|
||||||
Set the tags to the mp3
|
Set the tags to the mp3
|
||||||
"""
|
"""
|
||||||
print("Settings tags...")
|
log("Settings tags...", strverbosity=1)
|
||||||
user = client.get('/users/' + str(track.user_id), allow_redirects=False)
|
user = client.get('/users/' + str(track.user_id), allow_redirects=False)
|
||||||
|
|
||||||
artwork_url = track.artwork_url
|
artwork_url = track.artwork_url
|
||||||
|
@ -387,7 +405,7 @@ def settags(track):
|
||||||
if artwork_url is not None:
|
if artwork_url is not None:
|
||||||
audio["APIC"] = mutagen.id3.APIC(encoding=3, mime='image/jpeg', type=3, desc='Cover', data=open('/tmp/scdl.jpg', 'rb').read())
|
audio["APIC"] = mutagen.id3.APIC(encoding=3, mime='image/jpeg', type=3, desc='Cover', data=open('/tmp/scdl.jpg', 'rb').read())
|
||||||
else:
|
else:
|
||||||
print("Artwork can not be set.")
|
log("Artwork can not be set.", strverbosity=0)
|
||||||
audio.save()
|
audio.save()
|
||||||
|
|
||||||
|
|
||||||
|
@ -401,8 +419,8 @@ def signal_handler(signal, frame):
|
||||||
if not os.path.isdir(f) and ".tmp" in f:
|
if not os.path.isdir(f) and ".tmp" in f:
|
||||||
os.remove(f)
|
os.remove(f)
|
||||||
|
|
||||||
print('')
|
log('')
|
||||||
print('Good bye!')
|
log('Good bye!')
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in New Issue