import json
import time

from spotify import Spotify


def print_json(info):
    with open(f"tracks_info.json", "w") as f:
        f.write(json.dumps(info))


if __name__ == "__main__":
    sp = Spotify()
    ids = pd.read_csv("final_track_ids.csv", index_col="name")
    ids = ids[ids["track_id"] != "none"]
    tracks = {}
    idx = 0
    total = ids.shape[0]
    for _, row in ids.iterrows():
        if idx % 100 == 0:
            print(f"{idx}/{total}")
        idx += 1
        result = sp.get_track(row["track_id"])
        tracks[row["track_id"]] = {
            'artist_id': result["artists"][0]["id"],
            'artist_name': result["artists"][0]["name"],
            'duration_ms': result["duration_ms"],
            'track_name': result["name"],
        }
        time.sleep(0.01)
    print_json(tracks)
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)