class GoogleMusicApi():
    def __init__(self):
        self.xbmc = sys.modules["__main__"].xbmc
        self.xbmcgui = sys.modules["__main__"].xbmcgui
        self.xbmcplugin = sys.modules["__main__"].xbmcplugin

        self.settings = sys.modules["__main__"].settings
        self.language = sys.modules["__main__"].language
        self.dbg = sys.modules["__main__"].dbg
        self.common = sys.modules["__main__"].common
        self.storage = sys.modules["__main__"].storage

        self.gmusicapi = Api()
        self.login = GoogleMusicLogin.GoogleMusicLogin(self.gmusicapi)

    def getPlaylistSongs(self, playlist_id, forceRenew=False):
        if not self.storage.isPlaylistFetched(playlist_id) or forceRenew:
            self.updatePlaylistSongs(playlist_id)

        songs = self.storage.getPlaylistSongs(playlist_id)

        return songs

    def getPlaylistsByType(self, playlist_type, forceRenew=False):
        if forceRenew:
            self.updatePlaylists(playlist_type)

        playlists = self.storage.getPlaylistsByType(playlist_type)
        if len(playlists) == 0 and not forceRenew:
            self.updatePlaylists(playlist_type)
            playlists = self.storage.getPlaylistsByType(playlist_type)

        return playlists

    def getSong(self, song_id):
        return self.storage.getSong(song_id)

    def updatePlaylistSongs(self, playlist_id):
        api_songs = []

        self.login.login()
        if playlist_id == 'all_songs':
            api_songs = self.gmusicapi.get_all_songs()
        else:
            api_songs = self.gmusicapi.get_playlist_songs(playlist_id)

        self.storage.storeApiSongs(api_songs, playlist_id)

    def updatePlaylists(self, playlist_type):
        self.login.login()
        playlists = self.gmusicapi.get_all_playlist_ids(playlist_type=="auto", playlist_type=="instant", playlist_type=="user", always_id_lists=True)
        self.storage.storePlaylists(playlists[playlist_type], playlist_type)

    def getSongStreamUrl(self, song_id):
        self.login.login()
        stream_url = self.gmusicapi.get_stream_url(song_id)
        #self.storage.updateSongStreamUrl(song_id, stream_url)

        return stream_url
class AlbumArtist(object):
    def __init__(self, email=None, password=None):
        self.api = Api()
        if not email:
            email = raw_input("Email: ")
        if not password:
            password = getpass()

        self.email = email
        self.password = password

        self.logged_in = self.auth()


    def auth(self):
        self.logged_in = self.api.login(self.email, self.password)
        if not self.logged_in:
            print "Login failed..."
            exit()

        print ""
        print "Logged in as %s" % self.email
        print ""


    def fix_album_artist(self):

        def noAlbumArtist(x): return len(x['albumArtist']) == 0

        def fixSong(song):
            song['albumArtist'] = song['artist']
            return song

        def chunks(l, n):
            """ Yield successive n-sized chunks from l.
            """
            for i in xrange(0, len(l), n):
                yield l[i:i+n]

        songs = filter(noAlbumArtist, self.api.get_all_songs())

        print "Found %d songs that have no albumArtist" % len(songs)

        fixedSongs = map(fixSong, songs)

        fixedSongChunks = chunks(fixedSongs, 100)

        map(self.api.change_song_metadata, fixedSongChunks)

        print "Fixed %d songs" % len(fixedSongs)
Exemple #3
0
def importGmusicApi(email, password, gmusicCollection, keysCollection):
    api = Api()
    api.login(email, password)
    allSongs = api.get_all_songs()
    api.logout()

    gmusicCollection.remove()
    keys = set()
    for song in allSongs:
        gmusicCollection.insert(song)
        for key in song.iterkeys():
            keys.add(key)

    doc = { '_id' : 'gmusic', 'keys' : list(keys) }
    keysCollection.save(doc)
    print 'done importing', len(allSongs), 'gmusic songs into db'
