def run(self): api = Api() if len(self.username) == 0 or len(self.password) == 0: print "Credentials not supplied, cannot get information from Google Music" else: logged_in = False attempts = 0 while not logged_in and attempts < 3: logged_in = api.login(self.username, self.password) attempts += 1 if not api.is_authenticated(): print "Could not log in to Google Music with the supplied credentials." else: print "Logged in to Google Music" self.callback(api)
class GMusicRater: def __init__(self, files): self.__api = Api() self.__by_rating = {} self.__needs_rating_update = [] # fill list of songs lib = [] cachefile = "gmusic.pickle" if os.path.isfile(cachefile): print "Loading cached library..." infile = open(cachefile, "rb") lib = cPickle.load(infile) else: self.__log_in() print "Getting music..." lib = self.__api.get_all_songs() print "Writing..." outfile = open(cachefile, "wb+") cPickle.dump(lib, outfile) # order list of songs by rating notfound = [] total_found = 0 for s in lib: r = files.find_rating(s) # error finding file: if r < 0: notfound.append(s) continue # print "Got rating for %s: %s" % (s["title"], s["rating"]) # file rating is different from cloud rating: if not r == s["rating"]: s["rating"] = r self.__needs_rating_update.append(s) if not self.__by_rating.has_key(r): self.__by_rating[r] = [] self.__by_rating[r].append(s) total_found += 1 print "Found %d cloud songs, %d of which need rating updates." % (total_found, len(self.__needs_rating_update)) print "Not found on disk: %d" % len(notfound) for s in notfound: print " %s - %s" % (s["artist"], s["title"]) def __log_in(self): if self.__api.is_authenticated(): return print "Logging in..." email = raw_input("Email: ") password = getpass.getpass() if not self.__api.login(email, password): print "couldnt log in" sys.exit(1) def reset_playlists(self): self.__log_in() playlists = self.__api.get_all_playlist_ids(auto=False, user=True)["user"] print "Got %d playlists:" % len(playlists) for k, v in playlists.iteritems(): print " Deleting %s (%s)" % (k, v) for playlistid in v: self.__api.delete_playlist(playlistid) def get_ids(slist): ret = [] for s in slist: ret.append(s["id"]) return ret awesome_songids = get_ids(self.__by_rating.get(5, [])) good_songids = awesome_songids + get_ids(self.__by_rating.get(4, [])) unrated_songids = get_ids(self.__by_rating.get(0, [])) awesome_pid = self.__api.create_playlist("Awesome") print "Awesome %s -> %d songs" % (awesome_pid, len(awesome_songids)) self.__api.add_songs_to_playlist(awesome_pid, awesome_songids) good_pid = self.__api.create_playlist("Good") print "Good %s -> %d songs" % (good_pid, len(good_songids)) self.__api.add_songs_to_playlist(good_pid, good_songids) unrated_pid = self.__api.create_playlist("Unrated") print "Unrated %s -> %d songs" % (unrated_pid, len(unrated_songids)) self.__api.add_songs_to_playlist(unrated_pid, unrated_songids) def update_ratings(self): total = len(self.__needs_rating_update) if total == 0: return self.__log_in() print "Updating %d songs..." % total # divide updates into chunks. start = 0 chunksz = 100 # could probably be larger, wasn't tested for max possible while start < total: end = start + chunksz if end >= total: end = total print "%d - %d" % (start, end) self.__api.change_song_metadata(self.__needs_rating_update[start:end]) start = end def logout(self): if self.__api.is_authenticated(): print "Logging out..." self.__api.logout()
def main(argv): '''Farm out work to task-based methods. :param argv: list of command line arguments ''' # process command line options usage = """%prog [OPTIONS]... [COMMAND] [ARGS]... %prog [OPTIONS]... diff %prog [OPTIONS]... sync %prog [OPTIONS]... fs (not working) %prog [OPTIONS]... track UPDATE_KEYS[...] %prog [OPTIONS]... playlist [PLAYLIST]... %prog [OPTIONS]... delete [PLAYLIST]... %prog [OPTIONS]... validate %prog [OPTIONS]... dump TRACK_KEY[...]""" version_str = "{0} {1}".format(pkg, __version__) parser = OptionParser(usage=usage, version=version_str) # default banshee database banshee_db_def = os.environ['HOME'] + '/.config/banshee-1/banshee.db' banshee_db_help = "use Banshee database BANSHEE_DB (default {0})".format(banshee_db_def) parser.add_option("-b", "--banshee-db", default=banshee_db_def, help=banshee_db_help) parser.add_option("-d", "--dry-run", action="store_true", default=False, help="perform no action, just report what would be done") parser.add_option("-q", "--quiet", action="store_true", help="do not print status messages") # default minimum rating rating_def = 3 rating_help = "only consider Banshee songs with rating >= RATING (default {0})".format(rating_def) parser.add_option("-r", "--rating", type="int", default=rating_def, help=rating_help) (options, args) = parser.parse_args() # set "globals" global dryrun dryrun = options.dry_run logmsg.quiet = options.quiet # open log file logmsg.log_f = codecs.open(pkg + '.log', mode='w', encoding='utf-8') # determine action command = 'diff' if len(args): command = args[0] # save the rest args = args[1:] # log in to Google Music (gm) api = Api() gm_tracks = {} # sync and fs do not need connection to gm if command != 'sync' and command != 'fs': logged_in = False attempts = 0 while not logged_in and attempts < 3: email = raw_input("Email: ") password = getpass() logged_in = api.login(email, password) attempts += 1 if not api.is_authenticated(): logmsg('google credentials were not accepted', True) return logmsg("successfully logged in to google") # get the google music library gm_tracks = get_gm_library(api) # connect to banshee database banshee_conn = sqlite3.connect(options.banshee_db) if not banshee_conn: logmsg('unable to connect to banshee: {0}'.format(options.banshee_db), True) return # get the banshee library b_tracks = get_b_library(banshee_conn, options.rating) # dispatch rv = 0 if command == 'diff': # create files not in google music rv = diff(gm_tracks, b_tracks) elif command == 'sync': # create all files with sufficient rating rv = sync(b_tracks) elif command == 'fs': # check banshee database and file system for consistency rv = fs(b_tracks) elif command == 'track': # update track metadata rv = track(api, gm_tracks, b_tracks, args) elif command == 'playlist': # get banshee playlists b_playlists = get_b_playlists(banshee_conn, args) # upload banshee playlists to google music rv = playlist(api, gm_tracks, b_playlists) elif command == 'validate': # make sure the gm track metadata does not have bad characters rv = validate(gm_tracks) elif command == 'delete': # get banshee playlists b_playlists = get_b_playlists(banshee_conn, args) # delete tracks on banshee playlists from google music rv = delete(api, gm_tracks, b_playlists) elif command == 'dump': rv = dump(gm_tracks, args) else: logmsg('unknown command: {0}'.format(command), True) return # logout of gm api.logout() # disconnect from banshee database banshee_conn.close() # close log file logmsg.log_f.close if rv: sys.exit(0) # else sys.exit(1) # just in case return