Last active
February 6, 2016 04:59
-
-
Save nogweii/468ab5900d5f1efae130 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python2 | |
# A fairly simple script to download all of the music you paid for on Google Play Music to your hard drive. Not smart | |
# at all, will redownload the music if you run it a second time. | |
# | |
# Meant to run against gmusicapi v7. The next release shouldn't need the Paidmanager subclass hack. | |
import gmusicapi | |
from IPython import embed | |
import mutagen | |
import os | |
class Paidmanager(gmusicapi.clients.Musicmanager): | |
def get_purchased_songs(self, incremental=False): | |
""" | |
A hacked up version of the proper method once #406 is merged in and a | |
release made | |
""" | |
to_return = self._get_all_p_songs() | |
if not incremental: | |
to_return = [song for chunk in to_return for song in chunk] | |
return to_return | |
def _get_all_p_songs(self): | |
"""Return a generator of song chunks. Hard-coded to return only | |
purchased songs.""" | |
get_next_chunk = True | |
# need to spoof .continuation_token access, and | |
# can't add attrs to object(). Can with functions. | |
lib_chunk = lambda: 0 # noqa | |
lib_chunk.continuation_token = None | |
while get_next_chunk: | |
lib_chunk = self._make_call(gmusicapi.protocol.musicmanager.ListTracks, | |
self.uploader_id, | |
lib_chunk.continuation_token, 2) | |
yield [self._track_info_to_dict(info) | |
for info in lib_chunk.download_track_info] | |
get_next_chunk = lib_chunk.HasField('continuation_token') | |
print "Hello, retrieving your purchased songs from Google Music." | |
storage_dir = os.getenv('GMUSIC_PAID_DIR') | |
print "Putting all of your music into " + storage_dir | |
print "Logging in" | |
client = Paidmanager() | |
client.login() | |
print "Getting song information" | |
songs = client.get_purchased_songs() | |
total_count = len(songs) | |
print "Synchronizing %d songs" % (total_count) | |
#uncomment if debugging: | |
#embed() | |
for song_index, song in enumerate(songs): | |
print "Downloading '%(name)s' by %(artist)s (song %(index)d/%(count)d)" % \ | |
{'name': song['title'], 'index': song_index, 'count': total_count, 'artist': song['artist']} | |
file_name, audio_contents = client.download_song(song['id']) | |
album_dir = os.path.join(storage_dir, song['artist'], song['album']) | |
#break # stop after the first one | |
if not os.path.exists(album_dir): | |
os.makedirs(album_dir, 0755) | |
song_path = os.path.join(album_dir, file_name) | |
with open(song_path, mode='wb') as audio_file: | |
audio_file.write(audio_contents) | |
#print song_path |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment