Beispiel #1
0
def library_library(request, uuid, redirect_to_ap):
    queryset = models.Library.objects.filter(uuid=uuid)
    try:
        obj = queryset.get()
    except models.Library.DoesNotExist:
        return []

    if redirect_to_ap:
        raise middleware.ApiRedirect(obj.fid)

    library_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("library_library", kwargs={"uuid": obj.uuid}),
    )
    metas = [
        {"tag": "meta", "property": "og:url", "content": library_url},
        {"tag": "meta", "property": "og:type", "content": "website"},
        {"tag": "meta", "property": "og:title", "content": obj.name},
        {"tag": "meta", "property": "og:description", "content": obj.description},
    ]

    if preferences.get("federation__enabled"):
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/activity+json",
                "href": obj.fid,
            }
        )

    return metas
Beispiel #2
0
def actor_detail_username(request, username, redirect_to_ap):
    validator = federation_utils.get_actor_data_from_username
    try:
        username_data = validator(username)
    except serializers.ValidationError:
        return []

    queryset = (models.Actor.objects.filter(
        preferred_username__iexact=username_data["username"]).local().
                select_related("attachment_icon"))
    try:
        obj = queryset.get()
    except models.Actor.DoesNotExist:
        return []

    if redirect_to_ap:
        raise middleware.ApiRedirect(obj.fid)
    obj_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("actor_detail",
                          kwargs={"username": obj.preferred_username}),
    )
    metas = [
        {
            "tag": "meta",
            "property": "og:url",
            "content": obj_url
        },
        {
            "tag": "meta",
            "property": "og:title",
            "content": obj.display_name
        },
        {
            "tag": "meta",
            "property": "og:type",
            "content": "profile"
        },
    ]

    if obj.attachment_icon:
        metas.append({
            "tag":
            "meta",
            "property":
            "og:image",
            "content":
            obj.attachment_icon.download_url_medium_square_crop,
        })

    if preferences.get("federation__enabled"):
        metas.append({
            "tag": "link",
            "rel": "alternate",
            "type": "application/activity+json",
            "href": obj.fid,
        })

    return metas
Beispiel #3
0
def test_music_library_retrieve_redirects_to_html_if_header_set(
        factories, api_client, settings):
    library = factories["music.Library"](actor__local=True)

    url = reverse("federation:music:libraries-detail",
                  kwargs={"uuid": library.uuid})
    response = api_client.get(url, HTTP_ACCEPT="text/html")
    expected_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("library_library", kwargs={"uuid": library.uuid}),
    )
    assert response.status_code == 302
    assert response["Location"] == expected_url
Beispiel #4
0
def library_playlist(request, pk, redirect_to_ap):
    queryset = playlists_models.Playlist.objects.filter(pk=pk, privacy_level="everyone")
    try:
        obj = queryset.get()
    except playlists_models.Playlist.DoesNotExist:
        return []
    obj_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("library_playlist", kwargs={"pk": obj.pk}),
    )
    # we use the first playlist track's album's cover as image
    playlist_tracks = obj.playlist_tracks.exclude(track__album__attachment_cover=None)
    playlist_tracks = playlist_tracks.select_related("track__album").order_by("index")
    first_playlist_track = playlist_tracks.first()
    metas = [
        {"tag": "meta", "property": "og:url", "content": obj_url},
        {"tag": "meta", "property": "og:title", "content": obj.name},
        {"tag": "meta", "property": "og:type", "content": "music.playlist"},
    ]

    if first_playlist_track:
        metas.append(
            {
                "tag": "meta",
                "property": "og:image",
                "content": first_playlist_track.track.album.attachment_cover.download_url_medium_square_crop,
            }
        )

    if (
        models.Upload.objects.filter(
            track__pk__in=[obj.playlist_tracks.values("track")]
        )
        .playable_by(None)
        .exists()
    ):
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/json+oembed",
                "href": (
                    utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed"))
                    + "?format=json&url={}".format(urllib.parse.quote_plus(obj_url))
                ),
            }
        )
        # twitter player is also supported in various software
        metas += get_twitter_card_metas(type="playlist", id=obj.pk)
    return metas
