Example #1
0
def google_playlists(x):
	api = Mobileclient()
	api.login('*****@*****.**', 'rtqjkpidxwxddpur', Mobileclient.FROM_MAC_ADDRESS)
	all_playlists = api.get_all_playlists(incremental=False, include_deleted=False)
	dj_list = list(set(x['host']))
	for k, dj in enumerate(dj_list):
		# pull out subset of a given Dj
		subset = x.loc[x['host']==(dj)]
		print("\n   Analyzing "+dj+" Playlists...\n")
		# pull out subset of dj subset for a given month
		for i in np.arange(1, 12, 1):
			print('Now loading Month: '+str(i))
			artists = np.load(dj+'/'+'2015-'+str(i)+'-artists.npy')
			if len(artists) == 0:
				break
			titles  = np.load(dj+'/'+'2015-'+str(i)+'-titles.npy')
			# playlist_exists = False
			# playlist_name = 'KCRW DJ '+host+', Tracks of 2015-'+str(i)
			# print("Searching for playlist named: " + playlist_name)
			# for playlist in all_playlists:
			# 	if playlist['name'] == playlist_name:
			# 		playlist_exists = True
			# 		playlist_id = playlist['id']
			# 		print("Playlist exists, adding new songs to playlist: "+playlist_name)
			# if not playlist_exists:
			# 	playlist_id = api.create_playlist(playlist_name, description=None, public=False)
			# 	print("Playlist is new, creating playlist and adding new songs to: "+playlist_name)
			search_google(api, artists, titles)
Example #2
0
 def search(self, lib, opts, args):
     password = config['gmusic']['password']
     email = config['gmusic']['email']
     password.redact = True
     email.redact = True
     # Since Musicmanager doesn't support library management
     # we need to use mobileclient interface
     mobile = Mobileclient()
     try:
         mobile.login(email.as_str(), password.as_str(),
                      Mobileclient.FROM_MAC_ADDRESS)
         files = mobile.get_all_songs()
     except NotLoggedIn:
         ui.print_(
             u'Authentication error. Please check your email and password.'
         )
         return
     if not args:
         for i, file in enumerate(files, start=1):
             print(i, ui.colorize('blue', file['artist']),
                   file['title'], ui.colorize('red', file['album']))
     else:
         if opts.track:
             self.match(files, args, 'title')
         else:
             self.match(files, args, 'artist')
def login_to_google_music(user):
    api = Mobileclient()

    # Try to read the username and password from a file
    # This is useful for 2-step authentication
    # Don't store your regular password in plain text!
    try:
        creds_file = open(CREDS_FILE)
        creds = json.load(creds_file)
    except IOError:
        creds = {}

    try:
        user = creds["username"]
    except KeyError:
        if not user:
            user = raw_input("Google username/email: ")

    try:
        password = creds["password"]
    except KeyError:
        password = getpass()

    print "\nLogging in..."
    if api.login(user, password, Mobileclient.FROM_MAC_ADDRESS):
        return api
    else:
        print "Login failed. Giving up."
        exit(1)
    def start(self):
        """
        Start the sync
        """

        api = Webclient()
        apim = Mobileclient()
        apim.login(self.email, self.password)

        try:
            api.login(self.email, self.password)
            xml_file = open('self.xml_file', 'r').read()

            print "Parsing songs from iTunes XML file..."
            itunes_song_list = self.__get_itunes_song_list(xml_file)
            print "iTunes XML file parsing complete"

            print "Retrieving songs from Google Music..."
            gmusic_song_list = self.__get_gmusic_song_list(apim)
            print "Google Music song retrieval complete"

            print "Computing the intersection of the song lists..."
            song_list = self.__get_intersection(gmusic_songs=gmusic_song_list, itunes_songs=itunes_song_list,
                                                only_no_rating=self.only_no_rating)
            print "Song list intersection computed"

            print "Syncing song ratings..."
            self.__sync_song_ratings(api, song_list)
            print "Song ratings sync complete!"

        except CallFailure:
            print "Error: Couldn't log in to Google Music!"
        except IOError:
            print "Error: iTunes XML file not found"
Example #5
0
class GoogleMusic(Source):
    def __init__(self, library, username, password):
        Source.__init__(self, library, SourceType.GOOGLE)
        self.GOOGLE_DEVICE_ID = None

        print username
        print password

        self.client = Mobileclient()
        logged_in = self.client.login(username, password, Mobileclient.FROM_MAC_ADDRESS)
        print "Google logged in:", logged_in

        DList = self.client.get_registered_devices()
        self.GOOGLE_DEVICE_ID = DList[0]["id"]
        if self.GOOGLE_DEVICE_ID[:2] == '0x':
            self.GOOGLE_DEVICE_ID = self.GOOGLE_DEVICE_ID[2:]

        print self.GOOGLE_DEVICE_ID

        #>testing
        # self.get_stream_URL("47b9d52c-9d66-3ff2-94d4-3ae55c0d2acc")

    def get_stream_URL(self, song_id):
        return self.client.get_stream_url(song_id, self.GOOGLE_DEVICE_ID)

    def sync(self):
        gmusic_tracks = self.client.get_all_songs()
        for track in gmusic_tracks:
            art = ''
            try:
                art = track['albumArtRef'][0]['url']
            except KeyError:
                art = ''
            self.library.insert_track(track['title'], track['album'], track['artist'], self._source, str(track['id']), track['trackNumber'], art)
Example #6
0
class gmObject:
    
    def __init__(self):
        self.mc = Mobileclient()
        self.wc = Webclient()
        self.mm = Musicmanager()
    
    def login(self, username, password):
        error.e = 0
        
        if not self.mc.login(username, password):
            gmtPrintV("gmObject.login: Wrong username or password (or no internet connection)")
            error.e = error.LOGIN_FAILED
            return
        
        if not self.wc.login(username, password):
            gmtPrintV("gmObject.login: Wrong username or password (or no internet connection)")
            error.e = error.LOGIN_FAILED
            return
        
        if not self.mm.login(config.cred_path):
            gmtPrintV("gmObject.login: Wrong credentials (or no internet connection)")
            error.e = error.LOGIN_FAILED
            return
        
    def logout(self):
        error.e = 0
        
        try:
            self.mc.logout()
            self.wc.logout()
            self.mm.logout()
        except:
            gmtPrintV("gmObject.logout: Logout failed")
            error.e = error.LOGOUT_FAILED
def login_to_google_music(user):
    api = Mobileclient()
    attempts = 0

    while attempts < 3:
        if user == None:
            user = raw_input("Google username or email: ")

        # Try to read the password from a file
        # If file doesn't exist, ask for password
        # This is useful for 2-step authentication only
        # Don't store your regular password in plain text!
        try:
            pw_file = open("pass.txt")
            password = pw_file.readline()
            print "Reading password from pass.txt."
        except IOError:
            password = getpass()

        print "\nLogging in..."
        if api.login(user, password):
            return api
        else:
            print "Login failed."
            # Set the username to none so it is prompted to be re-entered on the next loop iteration
            user = None
            attempts += 1

    print str(attempts) + " failed login attempts. Giving up."
    exit(0)
def ask_for_credentials():
    """Make an instance of the api and attempts to login with it.
    Returns the authenticated api.
    """

    # We're not going to upload anything, so the Mobileclient is what we want.
    api = Mobileclient(debug_logging=False)

    logged_in = False
    attempts = 0

    #try:
    #    logged_in = api.login("mail", "pass", Mobileclient.FROM_MAC_ADDRESS)
    #except:
    #    print(Fore.YELLOW + "Error logging you in!")

    while not logged_in and attempts < 3:
        print("Please log in into your Google Play account.")
        email = input('Email: ')
        password = getpass()

        logged_in = api.login(email, password, Mobileclient.FROM_MAC_ADDRESS)
        attempts += 1

    return api
Example #9
0
 def __init__(self, fileName):
     '''
     Initializes the API with user credentials
     :param: fileName Reference to the file with authentication information
     :return: Reference to the API
     '''
     api = Mobileclient()
     # read in the auth file
     cntr = 0
     for line in open(fileName):
         if (cntr == 0):
             user = line.strip()
         if (cntr == 1):
             app_pwd = line.strip()
         cntr += 1
     # bail before potential exception
     if (cntr != 2):
         print("ERROR: Improperly formatted auth file.", file=sys.stderr)
         exit(1)
     # TODO improve MAC id
     logged_in = api.login(user, app_pwd, Mobileclient.FROM_MAC_ADDRESS)
     # error handling for auth
     if not(logged_in):
         print("ERROR: Unable to log in.", file=sys.stderr)
         exit(1)
     return api
Example #10
0
def main():

    api = Mobileclient()
    if not api.login(credentials.email, credentials.password):
        print "Couldn't log in :("
        return

    check_playlists(api)
    def __sync_song_ratings(self, apim, songs):
        apim = Mobileclient()
        apim.login(self.email, self.password)

        """
        Sync ratings to Google Music
        """

        apim.change_song_metadata(songs)
Example #12
0
def main():

    api = Mobileclient()
    if not api.login(credentials.email, credentials.password):
        print "Couldn't log in :("
        return

    regen_playlist(api, 'All')
    regen_playlist(api, 'Programming')
def setup_mobile_api():
    global mobile_api
    mobile_api = Mobileclient()

    mobile_logged_in = mobile_api.login(username, password)

    if not mobile_logged_in:
        print "Failed to log in to the mobile API, ensure your details are correct and try again."
        sys.exit(0)
Example #14
0
    def test_google_login(self):

        google_username = os.environ['INFRADIO_TEST_GOOGLE_USERNAME']
        google_password = os.environ['INFRADIO_TEST_GOOGLE_PASSWORD']

        from gmusicapi import Mobileclient

        api = Mobileclient()
        self.assertTrue(api.login(google_username, google_password,
                                  Mobileclient.FROM_MAC_ADDRESS))
Example #15
0
    def login(self):
        if self.api is not None:
            return self.api
        
        debug("logging in as {}", self.config["email"])
        
        api = Mobileclient(debug_logging=DEBUG)
        api.login(self.config["email"], self.config["password"], Mobileclient.FROM_MAC_ADDRESS)

        self.api = api
        
        return api
Example #16
0
class GMusicWS:
	def __init__(self, user, password, playlistName):
		self.playlistName = playlistName
		self.api = Mobileclient()
		print ("Logging into MobileClient API")
		self.api.login(user, password,"android_id") #insert unique android_id here

	def mapUnknownTracks(self, db):
		playlist = db.unmappedTracks()
		
		for track in playlist:
			searchstr = track.artist + " " + track.song
			print ("Searching for %s" % (searchstr))
			try:
				result = self.api.search_all_access(searchstr, max_results=1)
				print ("Found " + result['song_hits'][0]['track']['artist'] + " - " + result['song_hits'][0]['track']['title'])
				nid = result['song_hits'][0]['track']['nid']
				db.storemapping(track.song, track.artist, nid)
			except:
				print ("Error parsing result: " + str(result))
				
			time.sleep(1)
	
	def maintain(self, tracks):
		print ("Searching for playlist %s" % (self.playlistName))
				
		found = False
		searchres = self.api.get_all_playlists()
		for list in searchres:
			if list['name'] == self.playlistName:
				found = True
				pid = list['id']
				
		if not found:
			print ("Not found - creating")
			pid = self.api.create_playlist(self.playlistName)
		
		print ("Playlist id is %s" % (pid))
		
		print ("Getting current contents")
		playlists = self.api.get_all_user_playlist_contents()
		currentEntries = []
		for playlist in playlists:
			if playlist['name'] == self.playlistName:
				for entry in playlist['tracks']:
					currentEntries.append(entry['id'])

		print ("Removing songs")		
		self.api.remove_entries_from_playlist(currentEntries)
		
		print ("Adding songs")
		self.api.add_songs_to_playlist(pid, tracks)
Example #17
0
def _get_global_tracks(api: gmusicapi.Mobileclient, artist_ids, album_ids):
    artist_ids = list(artist_ids)
    album_ids = list(album_ids)

    for artist_id in artist_ids:
        results = api.get_artist_info(artist_id)
        for album_stub in results['albums']:
            album_id = album_stub['albumId']
            album_ids.append(album_id)

    for album_id in album_ids:
        album = api.get_album_info(album_id)
        yield from album['tracks']
Example #18
0
def main(path):
    api = Mobileclient()
    logged_in = api.login(EMAIL, PASSWORD)

    if logged_in:
        print("Succesfully logged in, retrieving all songs and running check...")
        all_songs = api.get_all_songs()
        tracks = remove_dups(all_songs)
        results = find_in_lib(path, tracks)
        print("saving file to %s" % os.path.join(os.getcwd(), "output.json"))
        with open("output.json", "w+") as f:
            f.write(json.dumps(results))
            f.close()
Example #19
0
def open_api():
    global api
    log('Logging into google music...')
    api = Mobileclient()
    if not api.oauth_login(Mobileclient.FROM_MAC_ADDRESS):
        log('ERROR unable to login')
        time.sleep(3)
        exit()

    password = None
    log('Login Successful.')
    dlog(u'Available track details: '+str(get_google_track_details()))
    return api