class GoogleMusicApi():
    def __init__(self):
        self.storage = sys.modules["__main__"].storage

        self.gmusicapi = Api(debug_logging=False)
        self.login = GoogleMusicLogin.GoogleMusicLogin(self.gmusicapi)

    def getPlaylistSongs(self, playlist_id, forceRenew=False):

        if playlist_id == 'thumbsup':
            return self.storage.getThumbsup()
        if playlist_id == 'lastadded':
            return self.storage.getLastadded()
        if playlist_id == 'mostplayed':
            return self.storage.getMostplayed()
        if playlist_id == 'freepurchased':
            return self.storage.getFreepurchased()

        if not self.storage.isPlaylistFetched(playlist_id) or forceRenew:
            self.updatePlaylistSongs(playlist_id)

        songs = self.storage.getPlaylistSongs(playlist_id)

        return songs

    def getPlaylistsByType(self, playlist_type, forceRenew=False):
        if playlist_type == 'auto':
            return [['thumbsup', 'Highly Rated'], ['lastadded', 'Last Added'],
                    ['freepurchased', 'Free and Purchased'],
                    ['mostplayed', 'Most Played']]

        if forceRenew:
            self.updatePlaylists(playlist_type)

        playlists = self.storage.getPlaylistsByType(playlist_type)
        if len(playlists) == 0 and not forceRenew:
            self.updatePlaylists(playlist_type)
            playlists = self.storage.getPlaylistsByType(playlist_type)

        return playlists

    def getSong(self, song_id):
        return self.storage.getSong(song_id)

    def updatePlaylistSongs(self, playlist_id):
        api_songs = []

        self.login.login()
        if playlist_id == 'all_songs':
            api_songs = self.gmusicapi.get_all_songs()
        else:
            api_songs = self.gmusicapi.get_playlist_songs(playlist_id)

        if api_songs:
            self.storage.storeApiSongs(api_songs, playlist_id)

    def updatePlaylists(self, playlist_type):
        self.login.login()
        playlists = self.gmusicapi.get_all_playlist_ids(playlist_type)
        self.storage.storePlaylists(playlists[playlist_type], playlist_type)

    def getSongStreamUrl(self, song_id):
        self.login.login()
        stream_url = self.gmusicapi.get_stream_url(song_id)
        #self.storage.updateSongStreamUrl(song_id, stream_url)

        return stream_url

    def getFilterSongs(self, filter_type, filter_criteria):
        songs = self.storage.getFilterSongs(filter_type, filter_criteria)

        return songs

    def getCriteria(self, criteria):
        return self.storage.getCriteria(criteria)

    def getSearch(self, query):
        return self.storage.getSearch(query)

    def clearCache(self):
        self.storage.clearCache()
        self.login.clearCookie()

    def clearCookie(self):
        self.login.clearCookie()
Exemple #5
0
class Serenade():


	def __init__(self):
		self.app = QtGui.QApplication(sys.argv)
		self.app.setApplicationName("Serenade")
		signal.signal(signal.SIGINT, signal.SIG_DFL)

		self.position = 0

		self.player = MultimediaKit.QMediaPlayer(self.app)
		self.player.positionChanged.connect(self.positionChanged)

		self.signals = Signals()

		self.client = gconf.client_get_default()

		self.api = Api()
		self.artists = []
		self.library = {}

		self.cacheDir = QtGui.QDesktopServices.storageLocation(QtGui.QDesktopServices.CacheLocation)
		if not os.path.exists(self.cacheDir):
			os.mkdir(self.cacheDir)
		self.artistModel = ArtistModel()
		self.songModel = SongModel()
		self.signals.onDoneWorking.connect(self.doneWorking)
		self.signals.onError.connect(self.error)
		self.view = QtDeclarative.QDeclarativeView()
		self.view.setSource("/opt/serenade/qml/Main.qml")
		self.rootObject = self.view.rootObject()
		self.context = self.view.rootContext()
		self.context.setContextProperty('songModel', self.songModel)
		self.context.setContextProperty('artistModel', self.artistModel)
		self.rootObject.openFile("MenuPage.qml")
		self.rootObject.refresh.connect(self.updateSongs)
		self.rootObject.newLogin.connect(self.newLogin)
		self.rootObject.play.connect(self.play)
		self.rootObject.togglePause.connect(self.togglePause)
		self.login()
		self.view.showFullScreen()

		sys.exit(self.app.exec_())


	def login(self):
		email = self.client.get_string('/apps/serenade/email')
		passwd = self.client.get_string('/apps/serenade/passwd')
		if not email or not passwd:
			self.rootObject.openFile("LoginPage.qml")
		else:
			logged_in = self.api.login(email, passwd)
			if not logged_in:
				self.rootObject.openFile("LoginPage.qml")
				self.rootObject.showMessage("Login failed", "Please check your email and password and try again. If you're using two-factor authentication you may need to set an application specific password in your Google account.")
			else:
				self.rootObject.openFile("MenuPage.qml")
				self.updateSongs()

	
	def newLogin(self, email, passwd):
		self.client.set_string('/apps/serenade/email', email)
		self.client.set_string('/apps/serenade/passwd', passwd)
		self.login()


	def updateSongs(self):
		self.rootObject.startWorking()
		thread = threading.Thread(target=self._updateSongs)
		thread.start()


	def _updateSongs(self):
		self.library = sorted(self.api.get_all_songs(), key=lambda x: x['title'])
		self.library.reverse()
		for s in self.library:
			if "albumArtUrl" in s:
				art = self.getImage(s['albumArtUrl'])
			else:
				art = "/opt/serenade/no-art.png"
			if s['artist'] not in self.artists:
				artist = Artist(s['artist'], art)
				self.artists.append(s['artist'])
				self.artistModel.add(artist)
			song = Song(s['id'], s['title'], s['album'], s['artist'], False, art)
			self.songModel.add(song)
		self.artistModel.sort()
		self.signals.onDoneWorking.emit()


	def doneWorking(self):
		self.rootObject.stopWorking()


	def error(self, title, message):
		self.rootObject.showMessage(title, message)


	def getImage(self, url):
		filename = url.split("/")[-1]
		imagePath = os.path.join(self.cacheDir, filename)		
		imagePath = imagePath.replace("?", "")
		if not os.path.exists(imagePath):
			try:   
				out = open(imagePath, 'wb')
				out.write(urllib2.urlopen("http:" + url).read())
				out.close()
			except Exception, err:
				return "/opt/serenade/no-art.png"
		return imagePath
