예제 #1
0
def playlist(request: HttpRequest) -> JsonResponse:
    spotify = get_spotify()
    tracks = spotify.user_playlist_tracks(
        os.getenv("SPOTIPY_USERNAME"),
        os.getenv("SPOTIFY_PLAYLIST_ID"),
    )

    return JsonResponse(SlackFormatter.playlist(tracks))
예제 #2
0
    def populate():
        client = get_spotify()
        errors = []

        tracks = Track.objects.filter(populated=False, spotify_id__isnull=False)[:10]
        for track in tracks:
            try:
                data = client._get("audio-features/" + client._get_id("track", track.spotify_id))
            except Exception as e:
                errors.append(str(e))
                continue

            track.analysis_url = data["analysis_url"]
            track.key = data["key"]
            track.time_signature = data["time_signature"]
            track.danceability = data["danceability"]
            track.energy = data["energy"]
            track.loudness = data["loudness"]
            track.speechiness = data["speechiness"]
            track.acousticness = data["acousticness"]
            track.instrumentalness = data["instrumentalness"]
            track.liveness = data["liveness"]
            track.valence = data["valence"]
            track.tempo = data["tempo"]
            track.duration_ms = data["duration_ms"]
            track.populated = True
            track.save()

            youtube_videos = YouTubeHelper().search("%s - %s" % (track.artists_to_str, track.title))

            for youtube_video in youtube_videos:
                try:
                    # do not load the same video twice
                    Video.objects.get(video_id=youtube_video["id"]["videoId"])
                    continue
                except Video.DoesNotExist:
                    pass
                except Video.MultipleObjectsReturned:
                    continue

                try:
                    video = Video()
                    video.track = track
                    video.source = "youtube"
                    video.description = youtube_video["snippet"]["description"]
                    video.title = youtube_video["snippet"]["title"]
                    video.channel_id = youtube_video["snippet"]["channelId"]
                    video.url = "https://www.youtube.com/watch?v=%s" % youtube_video["id"]["videoId"]
                    video.video_id = youtube_video["id"]["videoId"]
                    video.save()
                except Exception as e:
                    errors.append(str(e))
                    continue

        return [tracks, errors]
예제 #3
0
    def current_playing_track():
        client = get_spotify()
        logger = logging.getLogger(__name__)
        played = None
        try:
            track_details = client._get("me/player")
        except Exception as e:
            logger.error("Failed to retrieve details about current playing song: " + str(e))
            track_details = None

        if track_details \
                and "item" in track_details \
                and "uri" in track_details["item"] \
                and "artists" in track_details["item"]:
            try:
                track = Track.objects.get(spotify_id=track_details["item"]["uri"])
            except Track.DoesNotExist:
                track = Track()
            track.title = track_details["item"]["name"]
            track.album = track_details["item"]["album"]["name"]
            track.spotify_id = track_details["item"]["uri"]
            track.url = track_details["item"]["preview_url"]
            track.save()

            for artist_details in track_details["item"]["artists"]:
                try:
                    artist = Artist.objects.get(spotify_id=artist_details["uri"])
                except Artist.DoesNotExist:
                    artist = Artist()
                artist.spotify_id = artist_details["uri"]
                artist.name = artist_details["name"]
                artist.save()

                track.artists.add(artist)
                track.save()

            # Update played song if it has not played recently
            time_threshold = timezone.now() - timedelta(minutes=120)
            try:
                played = Played.objects.filter(track=track, on__gt=time_threshold)[:1].get()
            except Played.DoesNotExist:
                played = Played()
                played.on = timezone.now()
                played.track = track
                played.save()
        else:
            track = None

        return track, track_details, played
예제 #4
0
    def handle(self, *args, **options):
        sc = WebClient(os.getenv("SLACK_API_TOKEN"))
        sqs = boto3.client('sqs',
                           region_name=os.getenv('AWS_REGION',
                                                 'ap-southeast-2'))

        while True:
            if self.kill_now:
                break

            # in the loop so we can refresh the token if needed
            spotify_client = get_spotify()

            response = sqs.receive_message(
                QueueUrl=os.getenv('SLACK_PLAYLIST_QUEUE'),
                MaxNumberOfMessages=10,
                WaitTimeSeconds=20,
                VisibilityTimeout=60,
                MessageAttributeNames=['All'])

            if 'Messages' not in response:
                continue

            for sqs_msg in response['Messages']:
                try:
                    body = json.loads(sqs_msg['Body'])
                    action = body["action"]
                    title = body["search"]["q"]
                    user_slack_id = body["user"]["slack_id"]
                    tracks = spotify_client.search(title, limit=1)

                    if 1 == len(tracks["tracks"]["items"]) and action in [
                            "queue", "dequeue"
                    ]:
                        track_details = tracks["tracks"]["items"][0]

                        self._update_models(track_details, action,
                                            user_slack_id)

                        if "queue" == action:
                            spotify_client.user_playlist_add_tracks(
                                os.getenv("SPOTIPY_USERNAME"),
                                os.getenv("SPOTIFY_PLAYLIST_ID"),
                                [track_details["id"]])
                            notification = "The song *%s* by *%s* was queued to the playlist" % (
                                track_details["name"],
                                track_details["artists"][0]["name"])
                        else:
                            spotify_client.user_playlist_remove_all_occurrences_of_tracks(
                                os.getenv("SPOTIPY_USERNAME"),
                                os.getenv("SPOTIFY_PLAYLIST_ID"),
                                [track_details["id"]])
                            notification = "The song *%s* by *%s* was dequeued from the playlist" % (
                                track_details["name"],
                                track_details["artists"][0]["name"])

                        sc.api_call("chat.postMessage",
                                    channel=user_slack_id,
                                    text=notification,
                                    markdown=True,
                                    username="******" %
                                    os.getenv("SLACK_USERNAME", "Fusebox"),
                                    as_user=True)

                        requests.post(os.getenv("SPOTIPY_SLACK_CHANNEL_URL"),
                                      json={
                                          "text":
                                          "@%s just %sd *%s* by *%s*" %
                                          (body["user"]["name"], action,
                                           track_details["name"],
                                           track_details["artists"][0]["name"])
                                      })
                    else:
                        sc.api_call("chat.postMessage",
                                    channel=user_slack_id,
                                    text="No results for the song *%s*" %
                                    title,
                                    markdown=True,
                                    username="******" %
                                    os.getenv("SLACK_USERNAME", "Fusebox"),
                                    as_user=True)
                except JSONDecodeError as e:
                    logging.getLogger(__name__).error("Invalid json: " +
                                                      str(e))
                except SpotifyException as e:
                    logging.getLogger(__name__).error("Spotify failed: " +
                                                      str(e))
                    if 'user_slack_id' in locals():
                        sc.api_call(
                            "chat.postMessage",
                            channel=user_slack_id,
                            text=
                            "Spotify failed to handle request. Retry again.",
                            markdown=True,
                            username="******" %
                            os.getenv("SLACK_USERNAME", "Fusebox"),
                            as_user=True)

                sqs.delete_message(QueueUrl=os.getenv('SLACK_PLAYLIST_QUEUE'),
                                   ReceiptHandle=sqs_msg['ReceiptHandle'])
