예제 #1
0
        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)
예제 #2
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()
예제 #3
0
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