Example #20
0
def login():
    # get the password each time so that it isn't stored in plain text
    password = getpass.getpass(username + '\'s password: '******'ERROR unable to login'
        time.sleep(3)
        exit()
        
    password = None

    return api
Example #21
0
def init_gmusic():
    """Request credentials, authenticate and connect to Google Music. Return
    authenticated MobileClient instance.
    """

    username = raw_input("Please enter your Google username: "******"Please enter password for user %s: " % username)
    gmusic = Mobileclient()
    logged_in = gmusic.login(username, password, Mobileclient.FROM_MAC_ADDRESS)
    if not logged_in:
        raise Exception("Failed to authenticate google music account")
        sys.exit(2)
    return gmusic
Example #22
0
    def __init__(self, email, password, device_id):
        self.__gmusic = Mobileclient()
        self.__email = email
        self.__device_id = device_id
        self.logged_in = False
        self.queue = list()
        self.queue_index = -1
        self.play_queue_order = list()
        self.play_modes = TizEnumeration(["NORMAL", "SHUFFLE"])
        self.current_play_mode = self.play_modes.NORMAL
        self.now_playing_song = None

        userdir = os.path.expanduser('~')
        tizconfig = os.path.join(userdir, ".config/tizonia/." + email + ".auth_token")
        auth_token = ""
        if os.path.isfile(tizconfig):
            with open(tizconfig, "r") as f:
                auth_token = pickle.load(f)
                if auth_token:
                    # 'Keep track of the auth token' workaround. See:
                    # https://github.com/diraimondo/gmusicproxy/issues/34#issuecomment-147359198
                    print_msg("[Google Play Music] [Authenticating] : " \
                              "'with cached auth token'")
                    self.__gmusic.android_id = device_id
                    self.__gmusic.session._authtoken = auth_token
                    self.__gmusic.session.is_authenticated = True
                    try:
                        self.__gmusic.get_registered_devices()
                    except CallFailure:
                        # The token has expired. Reset the client object
                        print_wrn("[Google Play Music] [Authenticating] : " \
                                  "'auth token expired'")
                        self.__gmusic = Mobileclient()
                        auth_token = ""

        if not auth_token:
            attempts = 0
            print_nfo("[Google Play Music] [Authenticating] : " \
                      "'with user credentials'")
            while not self.logged_in and attempts < 3:
                self.logged_in = self.__gmusic.login(email, password, device_id)
                attempts += 1

            with open(tizconfig, "a+") as f:
                f.truncate()
                pickle.dump(self.__gmusic.session._authtoken, f)

        self.library = CaseInsensitiveDict()
        self.song_map = CaseInsensitiveDict()
        self.playlists = CaseInsensitiveDict()
        self.stations = CaseInsensitiveDict()
Example #23
0
class GMusicAPI():
    def __init__(self, username=None, encrypted_pass=None):
        self._api = Mobileclient()
        self.logged_in = False
        if username and encrypted_pass:
            self.login(username, encrypted_pass)

    def login(self, username, encrypted_pass):
        self.logged_in = self._api.login(username, decrypt(encrypted_pass), Mobileclient.FROM_MAC_ADDRESS)

    def logout(self):
        self._api.logout()
        self.logged_in = False

    def clear_playlist(self, playlist_name):
        playlists = self._api.get_all_user_playlist_contents()
        playlist = [playlist for playlist in playlists if playlist['name'] == playlist_name][0]
        entry_ids = [entry['id'] for entry in playlist['tracks']]
        removed = self._api.remove_entries_from_playlist(entry_ids)
        return len(removed)

    def search(self, *args):
        """
        Returns the best-fitting track dict for the given information.
        :param args: Strings which can be artist, song title, album etc.
        :return:
        """
        query = sanitise_query(' '.join(args))

        result = self._api.search(query)

        song_results = result['song_hits']
        if not song_results:
            warnings.warn('Warning: query {} returned no song hits.'.format(query))
            return None

        tracks = [song_result['track'] for song_result in song_results[:5]]

        for track in tracks:
            if not is_tribute(track, query):
                return track

        warnings.warn('Warning: query {} returned no non-tribute song hits.'.format(query))
        return None

    def get_playlist_id(self, playlist_name):
        for playlist in self._api.get_all_playlists():
            if playlist['name'] == playlist_name:
                return playlist['id']
        raise ValueError("Playlist '{}' not found".format(playlist_name))

    def add_songs(self, playlist_name, tracks):
        playlist_id = self.get_playlist_id(playlist_name)
        track_ids = [track['nid'] for track in tracks if track]
        self._api.add_songs_to_playlist(playlist_id, track_ids)
Example #24
0
def open_api():
    global api
    log('Logging into google music...')
    # get the password each time so that it isn't stored in plain text
    
    api = Mobileclient()
    if not api.login(username, password, Mobileclient.FROM_MAC_ADDRESS):
        log('ERROR unable to login')
        time.sleep(3)
        exit()
        
    log('Login Successful.')
    dlog(u'Available track details: '+str(get_google_track_details()))
    return api
def login_gpm():
    #takes credentials and checks user login of Google
    username = raw_input("Enter your Google Play username: "******"Enter your Google Play password: "******"\nNot a valid login")
        exit()
    else:
        print("\nLogin success!")
        return gpm
Example #26
0
 def authenticate(self, email=None, password=None):
     # create the gmusicapi client and attempt to login
     # TODO: store the client somewhere so we can use it for music
     gmc = Mobileclient()
     valid = gmc.login(email, password)
     if valid:
         try:
             user = User.objects.get(username=username)
         except User.DoesNotExist:
             # Create a new user. We don't need to store the password
             user = User(username=username, password='******')
             # TODO: store some basic account info
             user.save()
         return user
     return None
def login():
    config = ConfigParser.ConfigParser()
    config.read('config.ini')

    email = config.get('login', 'email')
    password = config.get('login', 'password')

    print "Logging into Google Play Music as", email
    api = Mobileclient()
    login = api.login(email, password, Mobileclient.FROM_MAC_ADDRESS)

    if not login:
        print "<< Couldn't login. >>"
        sys.exit()
    
    return api
Example #28
0
 def __init__(self, google_username, google_password):
     self.client = Mobileclient(validate=False)
     # generate a stable, unique android id
     h = hashlib.sha256()
     h.update(google_username)
     android_id = h.hexdigest()[:16]
     self.client.login(google_username, google_password, android_id)
Example #29
0
 def __init__(self):
     import requests
     from requests.packages.urllib3.exceptions import InsecureRequestWarning
     from requests.packages.urllib3.exceptions import InsecurePlatformWarning
     requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
     requests.packages.urllib3.disable_warnings(InsecurePlatformWarning)
     self.gmusicapi = Mobileclient(debug_logging=False, validate=False, verify_ssl=False)
Example #30
0
    def __login_and_setup(self, username=None, password=None):
        # If credentials are not specified, get them from $HOME/.gmusicfs
        if not username or not password:
            cred_path = os.path.join(os.path.expanduser('~'), '.gmusicfs')
            if not os.path.isfile(cred_path):
                raise NoCredentialException(
                    'No username/password was specified. No config file could '
                    'be found either. Try creating %s and specifying your '
                    'username/password there. Make sure to chmod 600.'
                    % cred_path)
            if not oct(os.stat(cred_path)[os.path.stat.ST_MODE]).endswith('00'):
                raise NoCredentialException(
                    'Config file is not protected. Please run: '
                    'chmod 600 %s' % cred_path)
            self.config = ConfigParser.ConfigParser()
            self.config.read(cred_path)
            username = self.config.get('credentials','username')
            password = self.config.get('credentials','password')
            global deviceId
            deviceId = self.config.get('credentials','deviceId')
            if not username or not password:
                raise NoCredentialException(
                    'No username/password could be read from config file'
                    ': %s' % cred_path)
            if not deviceId:
                raise NoCredentialException(
                    'No deviceId could be read from config file'
                    ': %s' % cred_path)

        self.api = GoogleMusicAPI(debug_logging=self.verbose)
        log.info('Logging in...')
        self.api.login(username, password)
        log.info('Login successful.')
Example #31
0
#!/usr/bin/env python


import vlc
import os
import json
from gmusicapi import Mobileclient
import os.path
from youtube_search_engine import youtube_search
from youtube_search_engine import youtube_stream_link
import yaml

with open('/home/pi/GassistPi/src/config.yaml','r') as conf:
    configuration = yaml.load(conf)

api = Mobileclient()
#If you are using two-step authentication, use app specific password. For guidelines, go through README
logged_in = api.login(configuration['Gmusicapi']['email'],configuration['Gmusicapi']['password'] , configuration['Gmusicapi']['deviceid'])


class vlcplayer():

    def __init__(self):
        self.libvlc_Instance=vlc.Instance('--verbose 0')
        self.libvlc_player = self.libvlc_Instance.media_player_new()
        # self.libvlc_list_player = self.libvlc_Instance.media_list_player_new()
        # self.libvlc_Media_list = self.libvlc_Instance.media_list_new()
        # self.libvlc_list_player.set_media_player(self.libvlc_player)
        # self.libvlc_list_player.set_media_list(self.libvlc_Media_list)
        # self.libvlc_player_event_manager= self.libvlc_player.event_manager()
    print "Please fill in the details in the .myrock_google_sync file in the current directory"
    exit(1)

#print 'Loading'
from gmusicapi import Mobileclient
import datetime
import re

try:
    # For Python 3+
    from urllib.request import urlopen
except ImportError:
    # For Python 2
    from urllib2 import urlopen

api = Mobileclient()
print 'Logging in to Google Play'
logged_in = api.login(config['username'], config['password'], Mobileclient.FROM_MAC_ADDRESS)

def findId(title, artist):
    if artist == 'Rammstein': # Rammstein is not available on Google Play only covers
        return None

    results = api.search(title + ', ' + artist)
    for song_hit in results['song_hits']:
        track = song_hit['track']
        # print track
        #if cleanString(track['title']) == cleanString(title) and cleanString(track['albumArtist']) == cleanString(artist):
        # Trust google to find the right version
        return track['storeId'] 
Example #33
0
class GMusicWrapper(object):
    def __init__(self, username, password, logger=None):
        self._api = Mobileclient()
        self.logger = logger
        success = self._api.login(
            username, password,
            environ.get('ANDROID_ID', Mobileclient.FROM_MAC_ADDRESS))

        if not success:
            raise Exception("Unsuccessful login. Aborting!")

        # Populate our library
        self.library = {}
        self.indexing_thread = threading.Thread(target=self.index_library)
        self.indexing_thread.start()

    def _search(self, query_type, query):
        try:
            results = self._api.search(query)
        except CallFailure:
            return []

        hits_key = "%s_hits" % query_type

        if hits_key not in results:
            return []

        # Ugh, Google had to make this schema nonstandard...
        if query_type == 'song':
            query_type = 'track'

        return [x[query_type] for x in results[hits_key]]

    def is_indexing(self):
        return self.indexing_thread.is_alive()

    def index_library(self):
        """
        Downloads the a list of every track in a user's library and populates
        self.library with storeIds -> track definitions
        """
        self.logger.debug('Fetching library...')
        tracks = self.get_all_songs()

        for track in tracks:
            song_id = track['id']
            self.library[song_id] = track

        self.logger.debug('Done! Discovered %d tracks.' % len(self.library))

    def get_artist(self, name):
        """
        Fetches information about an artist given its name
        """
        search = self._search("artist", name)

        if len(search) == 0:
            return False

        return self._api.get_artist_info(search[0]['artistId'],
                                         max_top_tracks=100)

    def get_album(self, name, artist_name=None):
        if artist_name:
            name = "%s %s" % (name, artist_name)

        search = self._search("album", name)

        if len(search) == 0:
            return False

        return self._api.get_album_info(search[0]['albumId'])

    def get_latest_album(self, artist_name=None):
        search = self._search("artist", artist_name)

        if len(search) == 0:
            return False

        artist_info = self._api.get_artist_info(search[0]['artistId'],
                                                include_albums=True)
        album_info = artist_info['albums']
        sorted_list = sorted(album_info.__iter__(),
                             key=lambda s: s['year'],
                             reverse=True)

        for index, val in enumerate(sorted_list):
            album_info = self._api.get_album_info(
                album_id=sorted_list[index]['albumId'], include_tracks=True)
            if len(album_info['tracks']) >= 5:
                return album_info

        return False

    def get_album_by_artist(self, artist_name, album_id=None):
        search = self._search("artist", artist_name)
        if len(search) == 0:
            return False

        artist_info = self._api.get_artist_info(search[0]['artistId'],
                                                include_albums=True)
        album_info = artist_info['albums']
        random.shuffle(album_info)

        for index, val in enumerate(album_info):
            album = self._api.get_album_info(
                album_id=album_info[index]['albumId'], include_tracks=True)
            if album['albumId'] != album_id and len(album['tracks']) >= 5:
                return album

        return False

    def get_song(self, name, artist_name=None, album_name=None):
        if artist_name:
            name = "%s %s" % (artist_name, name)
        elif album_name:
            name = "%s %s" % (album_name, name)

        search = self._search("song", name)

        if len(search) == 0:
            return False

        if album_name:
            for i in range(0, len(search) - 1):
                if album_name in search[i]['album']:
                    return search[i]
        return search[0]

    def get_station(self, title, track_id=None, artist_id=None, album_id=None):
        if artist_id is not None:
            if album_id is not None:
                if track_id is not None:
                    return self._api.create_station(title, track_id=track_id)
                return self._api.create_station(title, album_id=album_id)
            return self._api.create_station(title, artist_id=artist_id)

    def get_station_tracks(self, station_id):
        return self._api.get_station_tracks(station_id)

    def get_google_stream_url(self, song_id):
        return self._api.get_stream_url(song_id)

    def get_stream_url(self, song_id):
        return "%s/alexa/stream/%s" % (environ['APP_URL'], song_id)

    def get_thumbnail(self, artist_art):
        return artist_art.replace("http://", "https://")

    def get_all_user_playlist_contents(self):
        return self._api.get_all_user_playlist_contents()

    def get_all_songs(self):
        return self._api.get_all_songs()

    def rate_song(self, song, rating):
        return self._api.rate_songs(song, rating)

    def extract_track_info(self, track):
        # When coming from a playlist, track info is nested under the "track"
        # key
        if 'track' in track:
            track = track['track']

        if 'storeId' in track:
            return track, track['storeId']
        elif 'trackId' in track:
            return self.library[track['trackId']], track['trackId']
        else:
            return None, None

    def get_artist_album_list(self, artist_name):
        search = self._search("artist", artist_name)
        if len(search) == 0:
            return "Unable to find the artist you requested."

        artist_info = self._api.get_artist_info(search[0]['artistId'],
                                                include_albums=True)
        album_list_text = "Here's the album listing for %s: " % artist_name

        counter = 0
        for index, val in enumerate(artist_info['albums']):
            if counter > 25:  # alexa will time out after 10 seconds if the list takes too long to iterate through
                break
            album_info = self._api.get_album_info(
                album_id=artist_info['albums'][index]['albumId'],
                include_tracks=True)
            if len(album_info['tracks']) > 5:
                counter += 1
                album_list_text += (
                    artist_info['albums'][index]['name']) + ", "
        return album_list_text

    def get_latest_artist_albums(self, artist_name):
        search = self._search("artist", artist_name)

        if len(search) == 0:
            return False

        artist_info = self._api.get_artist_info(search[0]['artistId'],
                                                include_albums=True)
        album_list = artist_info['albums']

        sorted_list = sorted(album_list.__iter__(),
                             key=lambda s: s['year'],
                             reverse=True)

        speech_text = 'The latest albums by %s are ' % artist_name

        counter = 0
        for index, val in enumerate(sorted_list):
            if counter > 5:
                break
            else:
                album_info = self._api.get_album_info(
                    album_id=sorted_list[index]['albumId'],
                    include_tracks=True)
                if len(album_info['tracks']) >= 5:
                    counter += 1
                    album_name = sorted_list[index]['name']
                    album_year = sorted_list[index]['year']
                    speech_text += '%s, released in %d, ' % (album_name,
                                                             album_year)

        return speech_text

    def closest_match(self,
                      request_name,
                      all_matches,
                      artist_name='',
                      minimum_score=70):
        # Give each match a score based on its similarity to the requested
        # name
        self.logger.debug("The artist name is " + str(artist_name))
        request_name = request_name.lower() + artist_name.lower()
        scored_matches = []
        for i, match in enumerate(all_matches):
            try:
                name = match['name'].lower()
            except (KeyError, TypeError):
                i = match
                name = all_matches[match]['title'].lower()
                if artist_name != "":
                    name += all_matches[match]['artist'].lower()

            scored_matches.append({
                'index': i,
                'name': name,
                'score': fuzz.ratio(name, request_name)
            })

        sorted_matches = sorted(scored_matches,
                                key=lambda a: a['score'],
                                reverse=True)
        top_scoring = sorted_matches[0]
        self.logger.debug("The top scoring match was: " + str(top_scoring))
        best_match = all_matches[top_scoring['index']]

        # Make sure we have a decent match (the score is n where 0 <= n <= 100)
        if top_scoring['score'] < minimum_score:
            return None

        return best_match

    def get_genres(self, parent_genre_id=None):
        return self._api.get_genres(parent_genre_id)

    def increment_song_playcount(self, song_id, plays=1, playtime=None):
        return self._api.increment_song_playcount(song_id, plays, playtime)

    def get_song_data(self, song_id):
        return self._api.get_track_info(song_id)

    @classmethod
    def generate_api(cls, **kwargs):
        return cls(environ['GOOGLE_EMAIL'], environ['GOOGLE_PASSWORD'],
                   **kwargs)
Example #34
0
class GMusicHandler:
    """
    GMusicHandler is the class handling the communication with the google music api.
    """
    def __init__(self, user, password):
        self.user = user
        self.password = password

        self.api = Mobileclient()

        if not self.api.oauth_login(Mobileclient.FROM_MAC_ADDRESS):
            raise Exception('Failed to login...')

        self.tracks = {}
        self.playlists = {}

    def get_all_song(self):
        if len(self.tracks) == 0:
            songs = self.api.get_all_songs()
            for song in songs:
                track_id = song['id']
                title = song['title']
                artist = song['artist']
                album = song['album']
                track_number = song['trackNumber']

                self.tracks[track_id] = Track(track_id, title, artist, album,
                                              track_number)
        return self.tracks

    def get_song(self, track_id):
        songs = self.get_all_song()
        return songs.get(track_id)

    def get_all_playlist(self):
        if len(self.playlists) == 0:
            playlists = self.api.get_all_user_playlist_contents()
            for pl in playlists:
                playlist = self._build_playlist(pl)
                self.playlists[playlist.id] = playlist
        return self.playlists

    def _build_playlist(self, data):
        playlist_id = data['id']
        playlist_name = data['name']
        p = Playlist(playlist_id, playlist_name)
        for track in data['tracks']:
            track_id = track['trackId']
            source = track['source']
            if source == '1':
                song = self.get_song(track_id)
                p.tracks[song.id] = song
            elif source == '2':
                song = self._create_track(track_id, track['track'])
                p.tracks[song.id] = song

        return p

    def _create_track(self, track_id, data):
        title = data['title']
        artist = data['artist']
        album = data['album']
        track_number = data['trackNumber']
        song = Track(track_id, title, artist, album, track_number)
        self.tracks[song.id] = song
        return song

    def get_playlist(self, playlist_name):
        playlists = self.get_all_playlist()
        return next(
            iter([p for p in playlists.values() if p.name == playlist_name]),
            None)

    def download_track(self, track_id):
        url = self.api.get_stream_url(track_id)
        file_path, headers = urllib.request.urlretrieve(url)
        return file_path

    def search(self, query):
        return self.api.search(query)
Example #35
0
class GMusicSession(object):
    def __init__(self):
        super(GMusicSession, self).__init__()
        logger.info('Mopidy uses Google Music')
        self.api = Mobileclient()

    def login(self, username, password, deviceid):
        if self.api.is_authenticated():
            self.api.logout()
        try:
            self.api.login(username, password)
        except CallFailure as error:
            logger.error(u'Failed to login as "%s": %s', username, error)
        if self.api.is_authenticated():
            if deviceid is None:
                self.deviceid = self.get_deviceid(username, password)
            else:
                self.deviceid = deviceid
        else:
            return False

    def logout(self):
        if self.api.is_authenticated():
            return self.api.logout()
        else:
            return True

    def get_all_songs(self):
        if self.api.is_authenticated():
            return self.api.get_all_songs()
        else:
            return {}

    def get_stream_url(self, song_id):
        if self.api.is_authenticated():
            try:
                return self.api.get_stream_url(song_id, self.deviceid)
            except CallFailure as error:
                logger.error(u'Failed to lookup "%s": %s', song_id, error)

    def get_all_user_playlist_contents(self):
        if self.api.is_authenticated():
            return self.api.get_all_user_playlist_contents()
        else:
            return {}

    def get_shared_playlist_contents(self, shareToken):
        if self.api.is_authenticated():
            return self.api.get_shared_playlist_contents(shareToken)
        else:
            return {}

    def get_all_playlists(self):
        if self.api.is_authenticated():
            return self.api.get_all_playlists()
        else:
            return {}

    def get_deviceid(self, username, password):
        logger.warning(u'No mobile device ID configured. '
                       u'Trying to detect one.')
        webapi = Webclient(validate=False)
        webapi.login(username, password)
        devices = webapi.get_registered_devices()
        deviceid = None
        for device in devices:
            if device['type'] == 'PHONE' and device['id'][0:2] == u'0x':
                # Omit the '0x' prefix
                deviceid = device['id'][2:]
                break
        webapi.logout()
        if deviceid is None:
            logger.error(u'No valid mobile device ID found. '
                         u'Playing songs will not work.')
        else:
            logger.info(u'Using mobile device ID %s', deviceid)
        return deviceid

    def get_track_info(self, store_track_id):
        if self.api.is_authenticated():
            try:
                return self.api.get_track_info(store_track_id)
            except CallFailure as error:
                logger.error(u'Failed to get All Access track info: %s', error)

    def get_album_info(self, albumid, include_tracks=True):
        if self.api.is_authenticated():
            try:
                return self.api.get_album_info(albumid, include_tracks)
            except CallFailure as error:
                logger.error(u'Failed to get All Access album info: %s', error)
Example #36
0
import sys
from gmusicapi import Mobileclient

if __name__ == "__main__":
    if sys.argv[1] == "1":
        mc = Mobileclient()
        success = mc.login(sys.argv[3], sys.argv[4])
        if success == True:
            sresults = mc.search_all_access(sys.argv[2], 1)  #2 = query
            song = sresults['song_hits'][0]
            sid = song['track']['nid']
            sname = song['track']['title']
            sartist = song['track']['artist']
            sartistid = song['track']['artistId'][0]
            salbum = song['track']['album']
            salbumart = song['track']['albumArtRef'][0]['url']
            aresults = mc.get_artist_info(sartistid, False, 1, 1)
            artistart = aresults['artistArtRef']
            print(sid)
            print(sname)
            print(sartist)
            print(salbum)
            print(salbumart)
            print(artistart)
    if sys.argv[1] == "2":
        print("Spotify is not yet supported.")
Example #37
0
RATING_NO_RATING = '0'
RATING_THUMBS_DOWN = '1'
RATING_THUMBS_UP = '5'
# API DOCS
# http://unofficial-google-music-api.readthedocs.io/en/latest/reference/mobileclient.html
# source code
# https://github.com/simon-weber/gmusicapi/blob/develop/gmusicapi/clients/mobileclient.py


def loadConfig(file="config.ini"):
    config = configparser.ConfigParser()
    config.read(file)
    return config


api = Mobileclient()
config = loadConfig()

logged_in = api.login(config['Credentials']["username"],
                      config['Credentials']["password"], 'f8:a9:d0:0c:9d:82')
songs_list = api.get_all_songs()

songs_to_delete = []
# following is just for debugging
# wanted_keys = ['artist', 'title', 'id', 'rating']

for song in songs_list:
    if song['rating'] == RATING_THUMBS_DOWN:
        songs_to_delete.append(song)
        # songs_to_delete.append({k: song[k] for k in wanted_keys})
Example #38
0
def allaccessimport(playlist=None,
                    username=None,
                    password=None,
                    dry_run=False):
    """
    Exports a Spotify playlist to stdout or csv.
    """

    if not username or not password:
        raise CommandError(
            "Username and password must be provided as either command-line " +
            "argument or in the application configuration file.")

    playlist_name = playlist
    playlist_description = ""
    if playlist:
        playlist_name = os.path.basename(playlist_name)
        playlist_name = os.path.splitext(playlist_name)[0]
    logging.debug("Playlist name will be: {}".format(playlist_name))

    api = Mobileclient(False, False)
    logged_in = api.login(username, password, Mobileclient.FROM_MAC_ADDRESS)
    if not logged_in:
        raise CommandError(
            'Error. Unable to login to Google Music All Access.')

    playlist_ref = None
    currenttracks = None

    failed_tracks = list()
    songs_added = 0
    total = 0

    stream = open(playlist, "rb") if playlist else sys.stdin

    for input_line in stream:
        input_line = input_line.strip()

        # Lazily search the beginning of the file for a Playlist name
        if input_line.startswith("#"):
            data = input_line[1:]
            parts = [x.strip() for x in data.split(":", 1)]

            if len(parts) == 2:
                if parts[0] == "Playlist":
                    playlist_name = parts[1]
                elif parts[0] == "Description":
                    playlist_description = parts[1]

            continue

        if not playlist_ref:
            if not playlist_name:
                raise CommandError(
                    "A playlist name was not given and it was not found " +
                    "in the file either. Can't continue.")
            else:
                playlist_ref, currenttracks = get_playlist(api, playlist_name)
                if not playlist_ref and not dry_run:
                    sys.stderr.write('Playlist not found. Creating new.\n')
                    playlist_ref = api.create_playlist(
                        playlist_name, description=playlist_description)
                yield 'Going to update playlist {0} ({1})\n'.format(
                    playlist_name, playlist_ref)

        trackinfo = list(csv.reader([input_line], quoting=csv.QUOTE_ALL))[0]

        if trackinfo[0] == 'Track' and trackinfo[1] == 'Artist':
            yield 'Skipping header.'
            continue

        search_term = "{0} {1}".format(trackinfo[0], trackinfo[1])
        total = total + 1
        newtrackid, error_reason = search_track(api, search_term,
                                                currenttracks)
        if newtrackid:
            if not dry_run:
                #print("Add to {} song {}".format(playlist_ref, newtrackid))
                api.add_songs_to_playlist(playlist_ref, [newtrackid])
            songs_added = songs_added + 1
        else:
            failed_tracks.append(trackinfo)
        sys.stderr.write("Searching {}...{}\n".format(search_term,
                                                      error_reason))

    yield "{0} songs added out of {1}. {2} Failed.".format(
        songs_added, total, total - songs_added)

    yield "Failed tracks:"
    for line in failed_tracks:
        print "  ", line
Example #39
0
        self.album = album
        self.title = []  # list of titles of this album
        self.artist = []  # could be a sampler with...
        self.genre = []  # ...different artists and genres
        self.ID = []  # id is needed to remove a song

    def add(self, artist, genre, title, ID):  # add a song to the album
        self.artist.append(artist)
        self.genre.append(genre)
        self.title.append(title)
        self.ID.append(ID)


all_albums = {}  # dict of albums, indexed by album name
n = 0  # counts the songs
api = Mobileclient()  # Mobileclient is the simple gmusicapi interface

if api.login(USER, PASS, Mobileclient.FROM_MAC_ADDRESS):
    songs = api.get_all_songs()
    for i in songs:  # iterate across the songs
        if i['album'] == '':  # no album title, artist, song title? invent one
            i['album'] = 'ALBUM-' + str(n)
        if i['artist'] == '':
            i['artist'] = 'ARTIST-' + str(n)
        if i['title'] == '':
            i['title'] = 'TITLE-' + str(n)
        try:  # try to add song to existing album
            all_albums[i['album']].add(i['artist'], i['genre'], i['title'],
                                       i['id'])
#    	print('>>> added', i['title'], 'to album', i['album'])
        except:  # no album exists -> create it, then add song
class MusicPlayer:
    def __init__(self, device_id, token):
        # Gmusic API initialization
        print("initializing client")
        self.api = Mobileclient()
        print("logging in")
        self.api.oauth_login(device_id, token)
        print("loading all songs")
        self.all_songs = self.api.get_all_songs()
        print("loading playlists")
        self.all_playlists = self.api.get_all_user_playlist_contents()
        self.all_playlist_names = {}
        for playlist in self.all_playlists:
            self.all_playlist_names[playlist["name"]] = playlist["id"]

        # VLC initialization
        self.track_file = vlc.MediaPlayer()
        self.track_list = []
        self.titles = []
        self.track_number = 0
        self.playlists = []
        self.current_time = -1
        self.max_time = -1

        # Get playlists, songs from the first playlist, and load the first song
        self.get_playlists()
        self.get_songs_from_playlist(self.playlists[0])
        self.song = self.track_list[self.track_number]["trackId"]
        self.load_track()

        # GUI initialization
        print("creating window")
        self.song = ""
        self.player_layout = [
            [sg.Text("I love you Mom!", size=(15, 1), font=("Helvetica", 25))],
            [sg.Listbox(values=self.playlists, size=(30, 20), bind_return_key=True, key="_playlists_"),
             # sg.Image(),
             sg.Listbox(values=self.titles, size=(30, 20), bind_return_key=True, key="_Tracks_")],
            [sg.Text("Click Play or select song", key="_SongName_", enable_events=True)],
            [sg.Text("Volume:"), sg.Slider(range=(0, 100), orientation="h", size=(20, 15),
                                           default_value=self.track_file.audio_get_volume(), key="_volume_"),
             sg.Button("Play"), sg.Button("Pause"), sg.Button("Next")]
        ]

        self.title = "Music Player"
        self.window = sg.Window(self.title).Layout(self.player_layout)

    def get_playlists(self):
        data = self.api.get_all_playlists()
        self.playlists = []
        for playlist in data:
            if not playlist['deleted']:
                self.playlists.append(playlist['name'])
        print(self.playlists)

    def change_playlists(self, name):
        for pos, title in enumerate(self.playlists):
            if title == name:
                self.get_songs_from_playlist(self.playlists[pos])

    def get_songs_from_playlist(self, name):
        print("Obtaining track list")
        tracks = []
        if name in self.all_playlist_names:
            for playlist in self.all_playlists:
                if playlist["name"] == name:
                    for track in playlist["tracks"]:
                        tracks.append(track)
                    break
        self.track_list = tracks
        self.get_playlist_song_titles()

    def get_playlist_song_titles(self):
        print("Getting playlist song titles")
        titles = []
        for song in self.track_list:
            if song["source"] == "2":
                titles.append(song["track"]["title"])
            else:
                for track in self.all_songs:
                    if track["id"] == song["trackId"]:
                        print("match found")
                        titles.append(track["title"])
                else:
                    print("No match found")
        print(titles)
        self.titles = titles

    def get_song_position_from_title(self, title):
        for pos, name in enumerate(self.titles):
            if name == title:
                return pos
        else:
            print("Couldn't find song in tracks")

    def download_song(self):
        print("downloading song")
        url = self.api.get_stream_url(self.song)
        doc = requests.get(url)
        with open("song.mp3", "wb") as f:
            f.write(doc.content)

    def load_track(self):
        self.track_file = vlc.MediaPlayer("song.mp3")
        print("Time:", self.track_file.get_length())

    def play(self):
        self.track_file.play()
        self.window.FindElement("_SongName_").Update(value=self.titles[self.track_number])

    def stop(self):
        self.track_file.stop()

    def pause(self):
        self.track_file.pause()

    def next(self):
        self.track_number += 1
        self.song = self.track_list[self.track_number]["trackId"]
        self.window.FindElement("_Tracks_").SetValue(self.titles[self.track_number])
        self.download_song()
        self.track_file.stop()
        self.load_track()
        self.track_file.play()
        self.max_time = self.track_file.get_time()

    def run(self):
        print("launching program")
        while True:
            self.current_time = self.track_file.get_time()
            if self.max_time == -1:
                self.max_time = self.track_file.get_length()
            elif self.max_time == 0:
                self.max_time = -1
            else:
                current = timedelta(milliseconds=self.current_time)
                max = timedelta(milliseconds=self.max_time)
                # print("Current", current, "Max", max)
                # print(int((self.current_time / self.max_time) * 100))

                if (self.current_time + 500) > self.max_time:
                    self.next()

            event, values = self.window.Read(timeout=100)
            if event is not None:
                if event == "Play":
                    self.play()
                elif event == "Stop":
                    self.stop()
                elif event == "Pause":
                    self.pause()
                elif event == "Next":
                    self.next()
                elif event == "_Tracks_":
                    self.track_number = self.get_song_position_from_title(values[event][0])
                    self.song = self.track_list[self.track_number]["trackId"]
                    self.download_song()
                    self.track_file.stop()
                    self.load_track()
                    self.play()
                elif event == "_playlists_":
                    print(values[event][0])
                    self.change_playlists(values[event][0])
                    self.window.FindElement("_Tracks_").Update(self.titles)
                elif event == "_volume_":
                    print("Volume", event, values)
                else:
                    self.track_file.audio_set_volume(values["_volume_"])
            if event == "Quit" or values is None:
                break
Example #41
0
 def __init__(self):
     self._gclient = Mobileclient()
     self._credentials = self._get_credentials()
Example #42
0
def authenticate(username, password):
    api = Mobileclient()
    api.login(username, password, Mobileclient.FROM_MAC_ADDRESS)
    return api
from gmusicapi import Mobileclient
from os import path

credentials_filename = 'mobilecredentials.cred'
gpm_mobileclient = Mobileclient()

oauth_creds = credentials_filename if path.exists(credentials_filename) else \
              gpm_mobileclient.perform_oauth('./mobilecredentials.cred',
                                             open_browser=True)

gpm_mobileclient.oauth_login('3b98457227009a89', oauth_credentials=oauth_creds)
Example #44
0
g_playlist_name = input('New playlist name (empty to keep name): ')
s_playlist_url = input('Spotify playlist URL: ')

# get spotify url params
spotify_user_id = 0
spotify_playlist_id = ''

path_data = s_playlist_url.split('/')
for path_piece in range(len(path_data)):
    if path_data[path_piece] == 'user':
        spotify_user_id = path_data[path_piece + 1]
    if path_data[path_piece] == 'playlist':
        spotify_playlist_id = path_data[path_piece + 1]

# authenticate
gapi = Mobileclient()
logged_in = gapi.login(g_username, g_password, Mobileclient.FROM_MAC_ADDRESS)
client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(
    client_id=SPOTIFY_CLIENT_ID, client_secret=SPOTIFY_CLIENT_SECRET)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

# get playlist
playlist = sp.user_playlist(spotify_user_id, spotify_playlist_id)
track_response = playlist['tracks']
gplaylist = []

for song in track_response['items']:
    song_search_string = "%s - %s - %s" % (song['track']['artists'][0]['name'],
                                           song['track']['name'],
                                           song['track']['album']['name'])
    song_result = gapi.search(song_search_string)
Example #45
0
import os
from flask import Flask
from flask_ask import Ask, statement
from gmusicapi import Mobileclient

app = Flask(__name__)
email = os.environ.get('email', 17995)
password = os.environ.get('password', 17995)
android_id = os.environ.get('android_id', 17995)

ask = Ask(app, '/alexa')

client = Mobileclient()

print('Logging in as:', email, 'with ANDROID_ID', android_id)

if client.login(email, password, android_id):
    print('Login successful!')
else:
    raise Exception('Login failed')

from . import utils
musicman = utils.musicmanager.MusicManager(client)
music_queue = utils.queue.MusicQueue()

from . import intents
from gmusicapi import Mobileclient
from config import *

# API
api = Mobileclient()
logged_in = api.login(gpm_username, gpm_password, '3a6a9d34f7e8237e')

# Data
artist_names = []

for song in api.get_all_songs():
    artist = song['artist']
    if not(any(artist[:5].lower() in n.lower() for n in artist_names)):
        artist_names.append(artist)

artist_names.sort()

file = open("artist.txt","w")
for artist in artist_names:
    print(artist)
    file.write(artist + "\n")
file.close()
Example #47
0
 def __init__(self):
     super(GMusicSession, self).__init__()
     logger.info('Mopidy uses Google Music')
     self.api = Mobileclient()
Example #48
0
                                       scope,
                                       client_id='YOUR CLIENT ID',
                                       client_secret='YOUR CLIENT SECRET',
                                       redirect_uri='YOUR REDIRECT URI')

    if token:
        sp = spotipy.Spotify(auth=token)  # start and authorize spotipy
        tracks = get_playlist_tracks(
            username, playlist)  # get track, artist, and album names
    else:
        print "Can't get token for", username

    # ********************
    # Update GPM playlist:
    # ********************
    gpm = Mobileclient()
    gpm_username = '******'
    gpm_password = '******'
    logged_in = gpm.login(
        gpm_username, gpm_password,
        Mobileclient.FROM_MAC_ADDRESS)  # is true if log in successful

    if logged_in:
        gpm_song_ids, skipped_songs = get_song_ids(tracks)
        gpm_playlist_id = 'YOUR GPM PLAYLIST ID'  #gpm.create_playlist('Export to GPM Test', description='Test playlist', public=False)
        for i in range(len(gpm_song_ids)):
            gpm.add_songs_to_playlist(gpm_playlist_id, gpm_song_ids[i])

        outputf.write('Number of tracks not found: %s' % skipped_songs)
        write_list_to_file(skipped_songs)
    else:
Example #49
0
    def _delete_duplicates(self, api: Mobileclient) -> None:
        """Delete duplicates."""

        self._combine_play_counts(api)
        discard_ids = [song["id"] for song in self.get_discard_songs()]
        api.delete_songs(discard_ids)
Example #50
0
class MusicLibrary(object):
    """This class reads information about your Google Play Music library"""
    def __init__(self,
                 username=None,
                 password=None,
                 true_file_size=False,
                 scan=True,
                 verbose=0):
        self.verbose = False
        if verbose > 1:
            self.verbose = True

        self.__login_and_setup(username, password)

        self.__artists = {}  # 'artist name' -> {'album name' : Album(), ...}
        self.__albums = []  # [Album(), ...]
        self.__tracks = {}
        self.__playlists = {}
        if scan:
            self.rescan()
        self.true_file_size = true_file_size

    def rescan(self):
        """Scan the Google Play Music library"""
        self.__artists = {}  # 'artist name' -> {'album name' : Album(), ...}
        self.__albums = []  # [Album(), ...]
        self.__tracks = {}
        self.__playlists = {}
        self.__aggregate_albums()

    def __login_and_setup(self, username=None, password=None):
        # If credentials are not specified, get them from $HOME/.gmusicfs
        if not username or not password:
            cred_path = os.path.join(os.path.expanduser('~'), '.gmusicfs')
            if not os.path.isfile(cred_path):
                raise NoCredentialException(
                    'No username/password was specified. No config file could '
                    'be found either. Try creating %s and specifying your '
                    'username/password there. Make sure to chmod 600.' %
                    cred_path)
            if not oct(
                    os.stat(cred_path)[os.path.stat.ST_MODE]).endswith('00'):
                raise NoCredentialException(
                    'Config file is not protected. Please run: '
                    'chmod 600 %s' % cred_path)
            self.config = ConfigParser.ConfigParser()
            self.config.read(cred_path)
            username = self.config.get('credentials', 'username')
            password = self.config.get('credentials', 'password')
            global deviceId
            deviceId = self.config.get('credentials', 'deviceId')
            if not username or not password:
                raise NoCredentialException(
                    'No username/password could be read from config file'
                    ': %s' % cred_path)
            if not deviceId:
                raise NoCredentialException(
                    'No deviceId could be read from config file'
                    ': %s' % cred_path)
            if deviceId.startswith("0x"):
                deviceId = deviceId[2:]

        self.api = GoogleMusicAPI(debug_logging=self.verbose)
        log.info('Logging in...')
        self.api.login(username, password, deviceId)
        log.info('Login successful.')

    def __aggregate_albums(self):
        """Get all the tracks and playlists in the library, parse into relevant dicts"""
        log.info('Gathering track information...')
        tracks = self.api.get_all_songs()
        for track in tracks:
            log.debug('track = %s' % pp.pformat(track))

            # Prefer the album artist over the track artist if there is one
            artist_name = formatNames(track['albumArtist'])
            if artist_name.strip() == '':
                artist_name = formatNames(track['artist'])
            if artist_name.strip() == '':
                artist_name = 'Unknown'

            # Get the Artist object, or create one if it doesn't exist
            artist = self.__artists.get(artist_name.lower(), None)
            if not artist:
                artist = Artist(self, artist_name)
                self.__artists[artist_name.lower()] = artist

            # Get the Album object, or create one if it doesn't exist
            album = artist.get_album(formatNames(track['album']))
            if not album:
                album = Album(self, track['album'])
                self.__albums.append(
                    album)  # NOTE: Current no purpose other than to count
                artist.add_album(album)

            # Add track to album
            album.add_track(track)

            # Add track to list of all tracks, indexable by track ID
            if 'id' in track:
                self.__tracks[track['id']] = track

        log.debug('%d tracks loaded.' % len(tracks))
        log.debug('%d artists loaded.' % len(self.__artists))
        log.debug('%d albums loaded.' % len(self.__albums))

        # Add all playlists
        playlists = self.api.get_all_user_playlist_contents()
        for pldata in playlists:
            playlist = Playlist(self, pldata)
            self.__playlists[playlist.dirname.lower()] = playlist
        log.debug('%d playlists loaded.' % len(self.__playlists))

    def get_artists(self):
        """Return list of all artists in the library"""
        return self.__artists.values()

    def get_artist(self, name):
        """Return the artist from the library with the specified name"""
        return self.__artists.get(name.lower(), None)

    def get_playlists(self):
        """Return list of all playlists in the library"""
        return self.__playlists.values()

    def get_playlist(self, name):
        """Return the playlist from the library with the specified name"""
        return self.__playlists.get(name.lower(), None)

    def get_track(self, trackid):
        """Return the track from the library with the specified track ID"""
        return self.__tracks.get(trackid, None)

    def cleanup(self):
        pass
