Exemple #1
0
    def patch(self, request, leaderboard_type, gamemode, leaderboard_id):
        osu_user_id = request.user.osu_user_id
        if osu_user_id is None:
            raise PermissionDenied(
                "Must be authenticated with an osu! account.")

        access_type = request.data.get("access_type")
        if access_type is not None and access_type not in [
                LeaderboardAccessType.PUBLIC,
                LeaderboardAccessType.PUBLIC_INVITE_ONLY,
                LeaderboardAccessType.PRIVATE
        ]:
            raise ParseError(
                "Parameter access_type must be either 1 for public, 2 for invite-only public, or 3 for private."
            )

        name = request.data.get("name")
        description = request.data.get("description")

        icon_url = request.data.get("icon_url")
        if icon_url is not None:
            validator = URLValidator()
            try:
                validator(icon_url)
            except ValidationError:
                icon_url = ""

        archived = request.data.get("archived")
        if archived == False:
            user_owned_leaderboards = Leaderboard.community_leaderboards.filter(
                owner_id=osu_user_id, archived=False)
            if user_owned_leaderboards.count() >= 10:
                raise PermissionDenied(
                    "Each user is limited to owning 10 active leaderboards. You must archive or delete another leaderboard first."
                )

        leaderboard = Leaderboard.community_leaderboards.get(id=leaderboard_id)

        if leaderboard.owner_id != osu_user_id:
            raise PermissionDenied(
                "You must be the owner of a leaderboard to edit it.")

        if access_type is not None:
            leaderboard.access_type = access_type
        if name is not None:
            leaderboard.name = name
        if description is not None:
            leaderboard.description = description
        if icon_url is not None:
            leaderboard.icon_url = icon_url
        if archived is not None:
            leaderboard.archived = archived

        leaderboard.save()

        serialiser = LeaderboardSerialiser(leaderboard)
        return Response(serialiser.data)
Exemple #2
0
    def get(self, request, leaderboard_id):
        osu_user_id = request.user.osu_user_id if request.user.is_authenticated else None

        try:
            leaderboard = Leaderboard.objects.visible_to(osu_user_id).get(
                id=leaderboard_id)
        except Leaderboard.DoesNotExist:
            raise NotFound("Leaderboard not found.")

        serialiser = LeaderboardSerialiser(leaderboard)
        return Response(serialiser.data)
Exemple #3
0
    def get(self, request, leaderboard_type, gamemode, leaderboard_id):
        osu_user_id = request.user.osu_user_id if request.user.is_authenticated else None

        if leaderboard_type == "global":
            leaderboards = Leaderboard.global_leaderboards
        elif leaderboard_type == "community":
            leaderboards = Leaderboard.community_leaderboards.visible_to(
                osu_user_id)

        try:
            leaderboard = leaderboards.get(id=leaderboard_id)
        except Leaderboard.DoesNotExist:
            raise NotFound("Leaderboard not found.")

        serialiser = LeaderboardSerialiser(leaderboard)
        return Response(serialiser.data)
Exemple #4
0
    def get(self, request, leaderboard_type, gamemode):
        osu_user_id = request.user.osu_user_id if request.user.is_authenticated else None

        limit = parse_int_or_none(request.query_params.get("limit", 5))
        offset = parse_int_or_none(request.query_params.get("offset", 0))
        if limit > 25:
            limit = 25

        if leaderboard_type == "global":
            leaderboards = Leaderboard.global_leaderboards.filter(
                gamemode=gamemode)
        elif leaderboard_type == "community":
            leaderboards = Leaderboard.community_leaderboards.filter(
                gamemode=gamemode).visible_to(osu_user_id).order_by(
                    "-member_count")

        serialiser = LeaderboardSerialiser(leaderboards[offset:offset + limit],
                                           many=True)
        return Response(
            OrderedDict(count=leaderboards.count(), results=serialiser.data))
Exemple #5
0
    def get(self, request):
        osu_user_id = request.user.osu_user_id if request.user.is_authenticated else None

        # something very weird is happening when visible_to() is chained after the aggregate annotation for member_count
        #   that is causing the annotated values to be jumbled up on wrong instances somehow
        # for now we will temporarily disable showing private leaderboards on the full leaderboard list so we dont need to use visible_to() and solve this issue

        user_id = request.query_params.get("user_id")
        gamemode = request.query_params.get("gamemode")
        if user_id is not None:
            # filtering for leaderboards with a specific member and exclude global leaderboards
            leaderboards = Leaderboard.objects.exclude(
                access_type=LeaderboardAccessType.GLOBAL).filter(
                    members__id=user_id).select_related("owner")

            if gamemode is not None:
                # Filtering for leaderboards for a speficic gamemode
                leaderboards = leaderboards.filter(gamemode=gamemode)

            # filter for leaderboards visible to the user
            leaderboards = leaderboards.visible_to(osu_user_id)
        else:
            # filter for public leaderboards
            leaderboards = Leaderboard.objects.filter(access_type__in=[
                LeaderboardAccessType.PUBLIC,
                LeaderboardAccessType.PUBLIC_INVITE_ONLY
            ]).select_related("owner")

            # order by member count
            leaderboards = leaderboards.annotate(
                member_count=Count("members")).order_by("-member_count")

            # add in global leaderboards
            global_leaderboards = Leaderboard.objects.filter(
                access_type=LeaderboardAccessType.GLOBAL).select_related(
                    "owner")
            leaderboards = list(global_leaderboards) + list(leaderboards[:25])

        serialiser = LeaderboardSerialiser(leaderboards, many=True)
        return Response(serialiser.data)
