Пример #1
0
def load_playlist(playlist_mbid: str):
    """Load a single playlist by id
    """
    if not is_valid_uuid(playlist_mbid):
        raise BadRequest("Provided playlist ID is invalid: %s" % playlist_mbid)

    playlist = db_playlist.get_by_mbid(playlist_mbid, True)
    # TODO: Allow playlist collaborators to access private playlist
    if playlist is None or not playlist.public and (not current_user.is_authenticated or playlist.creator_id != current_user.id):
        raise NotFound("Cannot find playlist: %s" % playlist_mbid)

    fetch_playlist_recording_metadata(playlist)

    spotify_data = {}
    current_user_data = {}
    if current_user.is_authenticated:
        spotify_data = spotify.get_user_dict(current_user.id)

        current_user_data = {
                "id": current_user.id,
                "name": current_user.musicbrainz_id,
                "auth_token": current_user.auth_token,
        }
    props = {
        "current_user": current_user_data,
        "spotify": spotify_data,
        "api_url": current_app.config["API_URL"],
        "web_sockets_server_url": current_app.config['WEBSOCKETS_SERVER_URL'],
        "playlist": serialize_jspf(playlist)
    }

    return render_template(
        "playlists/playlist.html",
        props=ujson.dumps(props)
    )
Пример #2
0
def playlists(user_name: str):
    """ Show user playlists """
    
    if not current_app.config.get("FEATURE_PLAYLIST", False):
        raise NotFound()
    
    offset = request.args.get('offset', 0)
    try:
        offset = int(offset)
    except ValueError:
        raise BadRequest("Incorrect int argument offset: %s" % request.args.get("offset"))
    
    count = request.args.get("count", DEFAULT_NUMBER_OF_PLAYLISTS_PER_CALL)
    try:
        count = int(count)
    except ValueError:
        raise BadRequest("Incorrect int argument count: %s" % request.args.get("count"))
    
    user = _get_user(user_name)
    user_data = {
        "name": user.musicbrainz_id,
        "id": user.id,
    }
    
    current_user_data = {}
    if current_user.is_authenticated:
        current_user_data = {
            "id": current_user.id,
            "name": current_user.musicbrainz_id,
            "auth_token": current_user.auth_token,
        }
    
    include_private = current_user.is_authenticated and current_user.id == user.id

    playlists = []
    user_playlists, playlist_count = get_playlists_for_user(user.id,
                                                            include_private=include_private,
                                                            load_recordings=False,
                                                            count=count,
                                                            offset=offset)
    for playlist in user_playlists:
        playlists.append(serialize_jspf(playlist))

    props = {
        "current_user": current_user_data,
        "api_url": current_app.config["API_URL"],
        "playlists": playlists,
        "user": user_data,
        "active_section": "playlists",
        "playlist_count": playlist_count,
        "pagination_offset": offset,
        "playlists_per_page": count,
    }

    return render_template(
        "playlists/playlists.html",
        active_section="playlists",
        props=ujson.dumps(props),
        user=user
    )
Пример #3
0
def collaborations(user_name: str):
    """ Show playlists a user collaborates on """

    offset = request.args.get('offset', 0)
    try:
        offset = int(offset)
    except ValueError:
        raise BadRequest("Incorrect int argument offset: %s" %
                         request.args.get("offset"))

    count = request.args.get("count", DEFAULT_NUMBER_OF_PLAYLISTS_PER_CALL)
    try:
        count = int(count)
    except ValueError:
        raise BadRequest("Incorrect int argument count: %s" %
                         request.args.get("count"))

    user = _get_user(user_name)
    user_data = {
        "name": user.musicbrainz_id,
        "id": user.id,
    }

    current_user_data = {}
    if current_user.is_authenticated:
        current_user_data = {
            "id": current_user.id,
            "name": current_user.musicbrainz_id,
            "auth_token": current_user.auth_token,
        }

    include_private = current_user.is_authenticated and current_user.id == user.id

    playlists = []
    colalborative_playlists, playlist_count = get_playlists_collaborated_on(
        user.id,
        include_private=include_private,
        load_recordings=False,
        count=count,
        offset=offset)
    for playlist in colalborative_playlists:
        playlists.append(serialize_jspf(playlist))

    props = {
        "current_user": current_user_data,
        "api_url": current_app.config["API_URL"],
        "playlists": playlists,
        "user": user_data,
        "active_section": "collaborations",
        "playlist_count": playlist_count,
        "sentry_dsn": current_app.config.get("LOG_SENTRY", {}).get("dsn")
    }

    return render_template("playlists/playlists.html",
                           active_section="collaborations",
                           props=ujson.dumps(props),
                           user=user)
