Ejemplo n.º 1
0
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()