class GoogleMusicApi():
    def __init__(self):
        self.storage = sys.modules["__main__"].storage

        self.gmusicapi = Api(debug_logging=False)
        self.login = GoogleMusicLogin.GoogleMusicLogin(self.gmusicapi)

    def getPlaylistSongs(self, playlist_id, forceRenew=False):

        if playlist_id == 'thumbsup':
            return self.storage.getThumbsup()
        if playlist_id == 'lastadded':
            return self.storage.getLastadded()
        if playlist_id == 'mostplayed':
            return self.storage.getMostplayed()
        if playlist_id == 'freepurchased':
            return self.storage.getFreepurchased()

        if not self.storage.isPlaylistFetched(playlist_id) or forceRenew:
            self.updatePlaylistSongs(playlist_id)

        songs = self.storage.getPlaylistSongs(playlist_id)

        return songs

    def getPlaylistsByType(self, playlist_type, forceRenew=False):
        if playlist_type == 'auto':
            return [['thumbsup','Highly Rated'],['lastadded','Last Added'],['freepurchased','Free and Purchased'],['mostplayed','Most Played']]

        if forceRenew:
            self.updatePlaylists(playlist_type)

        playlists = self.storage.getPlaylistsByType(playlist_type)
        if len(playlists) == 0 and not forceRenew:
            self.updatePlaylists(playlist_type)
            playlists = self.storage.getPlaylistsByType(playlist_type)

        return playlists

    def getSong(self, song_id):
        return self.storage.getSong(song_id)

    def updatePlaylistSongs(self, playlist_id):
        api_songs = []

        self.login.login()
        if playlist_id == 'all_songs':
            api_songs = self.gmusicapi.get_all_songs()
        else:
            api_songs = self.gmusicapi.get_playlist_songs(playlist_id)
 
        if api_songs:
            self.storage.storeApiSongs(api_songs, playlist_id)

    def updatePlaylists(self, playlist_type):
        self.login.login()
        playlists = self.gmusicapi.get_all_playlist_ids(playlist_type)
        self.storage.storePlaylists(playlists[playlist_type], playlist_type)

    def getSongStreamUrl(self, song_id):
        self.login.login()
        stream_url = self.gmusicapi.get_stream_url(song_id)
        #self.storage.updateSongStreamUrl(song_id, stream_url)

        return stream_url

    def getFilterSongs(self, filter_type, filter_criteria):
        songs = self.storage.getFilterSongs(filter_type, filter_criteria)

        return songs

    def getCriteria(self, criteria):
        return self.storage.getCriteria(criteria)
        
    def getSearch(self, query):
        return self.storage.getSearch(query)

    def clearCache(self):
        self.storage.clearCache()
        self.login.clearCookie()

    def clearCookie(self):
        self.login.clearCookie()