Пример #4
0
def recommendation_playlists(user_name: str):
    """ Show playlists created for user """
    
    if not current_app.config.get("FEATURE_PLAYLIST", False):
        raise NotFound()
    
    offset = request.args.get('offset', 0)
    try:
        offset = int(offset)
    except ValueError:
        raise BadRequest("Incorrect int argument offset: %s" % request.args.get("offset"))
    
    count = request.args.get("count", DEFAULT_NUMBER_OF_PLAYLISTS_PER_CALL)
    try:
        count = int(count)
    except ValueError:
        raise BadRequest("Incorrect int argument count: %s" % request.args.get("count"))
    
    
    user = _get_user(user_name)
    user_data = {
        "name": user.musicbrainz_id,
        "id": user.id,
    }
    
    spotify_data = {}
    current_user_data = {}
    if current_user.is_authenticated:
        spotify_data = spotify.get_user_dict(current_user.id)
        current_user_data = {
            "id": current_user.id,
            "name": current_user.musicbrainz_id,
            "auth_token": current_user.auth_token,
        }
    
    playlists = []
    user_playlists, playlist_count = get_playlists_created_for_user(user.id, False, count, offset)
    for playlist in user_playlists:
        playlists.append(serialize_jspf(playlist))


    props = {
        "current_user": current_user_data,
        "api_url": current_app.config["API_URL"],
        "playlists": playlists,
        "user": user_data,
        "active_section": "recommendations",
        "playlist_count": playlist_count,
    }

    return render_template(
        "playlists/playlists.html",
        active_section="recommendations",
        props=ujson.dumps(props),
        user=user
    )
Пример #5
0
def load_instant():
    """
    This endpoint takes in a list of recording_mbids and optional desc/name arguments  and then loads
    the recording_mbid's metadata and creates a JSPF file from this data and sends it to the front end
    so a playlist can be instantly played.

    .. note::
        We recommend that you do not send more than 50 recording_mbids in one request -- our
        server infrastructure will likely give you a gateway error (502) if you do.

    :param recording_mbids: A comma separated list of recording_mbids
    :type recording_mbids: ``str``
    :param desc: A description for this instant playlist (optional).
    :type desc: ``str``
    :param name: A name for this instant playlist (optional).
    :type name: ``str``
    :statuscode 200: playlist generated
    :statuscode 400: invalid recording_mbid arguments
    """

    recordings = request.args.get("recording_mbids", default=None)
    if recordings is None:
        raise BadRequest("recording_mbids argument must be present and contain a comma separated list of recording_mbids")

    recording_mbids = []
    for mbid in recordings.split(","):
        mbid_clean = mbid.strip()
        if not is_valid_uuid(mbid_clean):
            raise BadRequest(f"Recording mbid {mbid} is not valid.")

        recording_mbids.append(mbid_clean)

    desc = request.args.get("desc", default="")
    if not desc:
        desc = "Instant playlist"

    name = request.args.get("name", default="")
    if not name:
        name = "Instant playlist"

    now = datetime.now()
    playlist = WritablePlaylist(description=desc, name=name, creator="listenbrainz", creator_id=1, created=now)
    for i, mbid in enumerate(recording_mbids):
        rec = WritablePlaylistRecording(position=i, mbid=mbid, added_by_id=1, created=now)
        playlist.recordings.append(rec)

    fetch_playlist_recording_metadata(playlist)

    return render_template(
        "player/player-page.html",
        props=ujson.dumps({"playlist": serialize_jspf(playlist)})
    )
Пример #6
0
def serialize_playlists(playlists, playlist_count, count, offset):
    """
        Serialize the playlist metadata for the get playlists commands.
    """

    items = []
    for playlist in playlists:
        items.append(serialize_jspf(playlist))

    return {"playlists": items,
            "playlist_count": playlist_count,
            "offset": offset,
            "count": count}
