91 lines
2.7 KiB
Python
91 lines
2.7 KiB
Python
#!/usr/bin/env
|
|
|
|
desc = '''
|
|
This is a Python application which gets music from Spotify and stores it in
|
|
MP3 files, in a directory structure like "./Artist/Album/Song.mp3".
|
|
It takes Spotify URIs for individual songs, as well as playlists.
|
|
It also creates the appropriate ID3 tags.
|
|
'''
|
|
import argparse
|
|
import threading
|
|
from subprocess import Popen, PIPE, call
|
|
|
|
from spotify import Session, SessionConfig, Bitrate
|
|
|
|
from lib import (
|
|
Callbacks, create_path, formatted_track_name, format_path, get_id3
|
|
)
|
|
from settings import username, password
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=desc)
|
|
parser.add_argument("--URI", help="Valid Spotify URI")
|
|
args = parser.parse_args()
|
|
|
|
session = Session(config=SessionConfig(), callbacks=Callbacks())
|
|
session.preferred_bitrate(Bitrate.BITRATE_320k)
|
|
session.callbacks.URI = args.URI
|
|
session.callbacks.tracks_loaded = threading.Event()
|
|
|
|
session.login(username, password)
|
|
session.process_events()
|
|
|
|
session.callbacks.tracks_loaded.wait()
|
|
|
|
for track in session.callbacks.tracks:
|
|
track.load()
|
|
track_name = formatted_track_name(track)
|
|
print "Ripping track: {}.".format(track_name)
|
|
|
|
if track.is_autolinked:
|
|
track = track.playable
|
|
|
|
session.callbacks.delivery = threading.Event()
|
|
session.callbacks.track_ended = threading.Event()
|
|
|
|
session.player.load(track)
|
|
session.process_events()
|
|
session.player.play(play=True)
|
|
|
|
while True:
|
|
if session.callbacks.track_ended.is_set():
|
|
print "Done receiving audio data for {}.".format(track_name)
|
|
session.callbacks.track_ended.clear()
|
|
break
|
|
|
|
session.callbacks.delivery.wait()
|
|
session.process_events()
|
|
print "........"
|
|
session.callbacks.delivery.clear()
|
|
|
|
path = format_path(track)
|
|
create_path(path)
|
|
|
|
frames = session.callbacks.frames
|
|
print "Processing {} frames...".format(len(frames))
|
|
|
|
id3_args = get_id3(track)
|
|
song_path = "{}{}.mp3".format(path, track.name)
|
|
|
|
cover = track.album.cover(); cover.load()
|
|
if cover.is_loaded:
|
|
cover_path = "{}cover.jpg".format(path)
|
|
with open(cover_path, 'wb') as cover_file:
|
|
cover_file.write(cover.data)
|
|
print "Album cover saved at {}".format(cover_path)
|
|
|
|
id3_args += ' --ti "{}"'.format(cover_path)
|
|
|
|
proc = Popen("lame --silent {} -V2 -h -r - \"{}\"".format(
|
|
id3_args, song_path), stdin=PIPE, shell=True)
|
|
|
|
proc.stdin.write(frames)
|
|
proc.stdin.close()
|
|
|
|
print "Done writing audio data at {}".format(song_path)
|
|
|
|
session.logout()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|