Example #51
0
class Session(object):
    def __init__(self):
        self.api = None
        self.user = None
        self.lib_albums = {}
        self.lib_artists = {}
        self.lib_tracks = {}
        self.lib_playlists = {}
        self.lib_updatetime = 0
        self.sitdata = []
        self.sitbyid = {}
        self.sitdataupdtime = 0
        
    def dmpdata(self, who, data):
        uplog("%s: %s" % (who, json.dumps(data, indent=4)))

    # Look for an Android device id in the registered devices.
    def find_device_id(self, data):
        for entry in data:
            if "type" in entry and entry["type"] == u"ANDROID":
                # Get rid of 0x
                id = entry["id"][2:]
                uplog("Using deviceid %s" % id)
                return id
        return None
    
    def login(self, username, password, deviceid=None):
        self.api = Mobileclient(debug_logging=False)

        if deviceid is None:
            logged_in = self.api.login(username, password,
                                       Mobileclient.FROM_MAC_ADDRESS)
            if logged_in:
                # Try to re-login with a valid deviceid
                data = self.api.get_registered_devices()
                #self.dmpdata("registered devices", data)
                deviceid = self.find_device_id(data)
                if deviceid:
                    logged_in = self.login(username, password, deviceid)
        else:
            logged_in = self.api.login(username, password, deviceid)

        isauth = self.api.is_authenticated()
        #uplog("login: Logged in: %s. Auth ok: %s" % (logged_in, isauth))
        return logged_in

    def _get_user_library(self):
        now = time.time()
        if now - self.lib_updatetime < 300:
            return
        if self.lib_updatetime == 0:
            data = self.api.get_all_songs()
            #self.dmpdata("all_songs", data)
        else:
            data = self.api.get_all_songs(updated_after=datetime.datetime.fromtimestamp(self.lib_updatetime))
            #self.dmpdata("all_songs_since_update", data)
        self.lib_updatetime = now
        tracks = [_parse_track(t) for t in data]
        self.lib_tracks.update(dict([(t.id, t) for t in tracks]))
        for track in tracks:
            # We would like to use the album id here, but gmusic
            # associates the tracks with any compilations after
            # uploading (does not use the metadata apparently), so
            # that we can't (we would end up with multiple
            # albums). OTOH, the album name is correct (so seems to
            # come from the metadata). What we should do is test the
            # album ids for one album with a matching title, but we're
            # not sure to succeed. So at this point, the album id we
            # end up storing could be for a different albums, and we
            # should have a special library-local get_album_tracks
            self.lib_albums[track.album.name] = track.album
            self.lib_artists[track.artist.id] = track.artist
            
    def get_user_albums(self):
        self._get_user_library()
        return self.lib_albums.values()

    def get_user_artists(self):
        self._get_user_library()
        return self.lib_artists.values()

    def get_user_playlists(self):
        pldata = self.api.get_all_playlists()
        #self.dmpdata("playlists", pldata)
        return [_parse_playlist(pl) for pl in pldata]

    def get_user_playlist_tracks(self, playlist_id):
        self._get_user_library()
        # Unfortunately gmusic does not offer incremental updates for
        # playlists.  This means we must download all playlist data any
        # time we want an update.  Playlists include track information
        # for gmusic songs, so if a user has a lot of playlists this
        # can take some time.
        # For now, we only load the playlists one time for performance purposes
        if len(self.lib_playlists) == 0:
            data = self.api.get_all_user_playlist_contents()
            self.lib_playlists = dict([(pl['id'], pl) for pl in data])
        tracks = []
        if playlist_id in self.lib_playlists:
            for entry in self.lib_playlists[playlist_id]['tracks']:
                if entry['deleted']:
                    continue
                if entry['source'] == u'1':
                    tracks.append(self.lib_tracks[entry['trackId']])
                elif 'track' in entry:
                    tracks.append(_parse_track(entry['track']) )
        return tracks

    def create_station_for_genre(self, genre_id):
        id = self.api.create_station("station"+genre_id, genre_id=genre_id)
        return id

    def get_user_stations(self):
        data = self.api.get_all_stations()
        # parse_playlist works fine for stations
        stations = [_parse_playlist(d) for d in data]
        return stations

    def delete_user_station(self, id):
        self.api.delete_stations(id)

    # not working right now
    def listen_now(self):
        print("api.get_listen_now_items()", file=sys.stderr)
        ret = {'albums' : [], 'stations' : []}
        try:
            data = self.api.get_listen_now_items()
        except Exception as err:
            print("api.get_listen_now_items failed: %s" % err, file=sys.stderr)
            data = None

        # listen_now entries are not like normal albums or stations,
        # and need special parsing. I could not make obvious sense of
        # the station-like listen_now entries, so left them aside for
        # now. Maybe should use create_station on the artist id?
        if data:
            ret['albums'] = [_parse_ln_album(a['album']) \
                             for a in data if 'album' in a]
            #ret['stations'] = [_parse_ln_station(d['radio_station']) \
            #                   for d in data if 'radio_station' in d]
        else:
            print("listen_now: no items returned !", file=sys.stderr)
        print("get_listen_now_items: returning %d albums and %d stations" %\
              (len(ret['albums']), len(ret['stations'])), file=sys.stderr)
        return ret

    def get_situation_content(self, id = None):
        ret = {'situations' : [], 'stations' : []}
        now = time.time()
        if id is None and now - self.sitdataupdtime > 300:
            self.sitbyid = {}
            self.sitdata = self.api.get_listen_now_situations()
            self.sitdataupdtime = now

        # Root is special, it's a list of situations
        if id is None:
            ret['situations'] = [self._parse_situation(s) \
                                 for s in self.sitdata]
            return ret
        
        # not root
        if id not in self.sitbyid:
            print("get_situation_content: %s unknown" % id, file=sys.stderr)
            return ret

        situation = self.sitbyid[id]
        #self.dmpdata("situation", situation)
        if 'situations' in situation:
            ret['situations'] = [self._parse_situation(s) \
                                 for s in situation['situations']]
        if 'stations' in situation:
            ret['stations'] = [_parse_situation_station(s) \
                               for s in situation['stations']]

        return ret

    def _parse_situation(self, data):
        self.sitbyid[data['id']] = data
        return Playlist(id=data['id'], name=data['title'])
        
    def create_curated_and_get_tracks(self, id):
        sid = self.api.create_station("station"+id, curated_station_id=id)
        print("create_curated: sid %s"%sid, file=sys.stderr)
        tracks = [_parse_track(t) for t in self.api.get_station_tracks(sid)]
        #print("curated tracks: %s"%tracks, file=sys.stderr)
        self.api.delete_stations(sid)
        return tracks
    
    def get_station_tracks(self, id):
        return [_parse_track(t) for t in self.api.get_station_tracks(id)]
    
    def get_media_url(self, song_id, quality=u'med'):
        url = self.api.get_stream_url(song_id, quality=quality)
        print("get_media_url got: %s" % url, file=sys.stderr)
        return url

    def get_album_tracks(self, album_id):
        data = self.api.get_album_info(album_id, include_tracks=True)
        album = _parse_album(data)
        return [_parse_track(t, album) for t in data['tracks']]

    def get_promoted_tracks(self):
        data = self.api.get_promoted_songs()
        #self.dmpdata("promoted_tracks", data)
        return [_parse_track(t) for t in data]

    def get_genres(self, parent=None):
        data = self.api.get_genres(parent_genre_id=parent)
        return [_parse_genre(g) for g in data]
                
    def get_artist_info(self, artist_id, doRelated=False):
        ret = {"albums" : [], "toptracks" : [], "related" : []} 
        # Happens,some library tracks have no artistId entry
        if artist_id is None or artist_id == 'None':
            uplog("get_artist_albums: artist_id is None")
            return ret
        else:
            uplog("get_artist_albums: artist_id %s" % artist_id)

        maxrel = 20 if doRelated else 0
        maxtop = 0 if doRelated else 10
        incalbs = False if doRelated else True
        data = self.api.get_artist_info(artist_id, include_albums=incalbs,
                                        max_top_tracks=maxtop,
                                        max_rel_artist=maxrel)
        #self.dmpdata("artist_info", data)
        if 'albums' in data:
            ret["albums"] = [_parse_album(alb) for alb in data['albums']]
        if 'topTracks' in data:
            ret["toptracks"] = [_parse_track(t) for t in data['topTracks']]
        if 'related_artists' in data:
            ret["related"] = [_parse_artist(a) for a in data['related_artists']]
        return ret

    def get_artist_related(self, artist_id):
        data = self.get_artist_info(artist_id, doRelated=True)
        return data["related"]
    
    def search(self, query):
        data = self.api.search(query, max_results=50)
        #self.dmpdata("Search", data)

        tr = [_parse_track(i['track']) for i in data['song_hits']]
        ar = [_parse_artist(i['artist']) for i in data['artist_hits']]
        al = [_parse_album(i['album']) for i in data['album_hits']]
        #self.dmpdata("Search playlists", data['playlist_hits'])
        try:
            pl = [_parse_splaylist(i) for i in data['playlist_hits']]
        except:
            pl = []
        return SearchResult(artists=ar, albums=al, playlists=pl, tracks=tr)
Example #52
0
def main(no_oauth, spotify_only):
    if settings.SPOTIPY_CLIENT_ID == "<your-spotify-client-id>":
        click.echo(
            click.style(
                "To use this CLI utility, you must have a client account setup with Spotify.\n"
                "Setup a developer client account at: "
                "https://developer.spotify.com/my-applications\n"
                "Then, specify the client_id and client_secret in 'settings.local.yaml'",
                bold=True,
            )
        )
        return
    # setup for Google Play Music
    if not spotify_only:
        mobile_client = Mobileclient()
        if not no_oauth:
            if not os.path.exists(f"{CWD}/{settings.TOKEN_PATH}"):
                os.makedirs(f"{CWD}/{settings.TOKEN_PATH}")
            mobile_client.perform_oauth(storage_filepath=f"{GPM_TOKEN}")

        # Make sure that login works
        device_id = settings.GOOGLE_DEVICE_ID or get_mac_address().replace(":", "").upper()
        try:
            assert mobile_client.oauth_login(device_id, oauth_credentials=GPM_TOKEN)
        except Exception:
            click.echo(
                click.style(
                    "ERROR: login for Google Play Music hit an exception.", fg="red", bold=True
                )
            )
            raise

        click.echo(click.style("Success logging into Google Play Music!", fg="green", bold=True))
        click.echo(f"Oauth file for GPM stored in: '{GPM_TOKEN}'")

    # setup for Spotify
    try:
        if not no_oauth:
            token = prompt_for_user_token(
                settings.SPOTIPY_CLIENT_USERNAME,
                client_id=settings.SPOTIPY_CLIENT_ID,
                client_secret=settings.SPOTIPY_CLIENT_SECRET,
                redirect_uri=settings.SPOTIPY_REDIRECT_URI,
                cache_path=f"{SPOTIFY_TOKEN}",
                scope=settings.SPOTIPY_SCOPE,
            )
        else:
            token = spotipy.oauth2.SpotifyOAuth(
                username=settings.SPOTIPY_CLIENT_USERNAME,
                client_id=settings.SPOTIPY_CLIENT_ID,
                client_secret=settings.SPOTIPY_CLIENT_SECRET,
                redirect_uri=settings.SPOTIPY_REDIRECT_URI,
                cache_path=f"{SPOTIFY_TOKEN}",
            ).get_access_token()["access_token"]
        # verify that login works
        spotify = spotipy.Spotify(auth=token)
        assert bool(spotify.current_user())
    except Exception:
        click.echo(click.style("ERROR: login for Spotify hit an exception.", fg="red", bold=True))
        raise

    click.echo(click.style(f"Success logging into Spotify!", fg="green", bold=True))
    click.echo(f"Oauth file for Spotify stored in: '{SPOTIFY_TOKEN}'")
