From 588970e18c6787581a4bead1f6c4dc9bb07e4af3 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sat, 15 Jun 2024 20:50:22 +0200 Subject: [PATCH] Implemented incremental pagination when no images are valid --- src/services/gelbooruApiService.ts | 5 ++-- src/services/imageService.ts | 44 +++++++++++++++++------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/services/gelbooruApiService.ts b/src/services/gelbooruApiService.ts index 9e5b151..6a76fad 100644 --- a/src/services/gelbooruApiService.ts +++ b/src/services/gelbooruApiService.ts @@ -6,8 +6,9 @@ import GelbooruServiceResponse from "src/types/GelbooruServiceResponse"; export const LIMIT = env.GELBOORU_IMAGES_PER_REQUEST || 100; export const TAGS = encodeURIComponent(env.GELBOORU_TAGS || ""); -export async function get(): Promise { - const url: string = `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=${LIMIT}&json=1&tags=${TAGS}`; +export async function get(pid?: number): Promise { + const pidQueryParam = pid ? `&pid=${pid}` : ""; + const url: string = `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=${LIMIT}&json=1&tags=${TAGS}${pidQueryParam}`; const response: GelbooruApiResponse = (await fetch(url).then( async (res) => { diff --git a/src/services/imageService.ts b/src/services/imageService.ts index ea20d53..3cf9a4d 100644 --- a/src/services/imageService.ts +++ b/src/services/imageService.ts @@ -2,22 +2,21 @@ import GelbooruServiceResponse from "src/types/GelbooruServiceResponse"; import Image from "src/types/Image"; import logger from "src/logger"; import { Mutex } from "async-mutex"; -import * as gelbooruApiService from 'src/services/gelbooruApiService'; -import * as botApiService from 'src/services/botApiService'; +import * as gelbooruApiService from "src/services/gelbooruApiService"; +import * as botApiService from "src/services/botApiService"; const mutex: Mutex = new Mutex(); const postsQueue: Image[] = []; // We wrap the function into a Mutex because it's not thread-safe export async function get(): Promise { - return await mutex.runExclusive(() => unsafeGet()) + return await mutex.runExclusive(() => unsafeGet()); } async function unsafeGet(): Promise { - while (postsQueue.length === 0) { - const validPosts = await getNewValidImages(); - validPosts.map(post => postsQueue.push(post)); - logger.info(`Got ${validPosts.length} images from remote`); + if (postsQueue.length === 0) { + const validPosts = await getNewImages(); + validPosts.map((post) => postsQueue.push(post)); } return popImage(); } @@ -25,27 +24,34 @@ async function unsafeGet(): Promise { function popImage(): Image { const image = postsQueue.pop(); if (image) { - return image + return image; } else { throw Error("Can't pop from an empty list"); } } -async function getNewValidImages(): Promise { - const gelbooruResponse: GelbooruServiceResponse = - await gelbooruApiService.get(); - const posts = gelbooruResponse.posts; +/** + * Returns an array of images that are not present in the bot database + */ +async function getNewImages(): Promise { + for (let pageId = 0; ; pageId++) { + const gelbooruResponse: GelbooruServiceResponse = + await gelbooruApiService.get(pageId); + const posts = gelbooruResponse.posts; - const botResponse = await botApiService.getAll(); - const imagesUrls = botResponse.images.map((image) => image.url); + const botResponse = await botApiService.getAll(); + const imagesUrls = botResponse.images.map((image) => image.url); - const validPosts = Promise.all( - posts + const validPosts = posts .filter((post) => !imagesUrls.some((url) => url === post.url)) .map((post): Image => { return { url: post.url, tags: post.tags }; - }) - ); + }); - return validPosts; + logger.info(`Got ${validPosts.length} valid images from remote`); + + if (validPosts.length > 0) { + return validPosts; + } + } }