Beispiel #5
0
def test_upload_retrieve_redirects_to_html_if_header_set(
        factories, api_client, settings):
    upload = factories["music.Upload"](library__local=True, playable=True)

    url = reverse(
        "federation:music:uploads-detail",
        kwargs={"uuid": upload.uuid},
    )
    response = api_client.get(url, HTTP_ACCEPT="text/html")
    expected_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("library_track", kwargs={"pk": upload.track.pk}),
    )
    assert response.status_code == 302
    assert response["Location"] == expected_url
Beispiel #6
0
def test_actor_retrieve_redirects_to_html_if_header_set(
        factories, api_client, settings):
    actor = factories["federation.Actor"](local=True)

    url = reverse(
        "federation:actors-detail",
        kwargs={"preferred_username": actor.preferred_username},
    )
    response = api_client.get(url, HTTP_ACCEPT="text/html")
    expected_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("actor_detail",
                          kwargs={"username": actor.preferred_username}),
    )
    assert response.status_code == 302
    assert response["Location"] == expected_url
Beispiel #7
0
def test_oembed_channel(factories, no_api_auth, api_client, settings):
    settings.FUNKWHALE_URL = "http://test"
    settings.FUNKWHALE_EMBED_URL = "http://embed"
    channel = factories["audio.Channel"](artist__with_cover=True)
    artist = channel.artist
    url = reverse("api:v1:oembed")
    obj_url = "https://test.com/channels/{}".format(channel.uuid)
    iframe_src = "http://embed?type=channel&id={}".format(channel.uuid)
    expected = {
        "version":
        "1.0",
        "type":
        "rich",
        "provider_name":
        settings.APP_NAME,
        "provider_url":
        settings.FUNKWHALE_URL,
        "height":
        400,
        "width":
        600,
        "title":
        artist.name,
        "description":
        artist.name,
        "thumbnail_url":
        federation_utils.full_url(
            artist.attachment_cover.file.crop["200x200"].url),
        "thumbnail_height":
        200,
        "thumbnail_width":
        200,
        "html":
        '<iframe width="600" height="400" scrolling="no" frameborder="no" src="{}"></iframe>'
        .format(iframe_src),
        "author_name":
        artist.name,
        "author_url":
        federation_utils.full_url(
            utils.spa_reverse("channel_detail", kwargs={"uuid":
                                                        channel.uuid})),
    }

    response = api_client.get(url, {"url": obj_url, "format": "json"})

    assert response.data == expected
Beispiel #8
0
def test_spa_views_raise_api_redirect_when_accept_json_set(
    factory_name,
    factory_kwargs,
    route_name,
    route_arg_name,
    route_arg,
    factories,
    fake_request,
):
    obj = factories[factory_name](**factory_kwargs)
    url = utils.spa_reverse(
        route_name,
        kwargs={route_arg_name: utils.recursive_getattr(obj, route_arg)})
    request = fake_request.get(url, HTTP_ACCEPT="application/activity+json")

    with pytest.raises(middleware.ApiRedirect) as excinfo:
        middleware.get_request_head_tags(request)
    assert excinfo.value.url == obj.fid