Exemple #7
0
class GoogleMusic():
	"""This class handles the communication with Google Music."""
	def __init__(self, email, password):
		if not email or not password:
			raise Exception("Username and password needs to be given")

		self._library = None
		self._artists = None
		self._albums = None
		self._playlists = None

		self._email = email
		self._password = password

		# Initialize the Google Music API
		self._api_init(self._email, self._password)

		if not self._api.is_authenticated():
			raise Exception("Credentials were not accepted!")

		# Initial load of the library
		self.load_library()

	def _api_init(self, email, password):
		"""Inits the API object and login to Google Music"""
		self._api = Api()
		self._api.login(email, password)

	def load_library(self):
		"""
		This function downloads the music library from Google Music and
		processes it.
		"""
		self._library = self._api.get_all_songs()

		# Generate artists and albums trees
		self._gen_trees()

	def _gen_trees(self):
		"""
		This function generates trees of artists and albums from the library.

		Parts of this function are taken from: https://github.com/mstill/thunner/blob/master/thunner
		=> Thanks for the great code :)
		"""
		# Use defaultdict to group song dictionaries by artists
		artists_dict = collections.defaultdict(list)
		for i in self._library:
			artists_dict[i['artist']].append(i)

		artists = []
		albums =  []
		for artist, songs_of_artist in artists_dict.iteritems():
			albums_of_artists_dict = collections.defaultdict(list)
			for i in songs_of_artist:
				albums_of_artists_dict[i['album']].append(i)

			albums_of_artist = []
			for album,tracks in albums_of_artists_dict.iteritems():
				album_name = album
				if album == "":
					album_name = "Untitled album"

				albums_of_artist.append({
											"name": album_name,
											"subtree": sorted(tracks, key=itemgetter('track')),
											"subtreeline": 0
										})

			albums = albums + albums_of_artist
			artists.append({
								"name": artist,
								"subtree": sorted(albums_of_artist, key=lambda x: x['name'].lower()),
								"subtreeline": 0
							})

		self._artists = sorted(artists, key=lambda x: x['name'].lower())
		self._albums = sorted(albums, key=lambda x: x['name'].lower())

	def get_songs(self):
		"""This function returns all songs from the music library."""
		songs = []
		for entry in self._library:
			song = {
				'id': entry['id'],
				'title': entry['title'], 
				'artist': entry['artist'], 
				'album': entry['album'] 
			}
			songs.append(song)

		return songs

	def get_artists(self):
		pass

	def get_albums(self):
		pass 

	def get_stream_url(self, id):
		return self._api.get_stream_url(id)
Exemple #8
0
class MusicLibrary(object):
    'Read information about your Google Music library'

    def __init__(self, username=None, password=None, true_file_size=False):
        self.__artists = {}  # 'artist name' -> {'album name' : Album(), ...}
        self.__albums = []  # [Album(), ...]
        self.__login(username, password)
        self.__aggregate_albums()
        self.true_file_size = true_file_size

    def __login(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)
            config = ConfigParser.ConfigParser()
            config.read(cred_path)
            username = config.get('credentials', 'username')
            password = config.get('credentials', 'password')
            if not username or not password:
                raise NoCredentialException(
                    'No username/password could be read from config file'
                    ': %s' % cred_path)

        self.api = GoogleMusicAPI()
        log.info('Logging in...')
        self.api.login(username, password, perform_upload_auth=False)
        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:
            # Get the Album object if it already exists:
            key = '%s|||%s' % (formatNames(
                track['artistNorm']), formatNames(track['albumNorm']))
            album = all_artist_albums.get(key, None)
            if not album:
                # New Album
                artist = formatNames(track['artistNorm'])
                if artist == '':
                    artist = 'unknown'
                album = all_artist_albums[key] = Album(
                    self, formatNames(track['albumNorm']))
                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]
Exemple #9
0
class MusicLibrary(object):
    'Read information about your Google Music library'
    
    def __init__(self, username=None, password=None, true_file_size=False):
        self.__artists = {} # 'artist name' -> {'album name' : Album(), ...}
        self.__albums = [] # [Album(), ...]
        self.__login(username, password)
        self.__aggregate_albums()
        self.true_file_size = true_file_size

    def __login(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)
            config = ConfigParser.ConfigParser()
            config.read(cred_path)
            username = config.get('credentials','username')
            password = config.get('credentials','password')
            if not username or not password:
                raise NoCredentialException(
                    'No username/password could be read from config file'
                    ': %s' % cred_path)
            
        self.api = GoogleMusicAPI()
        log.info('Logging in...')
        self.api.login(username, password, perform_upload_auth=False)
        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:
            # Get the Album object if it already exists:
            key = '%s|||%s' % (formatNames(track['artistNorm']), formatNames(track['albumNorm']))
            album = all_artist_albums.get(key, None)
            if not album:
                # New Album
                artist = formatNames(track['artistNorm'])
                if artist == '':
                    artist = 'unknown'
                album = all_artist_albums[key] = Album(
                    self, formatNames(track['albumNorm']))
                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]