Example #53
0
    '--merge',
    dest="merge",
    action='store_true',
    help='Merge playlist if name already exists. Crude implementation.')
parser.add_argument(
    '--rm-feat',
    dest="rmfeat",
    action='store_false',
    help=
    'Remove (feat artistname) from titles for google music. Messes up spotify search, default on.'
)
config = parser.parse_args()

spotify_username = config.spotify_user

google_api = Mobileclient()
google_api.login(config.g_user, config.g_password,
                 Mobileclient.FROM_MAC_ADDRESS)

token = util.prompt_for_user_token(spotify_username,
                                   scope='playlist-modify-public',
                                   client_id=config.spotify_client,
                                   client_secret=config.spotify_secret,
                                   redirect_uri=config.spotify_redirect)
spotify_api = spotipy.Spotify(auth=token)

playlists = google_api.get_all_user_playlist_contents()

output = [
    "[{}]: {}".format(i, name['name']) for i, name in enumerate(playlists)
]
Example #54
0
from gmusicapi import Mobileclient
import gMusicLogin

from tqdm import tqdm
import sys, os, time, requests

from mutagen.easyid3 import EasyID3
from mutagen.mp3 import MP3
import mutagen.id3

EasyID3.RegisterTextKey("albumartist", "TPE2")
EasyID3.RegisterTextKey("media", "TMED")

r_albumID = 'Bmzku73mo3yicub2vnes43wv52y'

api = Mobileclient()
try:
    api.login(gMusicLogin.getUser(), gMusicLogin.getPass(),
              Mobileclient.FROM_MAC_ADDRESS)
except:
    sys.exit("Login Failed")

while api.is_authenticated() == False:
    time.sleep(.1)


def removeNonASCII(text):
    return ''.join(i for i in text if ord(i) < 128)


def runMainBody():
Example #55
0
import sys
from gmusicapi import Mobileclient
from datetime import date
import fileinput

if len(sys.argv) > 1:

    pw = ""
    for line in fileinput.input():
        pw = line

    api = Mobileclient()
    logged_in = api.login('*****@*****.**', pw,
                          Mobileclient.FROM_MAC_ADDRESS)

    if logged_in:

        playlists = api.get_all_playlists()
        names = []

        for playlist in playlists:
            names.append(playlist['name'])

        for name in sorted(names):
            print(name)

    api.logout()