Beispiel #9
0
def library_track(request, pk, redirect_to_ap):
    queryset = models.Track.objects.filter(pk=pk).select_related("album", "artist")
    try:
        obj = queryset.get()
    except models.Track.DoesNotExist:
        return []

    playable_uploads = obj.uploads.playable_by(None).order_by("id")
    upload = playable_uploads.first()

    if redirect_to_ap:
        redirect_url = upload.fid if upload else obj.fid
        raise middleware.ApiRedirect(redirect_url)

    track_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("library_track", kwargs={"pk": obj.pk}),
    )
    metas = [
        {"tag": "meta", "property": "og:url", "content": track_url},
        {"tag": "meta", "property": "og:title", "content": obj.title},
        {"tag": "meta", "property": "og:type", "content": "music.song"},
        {"tag": "meta", "property": "music:album:disc", "content": obj.disc_number},
        {"tag": "meta", "property": "music:album:track", "content": obj.position},
        {
            "tag": "meta",
            "property": "music:musician",
            "content": utils.join_url(
                settings.FUNKWHALE_URL,
                utils.spa_reverse("library_artist", kwargs={"pk": obj.artist.pk}),
            ),
        },
    ]

    if obj.album:
        metas.append(
            {
                "tag": "meta",
                "property": "music:album",
                "content": utils.join_url(
                    settings.FUNKWHALE_URL,
                    utils.spa_reverse("library_album", kwargs={"pk": obj.album.pk}),
                ),
            },
        )

    if obj.attachment_cover:
        metas.append(
            {
                "tag": "meta",
                "property": "og:image",
                "content": obj.attachment_cover.download_url_medium_square_crop,
            }
        )
    elif obj.album and obj.album.attachment_cover:
        metas.append(
            {
                "tag": "meta",
                "property": "og:image",
                "content": obj.album.attachment_cover.download_url_medium_square_crop,
            }
        )
    if upload:
        metas.append(
            {
                "tag": "meta",
                "property": "og:audio",
                "content": utils.join_url(settings.FUNKWHALE_URL, obj.listen_url),
            }
        )
        if preferences.get("federation__enabled"):
            metas.append(
                {
                    "tag": "link",
                    "rel": "alternate",
                    "type": "application/activity+json",
                    "href": upload.fid,
                }
            )
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/json+oembed",
                "href": (
                    utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed"))
                    + "?format=json&url={}".format(urllib.parse.quote_plus(track_url))
                ),
            }
        )
        # twitter player is also supported in various software
        metas += get_twitter_card_metas(type="track", id=obj.pk)
    return metas
Beispiel #10
0
def library_artist(request, pk, redirect_to_ap):
    queryset = models.Artist.objects.filter(pk=pk)
    try:
        obj = queryset.get()
    except models.Artist.DoesNotExist:
        return []

    if redirect_to_ap:
        raise middleware.ApiRedirect(obj.fid)

    artist_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("library_artist", kwargs={"pk": obj.pk}),
    )
    # we use latest album's cover as artist image
    latest_album = (
        obj.albums.exclude(attachment_cover=None).order_by("release_date").last()
    )
    metas = [
        {"tag": "meta", "property": "og:url", "content": artist_url},
        {"tag": "meta", "property": "og:title", "content": obj.name},
        {"tag": "meta", "property": "og:type", "content": "profile"},
    ]

    if latest_album and latest_album.attachment_cover:
        metas.append(
            {
                "tag": "meta",
                "property": "og:image",
                "content": latest_album.attachment_cover.download_url_medium_square_crop,
            }
        )

    if preferences.get("federation__enabled"):
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/activity+json",
                "href": obj.fid,
            }
        )

    if (
        models.Upload.objects.filter(Q(track__artist=obj) | Q(track__album__artist=obj))
        .playable_by(None)
        .exists()
    ):
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/json+oembed",
                "href": (
                    utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed"))
                    + "?format=json&url={}".format(urllib.parse.quote_plus(artist_url))
                ),
            }
        )
        # twitter player is also supported in various software
        metas += get_twitter_card_metas(type="artist", id=obj.pk)
    return metas