Пример #7
0
def load_release(release_mbid):
    """
    This endpoint takes a release mbid, loads the tracks for this release and makes a playlist from it and
    sends it to the front end via JSPF.

    :statuscode 200: playlist generated
    :statuscode 400: invalid recording_mbid arguments
    """

    release_mbid = release_mbid.strip()
    if not is_valid_uuid(release_mbid):
        raise BadRequest(f"Recording mbid {release_mbid} is not valid.")

    playlist = None
    if mb_engine:
        release = get_release_by_mbid(release_mbid, includes=["media", "artists"])
        if not release:
            raise NotFound("This release was not found in our database. It may not have replicated to this server yet.")

        name = "Release %s by %s" % (release["name"], release["artist-credit-phrase"])
        desc = 'Release <a href="https://musicbrainz.org/release/%s">%s</a> by %s' % (release["mbid"],
                                                                                      release["name"],
                                                                                      release["artist-credit-phrase"])
        now = datetime.now()
        playlist = WritablePlaylist(description=desc, name=name, creator="listenbrainz", creator_id=1, created=now)
        for medium in release["medium-list"]:
            for recording in medium["track-list"]:
                rec = WritablePlaylistRecording(title=recording["name"],
                                                artist_credit=release["artist-credit-phrase"],
                                                artist_mbids=[a["artist"]["mbid"] for a in recording["artist-credit"]],
                                                release_name=release["name"],
                                                release_mbid=release["mbid"],
                                                position=recording["position"],
                                                mbid=recording["recording_id"],
                                                added_by_id=1, created=now)
                playlist.recordings.append(rec)

    return render_template(
        "player/player-page.html",
        props=ujson.dumps({"playlist": serialize_jspf(playlist) if playlist is not None else {}})
    )
Пример #8
0
def load_playlist(playlist_mbid: str):
    """Load a single playlist by id
    """
    if not is_valid_uuid(playlist_mbid):
        raise BadRequest("Provided playlist ID is invalid: %s" % playlist_mbid)

    current_user_id = None
    if current_user.is_authenticated:
        current_user_id = current_user.id

    playlist = db_playlist.get_by_mbid(playlist_mbid, True)
    if playlist is None or not playlist.is_visible_by(current_user_id):
        raise NotFound("Cannot find playlist: %s" % playlist_mbid)

    fetch_playlist_recording_metadata(playlist)

    spotify_data = {}
    current_user_data = {}
    if current_user.is_authenticated:
        spotify_data = spotify.get_user_dict(current_user.id)

        current_user_data = {
                "id": current_user.id,
                "name": current_user.musicbrainz_id,
                "auth_token": current_user.auth_token,
        }
    props = {
        "current_user": current_user_data,
        "spotify": spotify_data,
        "api_url": current_app.config["API_URL"],
        "labs_api_url": current_app.config["LISTENBRAINZ_LABS_API_URL"],
        "web_sockets_server_url": current_app.config['WEBSOCKETS_SERVER_URL'],
        "playlist": serialize_jspf(playlist),
        "sentry_dsn": current_app.config.get("LOG_SENTRY", {}).get("dsn")
    }

    return render_template(
        "playlists/playlist.html",
        props=ujson.dumps(props)
    )
Пример #9
0
def recommendation_playlists(user_name: str):
    """ Show playlists created for user """

    offset = request.args.get('offset', 0)
    try:
        offset = int(offset)
    except ValueError:
        raise BadRequest("Incorrect int argument offset: %s" %
                         request.args.get("offset"))

    count = request.args.get("count", DEFAULT_NUMBER_OF_PLAYLISTS_PER_CALL)
    try:
        count = int(count)
    except ValueError:
        raise BadRequest("Incorrect int argument count: %s" %
                         request.args.get("count"))
    user = _get_user(user_name)
    user_data = {
        "name": user.musicbrainz_id,
        "id": user.id,
    }

    playlists = []
    user_playlists, playlist_count = get_playlists_created_for_user(
        user.id, False, count, offset)
    for playlist in user_playlists:
        playlists.append(serialize_jspf(playlist))

    props = {
        "playlists": playlists,
        "user": user_data,
        "active_section": "recommendations",
        "playlist_count": playlist_count,
        "logged_in_user_follows_user": logged_in_user_follows_user(user),
    }

    return render_template("playlists/playlists.html",
                           active_section="recommendations",
                           props=ujson.dumps(props),
                           user=user)
Пример #10
0
def load_playlist(playlist_mbid: str):
    """Load a single playlist by id
    """
    if not is_valid_uuid(playlist_mbid):
        raise BadRequest("Provided playlist ID is invalid: %s" % playlist_mbid)

    current_user_id = None
    if current_user.is_authenticated:
        current_user_id = current_user.id

    playlist = db_playlist.get_by_mbid(playlist_mbid, True)
    if playlist is None or not playlist.is_visible_by(current_user_id):
        raise NotFound("Cannot find playlist: %s" % playlist_mbid)

    fetch_playlist_recording_metadata(playlist)

    props = {
        "labs_api_url": current_app.config["LISTENBRAINZ_LABS_API_URL"],
        "web_sockets_server_url": current_app.config['WEBSOCKETS_SERVER_URL'],
        "playlist": serialize_jspf(playlist),
    }

    return render_template("playlists/playlist.html", props=ujson.dumps(props))