feat: add automatic thumbnail generation
All checks were successful
Integration Tests / integration-tests (pull_request) Successful in 57s

This commit is contained in:
2026-02-05 20:59:34 +07:00
parent dea8c6b7ce
commit 745fd213f9
6 changed files with 115 additions and 0 deletions

View File

@ -0,0 +1,3 @@
import { prisma } from "../../utils/databases/prisma/connection";
export const episodeModel = prisma.episode;

View File

@ -0,0 +1,18 @@
import { Prisma } from "@prisma/client";
import { AppError } from "../../../../helpers/error/instances/app";
import { episodeModel } from "../../episode.model";
export const updateEpisodeRepository = async (
payload: Prisma.EpisodeUncheckedUpdateInput,
) => {
try {
return await episodeModel.update({
where: {
id: payload.id as string,
},
data: payload,
});
} catch (error) {
throw new AppError(500, "Failed to edit episode", error);
}
};

View File

@ -0,0 +1,21 @@
import { Context } from "elysia";
import { mainErrorHandler } from "../../../helpers/error/handler";
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
import { updateAllEpisodeThumbnailService } from "../services/http/updateAllEpisodeThumbnail.service";
export const updateAllEpisodeThumbnailController = async (
ctx: Context & { body: { service_reference_id: string } },
) => {
try {
const newEpisodeThumbnailsCount = await updateAllEpisodeThumbnailService(
ctx.body.service_reference_id,
);
return returnWriteResponse(
ctx.set,
204,
`Updating ${newEpisodeThumbnailsCount} episode thumbnails successfully.`,
);
} catch (error) {
return mainErrorHandler(ctx.set, error);
}
};

View File

@ -3,9 +3,11 @@ import { bulkInsertEpisodeController } from "./controllers/bulkInsertEpisode.con
import { bulkInsertMediaController } from "./controllers/bulkInsertMedia.controller"; import { bulkInsertMediaController } from "./controllers/bulkInsertMedia.controller";
import { createVideoServiceInternalController } from "./controllers/createVideoService.controller"; import { createVideoServiceInternalController } from "./controllers/createVideoService.controller";
import { bulkInsertVideoController } from "./controllers/bulkInsertVideo.controller"; import { bulkInsertVideoController } from "./controllers/bulkInsertVideo.controller";
import { updateAllEpisodeThumbnailController } from "./controllers/updateAllEpisodeThumbnail.controller";
export const internalModule = new Elysia({ prefix: "/internal" }) export const internalModule = new Elysia({ prefix: "/internal" })
.post("/media/bulk-insert", bulkInsertMediaController) .post("/media/bulk-insert", bulkInsertMediaController)
.post("/episode/bulk-insert", bulkInsertEpisodeController) .post("/episode/bulk-insert", bulkInsertEpisodeController)
.post("/episode/update-thumbnails", updateAllEpisodeThumbnailController)
.post("/video/bulk-insert", bulkInsertVideoController) .post("/video/bulk-insert", bulkInsertVideoController)
.post("/video-service", createVideoServiceInternalController); .post("/video-service", createVideoServiceInternalController);

View File

@ -0,0 +1,34 @@
import { AppError } from "../../../helpers/error/instances/app";
import { prisma } from "../../../utils/databases/prisma/connection";
export const getAllEpisodeWithThumbnailLinkRepository = async (
serviceReferenceId: string,
) => {
try {
return await prisma.episode.findMany({
where: {
deletedAt: null,
},
select: {
id: true,
episode: true,
videos: {
where: {
deletedAt: null,
serviceId: serviceReferenceId,
},
select: {
code: true,
service: {
select: {
endpointThumbnail: true,
},
},
},
},
},
});
} catch (error) {
throw new AppError(500, "Failed to update all episode thumbnails", error);
}
};

View File

@ -0,0 +1,37 @@
import { AppError } from "../../../../helpers/error/instances/app";
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
import { updateEpisodeRepository } from "../../../episode/repositories/PUT/updateEpisode.repository";
import { getAllEpisodeWithThumbnailLinkRepository } from "../../repositories/getAllEpisodeWithThumbnailLink.repository";
export const updateAllEpisodeThumbnailService = async (
serviceReferenceId: string,
) => {
try {
if (!serviceReferenceId)
throw new AppError(400, "Service Reference ID is required.");
const episodesData = await getAllEpisodeWithThumbnailLinkRepository(
serviceReferenceId,
);
console.log("episodesData", episodesData);
let updatedThumbnailsCount = 0;
for (const episode of episodesData) {
if (episode.videos.length === 0) continue;
await updateEpisodeRepository({
id: episode.id,
pictureThumbnail:
episode.videos[0].service.endpointThumbnail?.replace(
":code:",
episode.videos[0].code,
) || null,
});
updatedThumbnailsCount++;
}
return updatedThumbnailsCount;
} catch (error) {
ErrorForwarder(error);
}
};