diff --git a/discovery-provider/src/api/v1/tracks.py b/discovery-provider/src/api/v1/tracks.py index cf8a0b1edd7..9074deb0b9a 100644 --- a/discovery-provider/src/api/v1/tracks.py +++ b/discovery-provider/src/api/v1/tracks.py @@ -32,6 +32,7 @@ from src.api.v1.models.users import user_model_full from src.queries.get_feed import get_feed from src.queries.get_max_id import get_max_id +from src.queries.get_random_tracks import get_random_tracks from src.queries.get_recommended_tracks import ( DEFAULT_RECOMMENDED_LIMIT, get_full_recommended_tracks, @@ -1110,6 +1111,44 @@ def get(self): return success_response(tracks) +feeling_lucky_parser = current_user_parser.copy() +feeling_lucky_parser.add_argument( + "limit", + required=False, + default=25, + type=int, + description="Number of tracks to fetch", +) +feeling_lucky_parser.add_argument( + "with_users", + required=False, + type=bool, + description="Boolean to include user info with tracks", +) + + +@full_ns.route("/feeling_lucky") +class FeelingLucky(Resource): + @record_metrics + @full_ns.doc( + id="""Get Feeling Lucky Tracks""", + description="""Gets random tracks found on the \"Feeling Lucky\" smart playlist""", + ) + @full_ns.expect(feeling_lucky_parser) + @full_ns.marshal_with(full_tracks_response) + @cache(ttl_sec=10) + def get(self): + request_args = feeling_lucky_parser.parse_args() + args = { + "with_users": request_args.get("with_users"), + "limit": format_limit(request_args, max_limit=100, default_limit=25), + "user_id": get_current_user_id(request_args), + } + tracks = get_random_tracks(args) + tracks = list(map(extend_track, tracks)) + return success_response(tracks) + + @ns.route("/latest", doc=False) class LatestTrack(Resource): @record_metrics diff --git a/discovery-provider/src/queries/get_random_tracks.py b/discovery-provider/src/queries/get_random_tracks.py new file mode 100644 index 00000000000..a8932bd8d9d --- /dev/null +++ b/discovery-provider/src/queries/get_random_tracks.py @@ -0,0 +1,49 @@ +from sqlalchemy import func +from src.models.tracks.track import Track +from src.queries.query_helpers import ( + get_users_by_id, + get_users_ids, + populate_track_metadata, +) +from src.utils import helpers +from src.utils.db_session import get_db_read_replica + + +def get_random_tracks(args): + + limit = args.get("limit", 25) + + current_user_id = args.get("user_id") + db = get_db_read_replica() + with db.scoped_session() as session: + # Query for random tracks + tracks_query = ( + session.query( + Track, + ) + .filter( + Track.is_current == True, + Track.is_delete == False, + Track.is_unlisted == False, + Track.stem_of == None, + ) + .order_by(func.random()) + .limit(limit) + ) + + tracks_query_results = tracks_query.all() + tracks = helpers.query_result_to_list(tracks_query_results) + track_ids = list(map(lambda track: track["track_id"], tracks)) + + # bundle peripheral info into track results + tracks = populate_track_metadata(session, track_ids, tracks, current_user_id) + + if args.get("with_users", False): + user_id_list = get_users_ids(tracks) + users = get_users_by_id(session, user_id_list) + for track in tracks: + user = users[track["owner_id"]] + if user: + track["user"] = user + + return tracks