Exemple #10
0
class GoogleMusic():
    """This class handles the communication with Google Music."""
    def __init__(self, email, password):
        if not email or not password:
            raise Exception("Username and password needs to be given")

        self._library = None
        self._artists = None
        self._albums = None
        self._playlists = None

        self._email = email
        self._password = password

        # Initialize the Google Music API
        self._api_init(self._email, self._password)

        if not self._api.is_authenticated():
            raise Exception("Credentials were not accepted!")

        # Initial load of the library
        self.load_library()

    def _api_init(self, email, password):
        """Inits the API object and login to Google Music"""
        self._api = Api()
        self._api.login(email, password)

    def load_library(self):
        """
		This function downloads the music library from Google Music and
		processes it.
		"""
        self._library = self._api.get_all_songs()

        # Generate artists and albums trees
        self._gen_trees()

    def _gen_trees(self):
        """
		This function generates trees of artists and albums from the library.

		Parts of this function are taken from: https://github.com/mstill/thunner/blob/master/thunner
		=> Thanks for the great code :)
		"""
        # Use defaultdict to group song dictionaries by artists
        artists_dict = collections.defaultdict(list)
        for i in self._library:
            artists_dict[i['artist']].append(i)

        artists = []
        albums = []
        for artist, songs_of_artist in artists_dict.iteritems():
            albums_of_artists_dict = collections.defaultdict(list)
            for i in songs_of_artist:
                albums_of_artists_dict[i['album']].append(i)

            albums_of_artist = []
            for album, tracks in albums_of_artists_dict.iteritems():
                album_name = album
                if album == "":
                    album_name = "Untitled album"

                albums_of_artist.append({
                    "name":
                    album_name,
                    "subtree":
                    sorted(tracks, key=itemgetter('track')),
                    "subtreeline":
                    0
                })

            albums = albums + albums_of_artist
            artists.append({
                "name":
                artist,
                "subtree":
                sorted(albums_of_artist, key=lambda x: x['name'].lower()),
                "subtreeline":
                0
            })

        self._artists = sorted(artists, key=lambda x: x['name'].lower())
        self._albums = sorted(albums, key=lambda x: x['name'].lower())

    def get_songs(self):
        """This function returns all songs from the music library."""
        songs = []
        for entry in self._library:
            song = {
                'id': entry['id'],
                'title': entry['title'],
                'artist': entry['artist'],
                'album': entry['album']
            }
            songs.append(song)

        return songs

    def get_artists(self):
        pass

    def get_albums(self):
        pass

    def get_stream_url(self, id):
        return self._api.get_stream_url(id)
Exemple #11
0
class GoogleMusicApi():
    def __init__(self):
        self.xbmc = sys.modules["__main__"].xbmc
        self.xbmcgui = sys.modules["__main__"].xbmcgui
        self.xbmcplugin = sys.modules["__main__"].xbmcplugin

        self.settings = sys.modules["__main__"].settings
        self.language = sys.modules["__main__"].language
        self.dbg = sys.modules["__main__"].dbg
        self.common = sys.modules["__main__"].common
        self.storage = sys.modules["__main__"].storage

        self.gmusicapi = Api()
        self.login = GoogleMusicLogin.GoogleMusicLogin(self.gmusicapi)

    def getPlaylistSongs(self, playlist_id, forceRenew=False):
        if not self.storage.isPlaylistFetched(playlist_id) or forceRenew:
            self.updatePlaylistSongs(playlist_id)

        songs = self.storage.getPlaylistSongs(playlist_id)

        return songs

    def getPlaylistsByType(self, playlist_type, forceRenew=False):
        if forceRenew:
            self.updatePlaylists(playlist_type)

        playlists = self.storage.getPlaylistsByType(playlist_type)
        if len(playlists) == 0 and not forceRenew:
            self.updatePlaylists(playlist_type)
            playlists = self.storage.getPlaylistsByType(playlist_type)

        return playlists

    def getSong(self, song_id):
        return self.storage.getSong(song_id)

    def updatePlaylistSongs(self, playlist_id):
        api_songs = []

        self.login.login()
        if playlist_id == 'all_songs':
            api_songs = self.gmusicapi.get_all_songs()
        else:
            api_songs = self.gmusicapi.get_playlist_songs(playlist_id)

        self.storage.storeApiSongs(api_songs, playlist_id)

    def updatePlaylists(self, playlist_type):
        self.login.login()
        playlists = self.gmusicapi.get_all_playlist_ids(
            playlist_type == "auto",
            playlist_type == "instant",
            playlist_type == "user",
            always_id_lists=True)
        self.storage.storePlaylists(playlists[playlist_type], playlist_type)

    def getSongStreamUrl(self, song_id):
        self.login.login()
        stream_url = self.gmusicapi.get_stream_url(song_id)
        #self.storage.updateSongStreamUrl(song_id, stream_url)

        return stream_url
