From c72230a98d780bf6c06bcf4b45b7d4defb1a14a4 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 17 Oct 2024 16:24:10 +0100 Subject: [PATCH] cache unknown beatsaver maps --- .../backend/src/service/beatsaver.service.ts | 30 ++++++++++++------- projects/backend/src/service/score.service.ts | 30 +++++++++---------- .../src/model/beatsaver/beatsaver-map.ts | 10 +++++-- .../src/components/player/player-scores.tsx | 30 ++++++++++--------- 4 files changed, 57 insertions(+), 43 deletions(-) diff --git a/projects/backend/src/service/beatsaver.service.ts b/projects/backend/src/service/beatsaver.service.ts index 6a4e385..9ff910f 100644 --- a/projects/backend/src/service/beatsaver.service.ts +++ b/projects/backend/src/service/beatsaver.service.ts @@ -11,20 +11,28 @@ export default class BeatSaverService { public static async getMap(hash: string): Promise { let map = await BeatSaverMapModel.findById(hash); if (map != undefined) { - return map.toObject() as BeatSaverMap; + const toObject = map.toObject() as BeatSaverMap; + if (toObject.unknownMap) { + return undefined; + } + return toObject; } const token = await beatsaverService.lookupMap(hash); - if (token == undefined) { - return undefined; - } - map = await BeatSaverMapModel.create({ - _id: hash, - bsr: token.id, - author: { - id: token.uploader.id, - }, - }); + map = await BeatSaverMapModel.create( + token + ? { + _id: hash, + bsr: token.id, + author: { + id: token.uploader.id, + }, + } + : { + _id: hash, + unknownMap: true, + } + ); return map.toObject() as BeatSaverMap; } } diff --git a/projects/backend/src/service/score.service.ts b/projects/backend/src/service/score.service.ts index 758996c..15571ae 100644 --- a/projects/backend/src/service/score.service.ts +++ b/projects/backend/src/service/score.service.ts @@ -91,11 +91,16 @@ export class ScoreService { search: search, }); if (leaderboardScores == undefined) { - throw new NotFoundError( - `No scores found for "${id}", leaderboard "${leaderboardName}", page "${page}", sort "${sort}", search "${search}"` - ); + break; } + metadata = new Metadata( + Math.ceil(leaderboardScores.metadata.total / leaderboardScores.metadata.itemsPerPage), + leaderboardScores.metadata.total, + leaderboardScores.metadata.page, + leaderboardScores.metadata.itemsPerPage + ); + for (const token of leaderboardScores.playerScores) { const score = getScoreSaberScoreFromToken(token.score); if (score == undefined) { @@ -113,13 +118,6 @@ export class ScoreService { beatSaver: beatSaverMap, }); } - - metadata = new Metadata( - Math.ceil(leaderboardScores.metadata.total / leaderboardScores.metadata.itemsPerPage), - leaderboardScores.metadata.total, - leaderboardScores.metadata.page, - leaderboardScores.metadata.itemsPerPage - ); break; } default: { @@ -145,7 +143,7 @@ export class ScoreService { leaderboardName: Leaderboards, id: string, page: number - ): Promise> { + ): Promise> { const scores: Score[] = []; let leaderboard: Leaderboard | undefined; let beatSaverMap: BeatSaverMap | undefined; @@ -153,11 +151,6 @@ export class ScoreService { switch (leaderboardName) { case "scoresaber": { - const leaderboardScores = await scoresaberService.lookupLeaderboardScores(id, page); - if (leaderboardScores == undefined) { - throw new NotFoundError(`No scores found for "${id}", leaderboard "${leaderboardName}", page "${page}""`); - } - const leaderboardResponse = await LeaderboardService.getLeaderboard(leaderboardName, id); if (leaderboardResponse == undefined) { throw new NotFoundError(`Leaderboard "${leaderboardName}" not found`); @@ -165,6 +158,11 @@ export class ScoreService { leaderboard = leaderboardResponse.leaderboard; beatSaverMap = leaderboardResponse.beatsaver; + const leaderboardScores = await scoresaberService.lookupLeaderboardScores(id, page); + if (leaderboardScores == undefined) { + break; + } + for (const token of leaderboardScores.scores) { const score = getScoreSaberScoreFromToken(token); if (score == undefined) { diff --git a/projects/common/src/model/beatsaver/beatsaver-map.ts b/projects/common/src/model/beatsaver/beatsaver-map.ts index e068c59..8cbbfe0 100644 --- a/projects/common/src/model/beatsaver/beatsaver-map.ts +++ b/projects/common/src/model/beatsaver/beatsaver-map.ts @@ -30,15 +30,21 @@ export class BeatSaverMap { * The bsr code for the map. * @private */ - @prop({ required: true }) + @prop({ required: false }) public bsr!: string; /** * The author of the map. */ - @prop({ required: true, _id: false, type: () => BeatsaverAuthor }) + @prop({ required: false, _id: false, type: () => BeatsaverAuthor }) public author!: BeatsaverAuthor; + /** + * True if the map is unknown on beatsaver. + */ + @prop({ required: false }) + public unknownMap?: boolean; + /** * Exposes `id` as a virtual field mapped from `_id`. */ diff --git a/projects/website/src/components/player/player-scores.tsx b/projects/website/src/components/player/player-scores.tsx index ce969bb..0dcf3f3 100644 --- a/projects/website/src/components/player/player-scores.tsx +++ b/projects/website/src/components/player/player-scores.tsx @@ -229,20 +229,22 @@ export default function PlayerScores({ initialScoreData, initialSearch, player, ))} - { - return getUrl(page); - }} - onPageChange={newPage => { - setPreviousPage(pageState.page); - setPageState({ ...pageState, page: newPage }); - setShouldFetch(true); // Set to true to trigger fetch on page change - }} - /> + {scores.metadata.totalPages > 1 && ( + { + return getUrl(page); + }} + onPageChange={newPage => { + setPreviousPage(pageState.page); + setPageState({ ...pageState, page: newPage }); + setShouldFetch(true); // Set to true to trigger fetch on page change + }} + /> + )} )}