Beispiel #11
0
def library_album(request, pk, redirect_to_ap):
    queryset = models.Album.objects.filter(pk=pk).select_related("artist")
    try:
        obj = queryset.get()
    except models.Album.DoesNotExist:
        return []

    if redirect_to_ap:
        raise middleware.ApiRedirect(obj.fid)

    album_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("library_album", kwargs={"pk": obj.pk}),
    )
    metas = [
        {"tag": "meta", "property": "og:url", "content": album_url},
        {"tag": "meta", "property": "og:title", "content": obj.title},
        {"tag": "meta", "property": "og:type", "content": "music.album"},
        {
            "tag": "meta",
            "property": "music:musician",
            "content": utils.join_url(
                settings.FUNKWHALE_URL,
                utils.spa_reverse("library_artist", kwargs={"pk": obj.artist.pk}),
            ),
        },
    ]

    if obj.release_date:
        metas.append(
            {
                "tag": "meta",
                "property": "music:release_date",
                "content": str(obj.release_date),
            }
        )

    if obj.attachment_cover:
        metas.append(
            {
                "tag": "meta",
                "property": "og:image",
                "content": obj.attachment_cover.download_url_medium_square_crop,
            }
        )

    if preferences.get("federation__enabled"):
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/activity+json",
                "href": obj.fid,
            }
        )
    if models.Upload.objects.filter(track__album=obj).playable_by(None).exists():
        metas.append(
            {
                "tag": "link",
                "rel": "alternate",
                "type": "application/json+oembed",
                "href": (
                    utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed"))
                    + "?format=json&url={}".format(urllib.parse.quote_plus(album_url))
                ),
            }
        )
        # twitter player is also supported in various software
        metas += get_twitter_card_metas(type="album", id=obj.pk)
    return metas
Beispiel #12
0
    def validate(self, validated_data):
        try:
            match = common_utils.spa_resolve(
                urllib.parse.urlparse(validated_data["url"]).path
            )
        except urls.exceptions.Resolver404:
            raise serializers.ValidationError(
                "Invalid URL {}".format(validated_data["url"])
            )
        data = {
            "version": "1.0",
            "type": "rich",
            "provider_name": settings.APP_NAME,
            "provider_url": settings.FUNKWHALE_URL,
            "height": validated_data.get("maxheight") or 400,
            "width": validated_data.get("maxwidth") or 600,
        }
        embed_id = None
        embed_type = None
        if match.url_name == "library_track":
            qs = models.Track.objects.select_related("artist", "album__artist").filter(
                pk=int(match.kwargs["pk"])
            )
            try:
                track = qs.get()
            except models.Track.DoesNotExist:
                raise serializers.ValidationError(
                    "No track matching id {}".format(match.kwargs["pk"])
                )
            embed_type = "track"
            embed_id = track.pk
            data["title"] = "{} by {}".format(track.title, track.artist.name)
            if track.attachment_cover:
                data[
                    "thumbnail_url"
                ] = track.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            elif track.album and track.album.attachment_cover:
                data[
                    "thumbnail_url"
                ] = track.album.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["description"] = track.full_name
            data["author_name"] = track.artist.name
            data["height"] = 150
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse(
                    "library_artist", kwargs={"pk": track.artist.pk}
                )
            )
        elif match.url_name == "library_album":
            qs = models.Album.objects.select_related("artist").filter(
                pk=int(match.kwargs["pk"])
            )
            try:
                album = qs.get()
            except models.Album.DoesNotExist:
                raise serializers.ValidationError(
                    "No album matching id {}".format(match.kwargs["pk"])
                )
            embed_type = "album"
            embed_id = album.pk
            if album.attachment_cover:
                data[
                    "thumbnail_url"
                ] = album.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["title"] = "{} by {}".format(album.title, album.artist.name)
            data["description"] = "{} by {}".format(album.title, album.artist.name)
            data["author_name"] = album.artist.name
            data["height"] = 400
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse(
                    "library_artist", kwargs={"pk": album.artist.pk}
                )
            )
        elif match.url_name == "library_artist":
            qs = models.Artist.objects.filter(pk=int(match.kwargs["pk"]))
            try:
                artist = qs.get()
            except models.Artist.DoesNotExist:
                raise serializers.ValidationError(
                    "No artist matching id {}".format(match.kwargs["pk"])
                )
            embed_type = "artist"
            embed_id = artist.pk
            album = artist.albums.exclude(attachment_cover=None).order_by("-id").first()

            if album and album.attachment_cover:
                data[
                    "thumbnail_url"
                ] = album.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["title"] = artist.name
            data["description"] = artist.name
            data["author_name"] = artist.name
            data["height"] = 400
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse("library_artist", kwargs={"pk": artist.pk})
            )
        elif match.url_name == "channel_detail":
            from funkwhale_api.audio.models import Channel

            kwargs = {}
            if "uuid" in match.kwargs:
                kwargs["uuid"] = match.kwargs["uuid"]
            else:
                username_data = federation_utils.get_actor_data_from_username(
                    match.kwargs["username"]
                )
                kwargs["actor__domain"] = username_data["domain"]
                kwargs["actor__preferred_username__iexact"] = username_data["username"]
            qs = Channel.objects.filter(**kwargs).select_related(
                "artist__attachment_cover"
            )
            try:
                channel = qs.get()
            except models.Artist.DoesNotExist:
                raise serializers.ValidationError(
                    "No channel matching id {}".format(match.kwargs["uuid"])
                )
            embed_type = "channel"
            embed_id = channel.uuid

            if channel.artist.attachment_cover:
                data[
                    "thumbnail_url"
                ] = channel.artist.attachment_cover.download_url_medium_square_crop
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["title"] = channel.artist.name
            data["description"] = channel.artist.name
            data["author_name"] = channel.artist.name
            data["height"] = 400
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse(
                    "channel_detail", kwargs={"uuid": channel.uuid}
                )
            )
        elif match.url_name == "library_playlist":
            qs = playlists_models.Playlist.objects.filter(
                pk=int(match.kwargs["pk"]), privacy_level="everyone"
            )
            try:
                obj = qs.get()
            except playlists_models.Playlist.DoesNotExist:
                raise serializers.ValidationError(
                    "No artist matching id {}".format(match.kwargs["pk"])
                )
            embed_type = "playlist"
            embed_id = obj.pk
            playlist_tracks = obj.playlist_tracks.exclude(
                track__album__attachment_cover=None
            )
            playlist_tracks = playlist_tracks.select_related(
                "track__album__attachment_cover"
            ).order_by("index")
            first_playlist_track = playlist_tracks.first()

            if first_playlist_track:
                data[
                    "thumbnail_url"
                ] = (
                    first_playlist_track.track.album.attachment_cover.download_url_medium_square_crop
                )
                data["thumbnail_width"] = 200
                data["thumbnail_height"] = 200
            data["title"] = obj.name
            data["description"] = obj.name
            data["author_name"] = obj.name
            data["height"] = 400
            data["author_url"] = federation_utils.full_url(
                common_utils.spa_reverse("library_playlist", kwargs={"pk": obj.pk})
            )
        else:
            raise serializers.ValidationError(
                "Unsupported url: {}".format(validated_data["url"])
            )
        data[
            "html"
        ] = '<iframe width="{}" height="{}" scrolling="no" frameborder="no" src="{}"></iframe>'.format(
            data["width"], data["height"], get_embed_url(embed_type, embed_id)
        )
        return data