Exemple #12
0
class GMusicRater:
    def __init__(self, files):
        self.__api = Api()
        self.__by_rating = {}
        self.__needs_rating_update = []

        # fill list of songs
        lib = []
        cachefile = "gmusic.pickle"
        if os.path.isfile(cachefile):
            print "Loading cached library..."
            infile = open(cachefile, "rb")
            lib = cPickle.load(infile)
        else:
            self.__log_in()
            print "Getting music..."
            lib = self.__api.get_all_songs()
            print "Writing..."
            outfile = open(cachefile, "wb+")
            cPickle.dump(lib, outfile)

        # order list of songs by rating
        notfound = []
        total_found = 0
        for s in lib:
            r = files.find_rating(s)
            # error finding file:
            if r < 0:
                notfound.append(s)
                continue

            # print "Got rating for %s: %s" % (s["title"], s["rating"])
            # file rating is different from cloud rating:
            if not r == s["rating"]:
                s["rating"] = r
                self.__needs_rating_update.append(s)
            if not self.__by_rating.has_key(r):
                self.__by_rating[r] = []
            self.__by_rating[r].append(s)
            total_found += 1

        print "Found %d cloud songs, %d of which need rating updates." % (total_found, len(self.__needs_rating_update))
        print "Not found on disk: %d" % len(notfound)
        for s in notfound:
            print "  %s - %s" % (s["artist"], s["title"])

    def __log_in(self):
        if self.__api.is_authenticated():
            return

        print "Logging in..."
        email = raw_input("Email: ")
        password = getpass.getpass()
        if not self.__api.login(email, password):
            print "couldnt log in"
            sys.exit(1)

    def reset_playlists(self):
        self.__log_in()
        playlists = self.__api.get_all_playlist_ids(auto=False, user=True)["user"]
        print "Got %d playlists:" % len(playlists)
        for k, v in playlists.iteritems():
            print "  Deleting %s (%s)" % (k, v)
            for playlistid in v:
                self.__api.delete_playlist(playlistid)

        def get_ids(slist):
            ret = []
            for s in slist:
                ret.append(s["id"])
            return ret

        awesome_songids = get_ids(self.__by_rating.get(5, []))
        good_songids = awesome_songids + get_ids(self.__by_rating.get(4, []))
        unrated_songids = get_ids(self.__by_rating.get(0, []))

        awesome_pid = self.__api.create_playlist("Awesome")
        print "Awesome %s -> %d songs" % (awesome_pid, len(awesome_songids))
        self.__api.add_songs_to_playlist(awesome_pid, awesome_songids)

        good_pid = self.__api.create_playlist("Good")
        print "Good %s -> %d songs" % (good_pid, len(good_songids))
        self.__api.add_songs_to_playlist(good_pid, good_songids)

        unrated_pid = self.__api.create_playlist("Unrated")
        print "Unrated %s -> %d songs" % (unrated_pid, len(unrated_songids))
        self.__api.add_songs_to_playlist(unrated_pid, unrated_songids)

    def update_ratings(self):
        total = len(self.__needs_rating_update)
        if total == 0:
            return
        self.__log_in()
        print "Updating %d songs..." % total
        # divide updates into chunks.
        start = 0
        chunksz = 100  # could probably be larger, wasn't tested for max possible
        while start < total:
            end = start + chunksz
            if end >= total:
                end = total
            print "%d - %d" % (start, end)
            self.__api.change_song_metadata(self.__needs_rating_update[start:end])
            start = end

    def logout(self):
        if self.__api.is_authenticated():
            print "Logging out..."
            self.__api.logout()