Exemple #6
0
    def post(self, request):
        user_id = request.user.osu_user_id
        if user_id is None:
            return PermissionError(
                "Must be authenticated with an osu! account.")

        # Check required parameters
        gamemode = request.data.get("gamemode")
        if gamemode is None:
            raise ParseError("Missing gamemode parameter.")

        access_type = request.data.get("access_type")
        if access_type is None:
            raise ParseError("Missing access_type parameter.")
        elif access_type == LeaderboardAccessType.GLOBAL:
            raise ParseError(
                "Parameter access_type must be either 1 for public, 2 for invite-only public, or 3 for private."
            )

        name = request.data.get("name")
        if name is None:
            raise ParseError("Missing name parameter.")

        user_owned_leaderboards = Leaderboard.objects.filter(owner_id=user_id)
        if user_owned_leaderboards.count() >= 10:
            raise PermissionDenied(
                "Each user is limited to owning 10 leaderboards.")

        description = request.data.get("description")
        icon_url = request.data.get("icon_url")

        leaderboard = Leaderboard(gamemode=gamemode,
                                  access_type=access_type,
                                  name=name,
                                  description=description or "",
                                  icon_url=icon_url or "")

        # Set optional score criteria
        leaderboard.allow_past_scores = request.data.get(
            "allow_past_scores") if request.data.get(
                "allow_past_scores") is not None else True
        leaderboard.allowed_beatmap_status = request.data.get(
            "allowed_beatmap_status") or AllowedBeatmapStatus.RANKED_ONLY
        leaderboard.oldest_beatmap_date = request.data.get(
            "oldest_beatmap_date")
        leaderboard.newest_beatmap_date = request.data.get(
            "newest_beatmap_date")
        leaderboard.oldest_score_date = request.data.get("oldest_score_date")
        leaderboard.newest_score_date = request.data.get("newest_score_date")
        leaderboard.lowest_ar = request.data.get("lowest_ar")
        leaderboard.highest_ar = request.data.get("highest_ar")
        leaderboard.lowest_od = request.data.get("lowest_od")
        leaderboard.highest_od = request.data.get("highest_od")
        leaderboard.lowest_cs = request.data.get("lowest_cs")
        leaderboard.highest_cs = request.data.get("highest_cs")
        leaderboard.required_mods = request.data.get(
            "required_mods") or Mods.NONE
        leaderboard.disqualified_mods = request.data.get(
            "disqualified_mods") or Mods.NONE
        leaderboard.lowest_accuracy = request.data.get("lowest_accuracy")
        leaderboard.highest_accuracy = request.data.get("highest_accuracy")

        # Hand off to create_leaderboard service to set relations, update owner membership, and save
        leaderboard = create_leaderboard(user_id, leaderboard)

        serialiser = LeaderboardSerialiser(leaderboard)
        return Response(serialiser.data)
