Пример #1
0
try:
    youtube_auth = YTMusic('headers_auth.json')
except KeyError:
    sys.exit(
        'Cookie invalid. Did you paste your cookie into headers_auth.json?')

while True:
    uploaded_albums = youtube_auth.get_library_upload_albums()
    if not uploaded_albums:
        break
    for album in uploaded_albums:
        try:
            artist = album.get('artists')[0].get('name') if len(
                album.get('artists')) > 0 else "Unknown Artist"
            title = album.get("title")
            response = youtube_auth.delete_upload_entity(album['browseId'])
            if response == 'STATUS_SUCCEEDED':
                print(f'Deleted {artist} - {title}')
            else:
                print(f'Failed to delete {artist} - {title}')
        except (AttributeError, TypeError):
            pass

print('Finished deleting uploaded albums!')

while True:
    try:
        uploaded_songs = youtube_auth.get_library_upload_songs()
    except KeyError:
        break
    if not uploaded_songs:
Пример #2
0
class YoutubeMusicApiSingleton:
    __instance__ = None

    def __init__(self):
        """ Constructor."""
        self.__youtube_music_api = YTMusic(HEADERS_AUTH_FILE_PATH)
        if YoutubeMusicApiSingleton.__instance__ is None:
            YoutubeMusicApiSingleton.__instance__ = self
        else:
            raise Exception(
                "You cannot create another YoutubeMusicApiSingleton class, this class is a singleton"
            )

    @staticmethod
    def get_instance() -> 'YoutubeMusicApiSingleton':
        """Static method to get the current instance

        Returns:
            YoutubeMusicApiSingleton: Instance of the YoutubeMusicApiSingleton
        """
        if not YoutubeMusicApiSingleton.__instance__:
            YoutubeMusicApiSingleton()
        return YoutubeMusicApiSingleton.__instance__

    def add_song_to_library(self, song_to_add: Song) -> bool:
        """Add a song to the current user's Youtube Music library

        Args:
            song_to_add (Song): Song to add to library

        Returns:
            bool: True -> Song was successfully added to library | False -> Song was NOT added to library
        """
        response = self.__youtube_music_api.edit_song_library_status(song_to_add.feedback_tokens.add)
        # If responseContext is empty then song is already in library
        if not response['responseContext']:
            return True
        return to_bool(response['feedbackResponses'][0]['isProcessed'])

    def delete_library_uploaded_song(self, uploaded_song_to_delete: Song) -> None:
        """Delete an uploaded song from the current user's Youtube Music Library

        Args:
            uploaded_song_to_delete (Song): Uploaded song to delete
        """
        self.__youtube_music_api.delete_upload_entity(uploaded_song_to_delete.entity_id)

    def get_library_uploaded_songs(self, song_limit: int, order: Order) -> List[Song]:
        """Get a list of uploaded songs from the current user's Youtube Music Library

        Args:
            song_limit (int): Max amount of songs to retrieve
            order (Order): Order to retrieve the songs in

        Returns:
            List[Song]: List of uploaded library songs
        """
        return [Song(
            id=song_dict['videoId'],
            title=song_dict['title'],
            artists=[artist['name'] for artist in song_dict['artists']],
            album=song_dict['album']['name'],
            length=song_dict['duration'],
            like_status=LikeStatuses[song_dict['likeStatus']],
            entity_id=song_dict['entityId']) for song_dict in self.__youtube_music_api.get_library_upload_songs(song_limit, order.value)]

    def get_simple_library_playlists(self, playlist_limit: int) -> List[Playlist]:
        """Get a list of simple (no song info included) playlist information from the current user's Youtube Music library

        Args:
            playlist_limit (int): Max amount of playlists to retrieve

        Returns:
            List[Playlist]: List of simple library playlist information
        """
        return [Playlist(
            id=playlist_dict['playlistId'],
            title=playlist_dict['title'],
            song_count=playlist_dict.get('count', None)) for playlist_dict in self.__youtube_music_api.get_library_playlists(playlist_limit)]

    def rate_song(self, song: Song, rating: LikeStatuses) -> None:
        """Rate a song (Like / Dislike / Indifferent)

        Args:
            song (Song): Song to rate
        """
        self.__youtube_music_api.rate_song(song.id, rating)

    def perform_search(
            self, query: str, item_type: ItemType, item_search_limit: int, ignore_spelling: bool) -> List[Dict]:
        """Search for an item in Youtube Music

        Args:
            query (str): Search query
            item_type (ItemType): Item type to search for
            item_search_limit (int): Max amount of items in the search results
            ignore_spelling (bool): True -> Ignore spelling suggestions | False -> Use autocorrected text

        Returns:
            List[Dict]: List of search result items
        """

        search_results = []
        for result in self.__youtube_music_api.search(query=query, filter=item_type.value, limit=item_search_limit, ignore_spelling=ignore_spelling):

            if result['resultType'] == "song":
                search_results.append(
                    Song(
                        id=result['videoId'],
                        title=result['title'],
                        artists=[artist['name'] for artist in result['artists']],
                        album=result['album']['name'],
                        explicit=to_bool(result['isExplicit']),
                        length=result['duration'],
                        feedback_tokens=FeedbackTokens(
                            add=result['feedbackTokens']['add'],
                            remove=result['feedbackTokens']['remove'])))

            if result['resultType'] == "playlist":
                search_results.append(
                    Playlist(
                        id=result['browseId'],
                        title=result['title'],
                        song_count=result['itemCount']))

        return search_results

    def get_complete_playlist(self, playlist: Playlist, playlist_song_limit: int) -> Playlist:
        """Get complete information about the given playlist (including information about the items in the playlist)

        Args:
            playlist (Playlist): Playlist to get information for
            playlist_song_limit (int): Max amount of songs to retrieve from the playlist

        Returns:
            Playlist: Complete playlist
        """
        response = self.__youtube_music_api.get_playlist(playlist.id, playlist_song_limit)
        return Playlist(
            id=response['id'],
            title=response['title'],
            song_count=response['trackCount'],
            songs=[Song(
                id=song_dict['videoId'],
                title=song_dict['title'],
                artists=[artist['name'] for artist in song_dict['artists']],
                album=song_dict['album']['name'],
                explicit=to_bool(song_dict['isExplicit']),
                length=song_dict.get('duration'),
                like_status=LikeStatuses(song_dict['likeStatus']) if song_dict['likeStatus'] else None,
                set_id=song_dict['setVideoId'],
                feedback_tokens=FeedbackTokens(
                    add=song_dict.get('feedbackTokens', {}).get('add'),
                    remove=song_dict.get('feedbackTokens', {}).get('remove'))) for song_dict in response['tracks']])

    def remove_songs_from_playlist(self, playlist: Playlist, songs: List[Song]) -> None:
        """Remove songs from a playlist in Youtube Music

        Args:
            playlist (Playlist): Playlist to remove the song from (Complete playlist info required)
            songs (List[Song]): List of songs to remove from the playlist
        """
        self.__youtube_music_api.remove_playlist_items(playlist.id,
                                                       [{'videoId': song.id, 'setVideoId': song.set_id}
                                                        for song in songs])
Пример #3
0
 def delete(self, tracks):
     """Deletion can fail if exactly the same file was uploaded in a different album with a different title."""
     for track in tracks:
         YTMusic.delete_upload_entity(track["entityId"])