else:
    print(
        "Please include the path to a file containing a Google Music password."
                new_search = re.sub(pat, '', track_title, re.IGNORECASE)
                log_file_arr.append(
                    f'\tNOT FOUND | {artist} | {track_title} | SEARCHING FOR: {new_search}'
                )
                track_title = new_search
            elif iters == 2:
                new_search = track['album_artist']
                log_file_arr.append(
                    f'\tNOT FOUND | {artist} | {track_title} | SEARCHING FOR: {new_search}'
                )
                artist = new_search
            else:
                log_file_arr.append('\n')
                break
    return log_file_arr
    # playlist = spotify_object.user_playlist_create(username, name)
    # spotify_object.user_playlist_add_tracks(user=username, playlist_id=playlist['id'], tracks=spotify_song_ids)


if __name__ == "__main__":

    mc = Mobileclient()
    mc.oauth_login('3b98457227009a89',
                   oauth_credentials='./mobilecredentials.cred')
    playlists = pull_playlists(mc)
    log_file_arr = []
    for playlist in playlists:
        log_file_arr += import_playlist(playlist, username, sp)
    with open('log_file_2.txt', 'w') as f:
        f.write('\n'.join(log_file_arr))
Example #57
0
print "starting..."

from gmusicapi import Mobileclient
import sys
import login_credentials

api = Mobileclient()
api.login(login_credentials.google_email, login_credentials.google_password,
          Mobileclient.FROM_MAC_ADDRESS)

print "url: " + api.get_stream_url('59b55acc-09c2-3048-9463-40cf50d34d16')

print "...stopping"
Example #58
0
class MusicLibrary(object):
    'Read information about your Google Music library'

    def __init__(self,
                 username=None,
                 password=None,
                 true_file_size=False,
                 scan=True,
                 verbose=0):
        self.verbose = False
        if verbose > 1:
            self.verbose = True

        self.__login_and_setup(username, password)

        self.__artists = {}  # 'artist name' -> {'album name' : Album(), ...}
        self.__albums = []  # [Album(), ...]
        if scan:
            self.rescan()
        self.true_file_size = true_file_size

    def rescan(self):
        self.__artists = {}  # 'artist name' -> {'album name' : Album(), ...}
        self.__albums = []  # [Album(), ...]
        self.__aggregate_albums()

    def __login_and_setup(self, username=None, password=None):
        # If credentials are not specified, get them from $HOME/.gmusicfs
        if not username or not password:
            cred_path = os.path.join(os.path.expanduser('~'), '.gmusicfs')
            if not os.path.isfile(cred_path):
                raise NoCredentialException(
                    'No username/password was specified. No config file could '
                    'be found either. Try creating %s and specifying your '
                    'username/password there. Make sure to chmod 600.' %
                    cred_path)
            if not oct(
                    os.stat(cred_path)[os.path.stat.ST_MODE]).endswith('00'):
                raise NoCredentialException(
                    'Config file is not protected. Please run: '
                    'chmod 600 %s' % cred_path)
            self.config = ConfigParser.ConfigParser()
            self.config.read(cred_path)
            username = self.config.get('credentials', 'username')
            password = self.config.get('credentials', 'password')
            global deviceId
            deviceId = self.config.get('credentials', 'deviceId')
            if not username or not password:
                raise NoCredentialException(
                    'No username/password could be read from config file'
                    ': %s' % cred_path)
            if not deviceId:
                raise NoCredentialException(
                    'No deviceId could be read from config file'
                    ': %s' % cred_path)

        self.api = GoogleMusicAPI(debug_logging=self.verbose)
        log.info('Logging in...')
        self.api.login(username, password)
        log.info('Login successful.')

    def __aggregate_albums(self):
        'Get all the tracks in the library, parse into artist and album dicts'
        all_artist_albums = {}  # 'Artist|||Album' -> Album()
        log.info('Gathering track information...')
        tracks = self.api.get_all_songs()
        for track in tracks:
            # Prefer the album artist over the track artist if there is one:
            artist = formatNames(track['albumArtist'].lower())
            if artist.strip() == '':
                artist = formatNames(track['artist'].lower())
            # Get the Album object if it already exists:
            key = '%s|||%s' % (formatNames(artist),
                               formatNames(track['album'].lower()))
            album = all_artist_albums.get(key, None)
            if not album:
                # New Album
                if artist == '':
                    artist = 'unknown'
                album = all_artist_albums[key] = Album(
                    self, formatNames(track['album'].lower()))
                self.__albums.append(album)
                artist_albums = self.__artists.get(artist, None)
                if artist_albums:
                    artist_albums[formatNames(album.normtitle)] = album
                else:
                    self.__artists[artist] = {album.normtitle: album}
                    artist_albums = self.__artists[artist]
            album.add_track(track)
        log.debug('%d tracks loaded.' % len(tracks))
        log.debug('%d artists loaded.' % len(self.__artists))
        log.debug('%d albums loaded.' % len(self.__albums))

    def get_artists(self):
        return self.__artists

    def get_albums(self):
        return self.__albums

    def get_artist_albums(self, artist):
        log.debug(artist)
        return self.__artists[artist]

    def cleanup(self):
        pass
Example #59
0
 def __init__(self):
     self.session = Mobileclient()
     self.device_id = gmusic_device_id
     self.cred_path = gmusic_cred_path
     self.playlist_id = gmusic_playlist_id
Example #60
0
def reverseplaylist(playlist_name='', repeat=False, quick=False):
    mc = Mobileclient()
    mc.__init__()

    # Find location of this script
    dir_path = os.path.dirname(os.path.realpath(__file__))

    # Check whether this is the first time the program has been run by searching the directory for the log file
    file_list = os.listdir(dir_path)

    # No log file means not run
    if '.gmusiclog.txt' not in file_list:
        print(
            '\n' +
            'This is the first time this program has been run in this folder.'
            + '\n' + 'performing initial authentication.' + '\n')

        # Autorepeat cannot be true without logfile, override if true
        repeat = False

        # Start with a bogus device ID to determine real id from error message
        devID = 'ffffffff'
        mc.perform_oauth()
        try:
            mc.oauth_login(devID)
        except Exception as e:
            error = str(e)
            IDpos = error.find('*')
            nextIDpos = error.find('\n', IDpos + 1, len(error))
            devID = error[IDpos + 2:nextIDpos]
            # Perform login
            mc.oauth_login(devID)

        # Write authentication stuff to logfile
        with open(dir_path + '/.gmusiclog.txt', 'w') as log:
            log.write(devID + '\n')
            x = datetime.datetime.now()
            timeString = (str(x.day) + '/' + str(x.month) + '/' + str(x.year) +
                          '  ' + str(x.hour) + ':' + str(x.minute) + ':' +
                          str(x.second) + '.' + str(x.microsecond))
            log.write('Initial authentication performed at ' + timeString +
                      '\n')

    # Log file exists, we will check whether the user has requested autorepeat
    else:
        print(
            '\n' +
            'This is not the first time this program has been run in this folder'
            + '\n' + 'performing login.' + '\n')

        # Open the logfile to read device id and previous playlists
        with open(dir_path + '/.gmusiclog.txt', 'r') as log:
            # Get device ID
            devID = log.readline().strip()
            # Look for the playlist name from the bottom of the list
            contents = log.read()

        # Perform login
        mc.oauth_login(devID)
        playlistLocation = contents.rfind('PLAYLIST')
        if playlistLocation != -1:
            # Define end of playlist to make defining desired playlist a little cleaner
            endOfPlaylist = contents.find('\n', playlistLocation,
                                          len(contents))
            desired_playlist = contents[playlistLocation + 10:endOfPlaylist]

        with open(dir_path + '/.gmusiclog.txt', 'a+') as log:

            # Write authentication stuff to logfile
            x = datetime.datetime.now()
            timeString = (str(x.day) + '/' + str(x.month) + '/' + str(x.year) +
                          '  ' + str(x.hour) + ':' + str(x.minute) + ':' +
                          str(x.second) + '.' + str(x.microsecond))
            log.write('Login performed at ' + timeString + '\n')

    # Get user input for desired playlist if autorepeat is not enabled
    if repeat == False and playlist_name == '':
        desired_playlist = input(
            'Name of the playlist being reversed (case sensetive): ')
    elif playlist_name != '':
        # If a name is given this overrides all else
        desired_playlist = playlist_name
    else:
        print('Autorepeat enabled, reversing playlist: ' + desired_playlist +
              '\n')

    # Establish the name of the reversed playlist
    reversed_playlist = desired_playlist + 'REVERSED'

    # Check to see whether the desired and reversed playlists exist yet
    allPlaylists = mc.get_all_playlists()
    desired_playlist_index = -1
    reversed_playlist_index = -1
    for n in allPlaylists:
        if n['name'] == reversed_playlist:
            reversed_playlist_index = n
            reversedID = n['id']
        elif n['name'] == desired_playlist:
            desired_playlist_index = n
            desiredID = n['id']

    # Desired playlist exists, so we check to see if it has also been reversed
    if desired_playlist_index != -1:
        # We cache the playlist name so that it can be automatically re-reversed next time
        with open(dir_path + '/.gmusiclog.txt', 'a+') as log:
            log.write('PLAYLIST: ' + desired_playlist + '\n')

        # Desired playlist has been reversed, we can either delete the old one before proceeding
        # or perform a quick update
        if reversed_playlist_index != -1:
            print('The ' + desired_playlist + ' playlist has been reversed.')

            # Determine whether to do a quick update or not
            if quick == True:
                print('performing quick update')
                quick_update(mc, desiredID, reversedID)
                return
            else:
                print('Performing full update\n' +
                      'Deleting the old playlist...\n')
                mc.delete_playlist(reversedID)

        # Desired playlist has not been reversed, create the reverse
        else:
            print('The ' + desired_playlist +
                  ' playlist has not been reversed, creating the reverse now.')

        # If we have got this far, the reversed playlist doesn't exist
        print('Generating reversed song list...')
        reversedID, id_list = create_new(mc, desired_playlist)
        print('Adding songs to the playlist...')
        mc.add_songs_to_playlist(reversedID, id_list)
        print('Done!')

    # No such playlist exists
    else:
        print(
            'No playlist by the name of ' + desired_playlist +
            ' found. Did you spell it correctly? A reminder here that the playlist name is case sensetive.'
        )