Exemple #7
0
    def post(self, request, leaderboard_type, gamemode):
        user_id = request.user.osu_user_id
        if user_id is None:
            raise PermissionDenied(
                "Must be authenticated with an osu! account.")

        if leaderboard_type == "global":
            raise PermissionDenied("Cannot create global leaderboards.")

        # Check required parameters
        score_set = request.data.get("score_set")
        if score_set is None:
            raise ParseError("Missing score_set parameter.")
        elif gamemode != Gamemode.STANDARD:
            # score set is not supported yet by non-standard gamemodes since they dont support chokes
            score_set = ScoreSet.NORMAL

        access_type = request.data.get("access_type")
        if access_type is None:
            raise ParseError("Missing access_type parameter.")
        elif access_type not in [
                LeaderboardAccessType.PUBLIC,
                LeaderboardAccessType.PUBLIC_INVITE_ONLY,
                LeaderboardAccessType.PRIVATE
        ]:
            raise ParseError(
                "Parameter access_type must be either 1 for public, 2 for invite-only public, or 3 for private."
            )

        name = request.data.get("name")
        if name is None:
            raise ParseError("Missing name parameter.")

        user_owned_leaderboards = Leaderboard.community_leaderboards.filter(
            owner_id=user_id, archived=False)
        if user_owned_leaderboards.count() >= 10:
            raise PermissionDenied(
                "Each user is limited to owning 10 active leaderboards. You must archive or delete another leaderboard first."
            )

        description = request.data.get("description")

        validator = URLValidator()
        try:
            icon_url = request.data.get("icon_url")
            validator(icon_url)
        except ValidationError:
            icon_url = None

        score_filter_data = request.data.get("score_filter")
        if score_filter_data is None:
            raise ParseError("Missing score_filter parameter.")

        leaderboard = Leaderboard(
            gamemode=gamemode,
            score_set=score_set,
            access_type=access_type,
            name=name,
            description=description or "",
            icon_url=icon_url or "",
            allow_past_scores=request.data.get("allow_past_scores"),
            score_filter=ScoreFilter(
                allowed_beatmap_status=score_filter_data.get(
                    "allowed_beatmap_status"),
                oldest_beatmap_date=score_filter_data.get(
                    "oldest_beatmap_date"),
                newest_beatmap_date=score_filter_data.get(
                    "newest_beatmap_date"),
                oldest_score_date=score_filter_data.get("oldest_score_date"),
                newest_score_date=score_filter_data.get("newest_score_date"),
                lowest_ar=score_filter_data.get("lowest_ar"),
                highest_ar=score_filter_data.get("highest_ar"),
                lowest_od=score_filter_data.get("lowest_od"),
                highest_od=score_filter_data.get("highest_od"),
                lowest_cs=score_filter_data.get("lowest_cs"),
                highest_cs=score_filter_data.get("highest_cs"),
                required_mods=score_filter_data.get("required_mods",
                                                    Mods.NONE),
                disqualified_mods=score_filter_data.get(
                    "disqualified_mods", Mods.NONE),
                lowest_accuracy=score_filter_data.get("lowest_accuracy"),
                highest_accuracy=score_filter_data.get("highest_accuracy"),
                lowest_length=score_filter_data.get("lowest_length"),
                highest_length=score_filter_data.get("highest_length")))

        # Hand off to create_leaderboard service to set relations, update owner membership, and save
        leaderboard = create_leaderboard(user_id, leaderboard)

        serialiser = LeaderboardSerialiser(leaderboard)
        return Response(serialiser.data)
Exemple #8
0
    def post(self, request):
        user_id = request.user.osu_user_id
        if user_id is None:
            return PermissionError(
                "Must be authenticated with an osu! account.")

        # Check required parameters
        gamemode = request.data.get("gamemode")
        if gamemode is None:
            raise ParseError("Missing gamemode parameter.")

        score_set = request.data.get("score_set")
        if score_set is None:
            raise ParseError("Missing score_set parameter.")
        elif gamemode != Gamemode.STANDARD:
            # score set is not supported yet by non-standard gamemodes since they dont support chokes
            score_set = ScoreSet.NORMAL

        access_type = request.data.get("access_type")
        if access_type is None:
            raise ParseError("Missing access_type parameter.")
        elif access_type == LeaderboardAccessType.GLOBAL:
            raise ParseError(
                "Parameter access_type must be either 1 for public, 2 for invite-only public, or 3 for private."
            )

        name = request.data.get("name")
        if name is None:
            raise ParseError("Missing name parameter.")

        user_owned_leaderboards = Leaderboard.objects.filter(owner_id=user_id)
        if user_owned_leaderboards.count() >= 10:
            raise PermissionDenied(
                "Each user is limited to owning 10 leaderboards.")

        description = request.data.get("description")
        icon_url = request.data.get("icon_url")

        score_filter_data = request.data.get("score_filter")
        if score_filter_data is None:
            raise ParseError("Missing score_filter parameter.")

        leaderboard = Leaderboard(
            gamemode=gamemode,
            score_set=score_set,
            access_type=access_type,
            name=name,
            description=description or "",
            icon_url=icon_url or "",
            allow_past_scores=request.data.get("allow_past_scores"),
            score_filter=ScoreFilter.objects.create(
                allowed_beatmap_status=score_filter_data.get(
                    "allowed_beatmap_status"),
                oldest_beatmap_date=score_filter_data.get(
                    "oldest_beatmap_date"),
                newest_beatmap_date=score_filter_data.get(
                    "newest_beatmap_date"),
                oldest_score_date=score_filter_data.get("oldest_score_date"),
                newest_score_date=score_filter_data.get("newest_score_date"),
                lowest_ar=score_filter_data.get("lowest_ar"),
                highest_ar=score_filter_data.get("highest_ar"),
                lowest_od=score_filter_data.get("lowest_od"),
                highest_od=score_filter_data.get("highest_od"),
                lowest_cs=score_filter_data.get("lowest_cs"),
                highest_cs=score_filter_data.get("highest_cs"),
                required_mods=score_filter_data.get("required_mods",
                                                    Mods.NONE),
                disqualified_mods=score_filter_data.get(
                    "disqualified_mods", Mods.NONE),
                lowest_accuracy=score_filter_data.get("lowest_accuracy"),
                highest_accuracy=score_filter_data.get("highest_accuracy"),
                lowest_length=score_filter_data.get("lowest_length"),
                highest_length=score_filter_data.get("highest_length")))

        # Hand off to create_leaderboard service to set relations, update owner membership, and save
        leaderboard = create_leaderboard(user_id, leaderboard)

        serialiser = LeaderboardSerialiser(leaderboard)
        return Response(serialiser.data)