def get_spotify_data(keywords, num_playlists):
    """Master function get retrieve data from Spotify."""
    # Create instance of Spotify class
    SpotifyMaster = Spotify(CLIENT_ID, CLIENT_SECRET)

    # Only retrieve playlists if not at num_playlists
    playlist_table_size = return_table_len("Playlists")
    if playlist_table_size < num_playlists - 10:
        # Pull playlist data a keyword
        print("Getting Spotify playlists")
        cache_dict = json_helper.read_cache()
        keyword_index = cache_dict["keyword_index"]
        keyword = keywords[keyword_index]
        print("Keyword: " + keyword)

        # Get playlists
        json_result = SpotifyMaster.search(keyword, "playlist")
        playlists = json_result["playlists"]["items"]

        # Write playlists to database
        write_playlists_to_database(SpotifyMaster, playlists)
        playlist_table_size = return_table_len("Playlists")
        print("Playlist table size: " + str(playlist_table_size))

        return

    # Otherwise, start getting tracks until reach limit
    tracks_table_size = return_table_len("Tracks")
    track_features_table_size = return_table_len("TrackFeatures")

    # Finish if over 100 rows for either
    if tracks_table_size > 120 and track_features_table_size > 120:
        print("Gathered sufficient data for the database.")
        return

    if tracks_table_size != num_playlists * 10:
        print("Getting Spotify Tracks")

        # Get the correct playlist href and increment the index counter
        cache_dict = json_helper.read_cache()
        cache_dict["playlist_href_index"] = cache_dict.get(
            "playlist_href_index", -1) + 1
        playlist_href_index = cache_dict["playlist_href_index"]
        json_helper.write_cache(cache_dict)
        playlist_href = cache_dict["playlist_hrefs"][playlist_href_index]

        # Get track ids from the playlist and write to database
        track_ids = SpotifyMaster.get_tracks_from_playlist(playlist_href)
        write_tracks_and_features_to_database(SpotifyMaster, track_ids,
                                              playlist_href,
                                              playlist_href_index + 1)
        print("Tracks table size: " + str(tracks_table_size))
        print("Track Features table size: " + str(track_features_table_size))

        return

    # Done getting data, JOIN time.
    print("Done retrieving Spotify playlists and track data.")
Ejemplo n.º 2
0
class SpotifyToDiscord:
    def __init__(
        self,
        client_id: str,
        client_secret: str,
        webhook_url: str,
        playlist_id: str,
        interval: int = 60,
    ):
        self.spotify_api = Spotify(client_id, client_secret)
        self.webhook_url = webhook_url
        self.playlist_id = playlist_id
        self.interval = interval

    def _create_embed(self, track: Track, user: User,
                      notify_type: NotifyType) -> DiscordEmbed:
        embed = DiscordEmbed(title=notify_type.value.capitalize())

        artist_names = ", ".join(artist.name for artist in track.artists)

        user_link = f"https://open.spotify.com/user/{user.id}"
        user_hyperlink = f"[{user.display_name}]({user_link})"

        track_link = f"https://open.spotify.com/track/{track.id}"
        track_hyperlink = f"[{track.name}]({track_link})"

        playlist_link = f"https://open.spotify.com/playlist/{self.playlist_id}"
        add_text = (f"added by {user_hyperlink}\n"
                    if notify_type == NotifyType.ADD else "")

        description = (
            f"__{track_hyperlink}__ - {artist_names}\n{add_text}{playlist_link}"
        )

        embed.set_description(description)
        if track.album.images:
            embed.set_thumbnail(url=track.album.images[0].url)

        return embed

    def _send_webhook(self, track: Track, user: User,
                      notify_type: NotifyType) -> None:
        webhook = DiscordWebhook(url=self.webhook_url)
        embed = self._create_embed(track, user, notify_type)
        webhook.add_embed(embed)
        webhook.execute()

    def _get_tracks_data(self) -> list[tuple[str, str]]:
        return self.spotify_api.get_tracks_from_playlist(
            self.playlist_id,
            fields="items(added_by.id,track.id),next",
        )

    def start(self) -> None:
        self.spotify_api.update_token()
        before_tracks = set(self._get_tracks_data())
        loop_count = 1
        time.sleep(self.interval)
        self.loop(before_tracks, loop_count)

    def loop(self, before_tracks: set[tuple[str, str]],
             loop_count: int) -> None:
        # 1時間しかトークンが持たない><
        # 30分に1回くらい更新しとけばえかろ
        if loop_count % (self.interval // 2) == 0:
            self.spotify_api.update_token()

        after_tracks = set(self._get_tracks_data())

        added_tracks = after_tracks - before_tracks
        for track_id, user_id in added_tracks:
            track = self.spotify_api.get_track(track_id)
            user = self.spotify_api.get_user(user_id)
            logger.info('added "%s" from %s', asdict(track), asdict(user))
            self._send_webhook(track, user, NotifyType.ADD)

        deleted_tracks = before_tracks - after_tracks
        for track_id, user_id in deleted_tracks:
            track = self.spotify_api.get_track(track_id)
            user = self.spotify_api.get_user(user_id)
            logger.info('deleted "%s" from %s', asdict(track), asdict(user))
            self._send_webhook(track, user, NotifyType.REMOVE)

        time.sleep(self.interval)

        return self.loop(after_tracks, loop_count + 1)