#!/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()