fe-middleware/src/services/imageService.ts

52 lines
1.5 KiB
TypeScript

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';
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<Image> {
return await mutex.runExclusive(() => unsafeGet())
}
async function unsafeGet(): Promise<Image> {
while (postsQueue.length === 0) {
const validPosts = await getNewValidImages();
validPosts.map(post => postsQueue.push(post));
logger.info(`Got ${validPosts.length} images from remote`);
}
return popImage();
}
function popImage(): Image {
const image = postsQueue.pop();
if (image) {
return image
} else {
throw Error("Can't pop from an empty list");
}
}
async function getNewValidImages(): Promise<Image[]> {
const gelbooruResponse: GelbooruServiceResponse =
await gelbooruApiService.get();
const posts = gelbooruResponse.posts;
const botResponse = await botApiService.getAll();
const imagesUrls = botResponse.images.map((image) => image.url);
const validPosts = Promise.all(
posts
.filter((post) => !imagesUrls.some((url) => url === post.url))
.map((post): Image => {
return { url: post.url, tags: post.tags };
})
);
return validPosts;
}