예제 #5
0
    def handle(self, *args, **options):
        sc = WebClient(os.getenv("SLACK_API_TOKEN"))
        sqs = boto3.client('sqs',
                           region_name=os.getenv('AWS_REGION',
                                                 'ap-southeast-2'))

        while True:
            if self.kill_now:
                break

            response = sqs.receive_message(
                QueueUrl=os.getenv('SLACK_PREDICT_QUEUE'),
                MaxNumberOfMessages=10,
                WaitTimeSeconds=20,
                VisibilityTimeout=60,
                MessageAttributeNames=['All'])

            if 'Messages' not in response:
                continue

            # in the loop so we can refresh the token if needed
            spotify_client = get_spotify()

            for sqs_msg in response['Messages']:
                try:
                    body = json.loads(sqs_msg['Body'])
                except json.decoder.JSONDecodeError as e:
                    logging.getLogger(__name__).error("Invalid json: " +
                                                      str(e))
                    continue

                title = body["search"]["q"]
                slack_id = body["user"]["slack_id"]

                tracks = spotify_client.search(title, limit=1)
                if 1 == len(tracks["tracks"]["items"]):
                    try:
                        track = tracks["tracks"]["items"][0]
                        track_details = spotify_client._get("audio-features/" +
                                                            track["id"])

                        aws_client = boto3.client('machinelearning',
                                                  region_name="us-east-1")
                        predicted = aws_client.predict(
                            MLModelId=os.getenv('ML_MODEL_ID',
                                                'ml-0vlfzxpmeGb'),
                            Record={
                                'id':
                                track["id"],
                                'danceability':
                                str(track_details["danceability"]),
                                'energy':
                                str(track_details["energy"]),
                                'loudness':
                                str(track_details["loudness"]),
                                'speechiness':
                                str(track_details["speechiness"]),
                                'acousticness':
                                str(track_details["acousticness"]),
                                'instrumentalness':
                                str(track_details["instrumentalness"]),
                                'liveness':
                                str(track_details["liveness"]),
                                'valence':
                                str(track_details["valence"]),
                                'tempo':
                                str(track_details["tempo"]),
                                'duration_ms':
                                str(track_details["duration_ms"]),
                                'played':
                                str(
                                    Played.objects.filter(
                                        track__spotify_id=track["id"]).count())
                            },
                            PredictEndpoint=
                            'https://realtime.machinelearning.us-east-1.amazonaws.com'
                        )
                        sc.api_call(
                            "chat.postMessage",
                            channel=slack_id,
                            text=
                            "The song *%s* by *%s* got a predicted rate of %.2f"
                            % (track["name"], track["artists"][0]["name"],
                               predicted["Prediction"]["predictedValue"]),
                            markdown=True,
                            username="******" %
                            os.getenv("SLACK_USERNAME", "Fusebox"),
                            as_user=True)

                        requests.post(
                            os.getenv("SPOTIPY_SLACK_CHANNEL_URL"),
                            json={
                                "text":
                                "@%s checked prediction for *%s* by *%s*" %
                                (body["user"]["name"], track["name"],
                                 track["artists"][0]["name"])
                            })
                    except Exception as e:
                        logging.getLogger(__name__).error(
                            "Something failed: " + str(e))
                else:
                    sc.api_call("chat.postMessage",
                                channel=slack_id,
                                text="No results for the song *%s*" % title,
                                markdown=True,
                                username="******" %
                                os.getenv("SLACK_USERNAME", "Fusebox"),
                                as_user=True)

                sqs.delete_message(QueueUrl=os.getenv('SLACK_PREDICT_QUEUE'),
                                   ReceiptHandle=sqs_msg['ReceiptHandle'])