Beispiel #13
0
def channel_detail(query, redirect_to_ap):
    queryset = models.Channel.objects.filter(query).select_related(
        "artist__attachment_cover", "actor", "library")
    try:
        obj = queryset.get()
    except models.Channel.DoesNotExist:
        return []

    if redirect_to_ap:
        raise middleware.ApiRedirect(obj.actor.fid)

    obj_url = utils.join_url(
        settings.FUNKWHALE_URL,
        utils.spa_reverse("channel_detail",
                          kwargs={"username": obj.actor.full_username}),
    )
    metas = [
        {
            "tag": "meta",
            "property": "og:url",
            "content": obj_url
        },
        {
            "tag": "meta",
            "property": "og:title",
            "content": obj.artist.name
        },
        {
            "tag": "meta",
            "property": "og:type",
            "content": "profile"
        },
    ]

    if obj.artist.attachment_cover:
        metas.append({
            "tag":
            "meta",
            "property":
            "og:image",
            "content":
            obj.artist.attachment_cover.download_url_medium_square_crop,
        })

    if preferences.get("federation__enabled"):
        metas.append({
            "tag": "link",
            "rel": "alternate",
            "type": "application/activity+json",
            "href": obj.actor.fid,
        })

    metas.append(
        {
            "tag": "link",
            "rel": "alternate",
            "type": "application/rss+xml",
            "href": obj.get_rss_url(),
            "title": "{} - RSS Podcast Feed".format(obj.artist.name),
        }, )

    if obj.library.uploads.all().playable_by(None).exists():
        metas.append({
            "tag":
            "link",
            "rel":
            "alternate",
            "type":
            "application/json+oembed",
            "href":
            (utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed")) +
             "?format=json&url={}".format(urllib.parse.quote_plus(obj_url))),
        })
        # twitter player is also supported in various software
        metas += spa_views.get_twitter_card_metas(type="channel", id=obj.uuid)
    return metas
Beispiel #14
0
def test_library_track(spa_html, no_api_auth, client, factories, settings):
    upload = factories["music.Upload"](
        playable=True,
        track__disc_number=1,
        track__attachment_cover=None,
        track__album__with_cover=True,
    )
    track = upload.track
    url = "/library/tracks/{}".format(track.pk)

    response = client.get(url)

    expected_metas = [
        {
            "tag": "meta",
            "property": "og:url",
            "content": utils.join_url(settings.FUNKWHALE_URL, url),
        },
        {
            "tag": "meta",
            "property": "og:title",
            "content": track.title
        },
        {
            "tag": "meta",
            "property": "og:type",
            "content": "music.song"
        },
        {
            "tag": "meta",
            "property": "music:album:disc",
            "content": str(track.disc_number),
        },
        {
            "tag": "meta",
            "property": "music:album:track",
            "content": str(track.position),
        },
        {
            "tag":
            "meta",
            "property":
            "music:musician",
            "content":
            utils.join_url(
                settings.FUNKWHALE_URL,
                utils.spa_reverse("library_artist",
                                  kwargs={"pk": track.artist.pk}),
            ),
        },
        {
            "tag":
            "meta",
            "property":
            "music:album",
            "content":
            utils.join_url(
                settings.FUNKWHALE_URL,
                utils.spa_reverse("library_album",
                                  kwargs={"pk": track.album.pk}),
            ),
        },
        {
            "tag":
            "meta",
            "property":
            "og:image",
            "content":
            track.album.attachment_cover.download_url_medium_square_crop,
        },
        {
            "tag": "meta",
            "property": "og:audio",
            "content": utils.join_url(settings.FUNKWHALE_URL,
                                      track.listen_url),
        },
        {
            "tag": "link",
            "rel": "alternate",
            "type": "application/activity+json",
            "href": upload.fid,
        },
        {
            "tag":
            "link",
            "rel":
            "alternate",
            "type":
            "application/json+oembed",
            "href":
            (utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed")) +
             "?format=json&url={}".format(
                 urllib.parse.quote_plus(
                     utils.join_url(settings.FUNKWHALE_URL, url)))),
        },
        {
            "tag": "meta",
            "property": "twitter:card",
            "content": "player"
        },
        {
            "tag": "meta",
            "property": "twitter:player",
            "content": serializers.get_embed_url("track", id=track.id),
        },
        {
            "tag": "meta",
            "property": "twitter:player:width",
            "content": "600"
        },
        {
            "tag": "meta",
            "property": "twitter:player:height",
            "content": "400"
        },
    ]

    metas = utils.parse_meta(response.content.decode())

    # we only test our custom metas, not the default ones
    assert metas[:len(expected_metas)] == expected_metas