From 1dff4c4e20585496895d0d1eda8484b292539776 Mon Sep 17 00:00:00 2001 From: Scott Date: Fri, 20 Jun 2025 20:02:17 -0400 Subject: [PATCH 1/5] First prototype for repo level for custom ranked akatsuki beatmaps api --- app/repositories/akatsuki_beatmaps.py | 41 +++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/app/repositories/akatsuki_beatmaps.py b/app/repositories/akatsuki_beatmaps.py index f8a1811..1ffe472 100644 --- a/app/repositories/akatsuki_beatmaps.py +++ b/app/repositories/akatsuki_beatmaps.py @@ -135,8 +135,45 @@ async def fetch_one_by_id(beatmap_id: int, /) -> AkatsukiBeatmap | None: bancho_creator_id=rec["bancho_creator_id"], bancho_creator_name=rec["bancho_creator_name"], ) - - + +async def fetch_many_maps_with_custom_akatsuki_status() -> list[AkatsukiBeatmap]: + query = """\ + SELECT * FROM beatmaps WHERE ranked_status_freezed = 1 ORDER BY lastest_updated + """ + rec = await state.database.fetch_all(query) + akatsuki_maps_with_custom_status: list[AkatsukiBeatmap] = [] + for akatsuki_beatmap in rec: + beatmap = AkatsukiBeatmap( + beatmap_id=akatsuki_beatmap["beatmap_id"], + beatmapset_id=akatsuki_beatmap["beatmapset_id"], + beatmap_md5=akatsuki_beatmap["beatmap_md5"], + song_name=akatsuki_beatmap["song_name"], + file_name=akatsuki_beatmap["file_name"], + ar=akatsuki_beatmap["ar"], + od=akatsuki_beatmap["od"], + mode=akatsuki_beatmap["mode"], + max_combo=akatsuki_beatmap["max_combo"], + hit_length=akatsuki_beatmap["hit_length"], + bpm=akatsuki_beatmap["bpm"], + ranked=akatsuki_beatmap["ranked"], + latest_update=akatsuki_beatmap["latest_update"], + ranked_status_freezed=akatsuki_beatmap["ranked_status_freezed"], + playcount=akatsuki_beatmap["playcount"], + passcount=akatsuki_beatmap["passcount"], + rankedby=akatsuki_beatmap["rankedby"], + rating=akatsuki_beatmap["rating"], + bancho_ranked_status=akatsuki_beatmap["bancho_ranked_status"], + count_circles=akatsuki_beatmap["count_circles"], + count_spinners=akatsuki_beatmap["count_spinners"], + count_sliders=akatsuki_beatmap["count_sliders"], + bancho_creator_id=akatsuki_beatmap["bancho_creator_id"], + bancho_creator_name=akatsuki_beatmap["bancho_creator_name"], + ) + akatsuki_maps_with_custom_status.append(beatmap) + return akatsuki_maps_with_custom_status + + + async def create_or_replace(beatmap: AkatsukiBeatmap) -> AkatsukiBeatmap: query = """\ REPLACE INTO beatmaps ( From ff824c6fd8e2bf2f3a8d8c9419071de934c17cb3 Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 30 Jul 2025 20:34:41 -0400 Subject: [PATCH 2/5] added akatsuki.py in api public folder and function for getting all beatmaps with custom akatsuki status in service layer --- app/api/public/akatsuki.py | 25 +++++++++++++++++++++++++ app/usecases/akatsuki_beatmaps.py | 4 ++++ 2 files changed, 29 insertions(+) create mode 100644 app/api/public/akatsuki.py diff --git a/app/api/public/akatsuki.py b/app/api/public/akatsuki.py new file mode 100644 index 0000000..1e6d605 --- /dev/null +++ b/app/api/public/akatsuki.py @@ -0,0 +1,25 @@ +"""\ +Provides an API exposing Akatsuki's beatmaps, which +include internal state such as ranked status updates. +""" + +import logging + +from fastapi import APIRouter +from fastapi import Header +from fastapi import Response + +from app.api.responses import JSONResponse +from app.usecases import akatsuki_beatmaps + +router = APIRouter(tags=["Akatsuki Beatmaps"]) +@router.get("/api/akatsuki/v1/beatmaps/akatsuki_beatmaps_lookup") #changed name from lookup +async def get_beatmap( + beatmap_id: int | None = None, + beatmap_md5: str | None = None, + client_ip_address: str | None = Header(None, alias="X-Real-IP"), + client_user_agent: str | None = Header(None, alias="User-Agent"), +) -> Response: + #idk if stuff above with get_beatmap is needed + beatmaps = await akatsuki_beatmaps.fetch_all_custom_ranked_beatmaps() + return JSONResponse(content=[AkatsukiBeatmap.model_dump() for AkatsukiBeatmap in beatmaps]) \ No newline at end of file diff --git a/app/usecases/akatsuki_beatmaps.py b/app/usecases/akatsuki_beatmaps.py index af79e58..3293406 100644 --- a/app/usecases/akatsuki_beatmaps.py +++ b/app/usecases/akatsuki_beatmaps.py @@ -205,3 +205,7 @@ async def fetch_one_by_md5(beatmap_md5: str) -> AkatsukiBeatmap | None: ) return beatmap + +async def fetch_all_custom_ranked_beatmaps() -> list[AkatsukiBeatmap]: + beatmaps = await akatsuki_beatmaps.fetch_many_maps_with_custom_akatsuki_status() + return beatmaps From 539156d2767f70e842bc30a18ab97fc81e04c04a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 14:24:29 +0000 Subject: [PATCH 3/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- app/api/public/akatsuki.py | 12 +++++++++--- app/repositories/akatsuki_beatmaps.py | 8 ++++---- app/usecases/akatsuki_beatmaps.py | 1 + 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/api/public/akatsuki.py b/app/api/public/akatsuki.py index 1e6d605..2c2c8bb 100644 --- a/app/api/public/akatsuki.py +++ b/app/api/public/akatsuki.py @@ -13,13 +13,19 @@ from app.usecases import akatsuki_beatmaps router = APIRouter(tags=["Akatsuki Beatmaps"]) -@router.get("/api/akatsuki/v1/beatmaps/akatsuki_beatmaps_lookup") #changed name from lookup + + +@router.get( + "/api/akatsuki/v1/beatmaps/akatsuki_beatmaps_lookup", +) # changed name from lookup async def get_beatmap( beatmap_id: int | None = None, beatmap_md5: str | None = None, client_ip_address: str | None = Header(None, alias="X-Real-IP"), client_user_agent: str | None = Header(None, alias="User-Agent"), ) -> Response: - #idk if stuff above with get_beatmap is needed + # idk if stuff above with get_beatmap is needed beatmaps = await akatsuki_beatmaps.fetch_all_custom_ranked_beatmaps() - return JSONResponse(content=[AkatsukiBeatmap.model_dump() for AkatsukiBeatmap in beatmaps]) \ No newline at end of file + return JSONResponse( + content=[AkatsukiBeatmap.model_dump() for AkatsukiBeatmap in beatmaps], + ) diff --git a/app/repositories/akatsuki_beatmaps.py b/app/repositories/akatsuki_beatmaps.py index 1ffe472..a8c5dd4 100644 --- a/app/repositories/akatsuki_beatmaps.py +++ b/app/repositories/akatsuki_beatmaps.py @@ -135,7 +135,8 @@ async def fetch_one_by_id(beatmap_id: int, /) -> AkatsukiBeatmap | None: bancho_creator_id=rec["bancho_creator_id"], bancho_creator_name=rec["bancho_creator_name"], ) - + + async def fetch_many_maps_with_custom_akatsuki_status() -> list[AkatsukiBeatmap]: query = """\ SELECT * FROM beatmaps WHERE ranked_status_freezed = 1 ORDER BY lastest_updated @@ -171,9 +172,8 @@ async def fetch_many_maps_with_custom_akatsuki_status() -> list[AkatsukiBeatmap] ) akatsuki_maps_with_custom_status.append(beatmap) return akatsuki_maps_with_custom_status - - - + + async def create_or_replace(beatmap: AkatsukiBeatmap) -> AkatsukiBeatmap: query = """\ REPLACE INTO beatmaps ( diff --git a/app/usecases/akatsuki_beatmaps.py b/app/usecases/akatsuki_beatmaps.py index 3293406..744fd4d 100644 --- a/app/usecases/akatsuki_beatmaps.py +++ b/app/usecases/akatsuki_beatmaps.py @@ -206,6 +206,7 @@ async def fetch_one_by_md5(beatmap_md5: str) -> AkatsukiBeatmap | None: return beatmap + async def fetch_all_custom_ranked_beatmaps() -> list[AkatsukiBeatmap]: beatmaps = await akatsuki_beatmaps.fetch_many_maps_with_custom_akatsuki_status() return beatmaps From 94f40b9a924181d1366585c9b515d09b0d9f4f0c Mon Sep 17 00:00:00 2001 From: Scott Date: Thu, 31 Jul 2025 18:00:49 -0400 Subject: [PATCH 4/5] Applied changes that were mentioned in code review --- app/api/public/akatsuki.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/api/public/akatsuki.py b/app/api/public/akatsuki.py index 1e6d605..b3cc6e4 100644 --- a/app/api/public/akatsuki.py +++ b/app/api/public/akatsuki.py @@ -13,13 +13,7 @@ from app.usecases import akatsuki_beatmaps router = APIRouter(tags=["Akatsuki Beatmaps"]) -@router.get("/api/akatsuki/v1/beatmaps/akatsuki_beatmaps_lookup") #changed name from lookup -async def get_beatmap( - beatmap_id: int | None = None, - beatmap_md5: str | None = None, - client_ip_address: str | None = Header(None, alias="X-Real-IP"), - client_user_agent: str | None = Header(None, alias="User-Agent"), -) -> Response: - #idk if stuff above with get_beatmap is needed +@router.get("/api/akatsuki/v1/beatmaps/custom-ranked-beatmaps") +async def fetch_all_custom_ranked_beatmaps() -> Response: beatmaps = await akatsuki_beatmaps.fetch_all_custom_ranked_beatmaps() return JSONResponse(content=[AkatsukiBeatmap.model_dump() for AkatsukiBeatmap in beatmaps]) \ No newline at end of file From 70e9604ebffe34879b00cc797b041c5d00ffb292 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 22:06:42 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- app/api/public/akatsuki.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/api/public/akatsuki.py b/app/api/public/akatsuki.py index 82b2f40..09f0960 100644 --- a/app/api/public/akatsuki.py +++ b/app/api/public/akatsuki.py @@ -13,6 +13,8 @@ from app.usecases import akatsuki_beatmaps router = APIRouter(tags=["Akatsuki Beatmaps"]) + + @router.get("/api/akatsuki/v1/beatmaps/custom-ranked-beatmaps") async def fetch_all_custom_ranked_beatmaps() -> Response: beatmaps = await akatsuki_beatmaps.fetch_all_custom_ranked_beatmaps()