🚧 wip: update media bulk insert for new schema
This commit is contained in:
@ -2,6 +2,8 @@ import { Prisma } from "@prisma/client";
|
||||
import { AppError } from "../../../helpers/error/instances/app";
|
||||
import { prisma } from "../../../utils/databases/prisma/connection";
|
||||
import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
||||
import { MediaFullInfoResponse } from "../types/mediaFullInfo.type";
|
||||
import { SystemAccountId } from "../../../config/account/system";
|
||||
|
||||
/**
|
||||
* Media Payload Construction and Upsert
|
||||
@ -17,21 +19,100 @@ import { generateUUIDv7 } from "../../../helpers/databases/uuidv7";
|
||||
* @param data - The full media data for constructing the media payload.
|
||||
* @returns The inserted or updated media record.
|
||||
*/
|
||||
export const InsertMediaRepository = async ({
|
||||
malId,
|
||||
payload,
|
||||
}: {
|
||||
malId: number;
|
||||
payload: Omit<Prisma.MediaUncheckedCreateInput, "id">;
|
||||
}) => {
|
||||
export const InsertMediaRepository = async ({ payload }: { payload: MediaFullInfoResponse["data"] }) => {
|
||||
try {
|
||||
return await prisma.media.upsert({
|
||||
where: { malId },
|
||||
update: payload,
|
||||
create: {
|
||||
id: generateUUIDv7(),
|
||||
...payload,
|
||||
const constructMediaPayload: Prisma.MediaUpsertArgs["create"] = {
|
||||
mal_id: payload.mal_id,
|
||||
title: payload.title,
|
||||
title_secondary: payload.title_english,
|
||||
title_original: payload.title_japanese,
|
||||
title_synonyms: payload.title_synonyms,
|
||||
trailer: {
|
||||
connectOrCreate: {
|
||||
where: {
|
||||
embed_url: payload.trailer.embed_url,
|
||||
},
|
||||
create: {
|
||||
embed_url: payload.trailer.embed_url,
|
||||
url: payload.trailer.url,
|
||||
small_image_url: payload.trailer.images.small_image_url,
|
||||
large_image_url: payload.trailer.images.large_image_url,
|
||||
maximum_image_url: payload.trailer.images.maximum_image_url,
|
||||
},
|
||||
},
|
||||
},
|
||||
synopsis: payload.synopsis,
|
||||
small_image_url: payload.images.jpg.small_image_url,
|
||||
medium_image_url: payload.images.jpg.image_url,
|
||||
large_image_url: payload.images.jpg.large_image_url,
|
||||
type: {
|
||||
connectOrCreate: {
|
||||
where: {
|
||||
name: payload.type.toLowerCase(),
|
||||
},
|
||||
create: {
|
||||
name: payload.type.toLowerCase(),
|
||||
},
|
||||
},
|
||||
},
|
||||
source: {
|
||||
connectOrCreate: {
|
||||
where: {
|
||||
name: payload.source.toLowerCase(),
|
||||
},
|
||||
create: {
|
||||
name: payload.source.toLowerCase(),
|
||||
},
|
||||
},
|
||||
},
|
||||
status: {
|
||||
connectOrCreate: {
|
||||
where: {
|
||||
name: payload.status.toLowerCase(),
|
||||
},
|
||||
create: {
|
||||
name: payload.status.toLowerCase(),
|
||||
},
|
||||
},
|
||||
},
|
||||
airing: payload.airing,
|
||||
start_airing: payload.aired.from,
|
||||
end_airing: payload.aired.to,
|
||||
age_rating: {
|
||||
connectOrCreate: {
|
||||
where: {
|
||||
name: payload.rating.toLowerCase(),
|
||||
},
|
||||
create: {
|
||||
name: payload.rating.toLowerCase(),
|
||||
min_age: 0, // Placeholder, as the actual age rating details may require additional mapping
|
||||
},
|
||||
},
|
||||
},
|
||||
score_total: 0,
|
||||
score_count: 0,
|
||||
background: payload.background,
|
||||
season: payload.season,
|
||||
year: payload.year,
|
||||
country: {
|
||||
connectOrCreate: {
|
||||
where: {
|
||||
code: "jpn",
|
||||
},
|
||||
create: {
|
||||
name: "japan",
|
||||
slug: "japan",
|
||||
code: "jpn",
|
||||
},
|
||||
},
|
||||
},
|
||||
broadcast_day: payload.broadcast.day,
|
||||
};
|
||||
|
||||
return await prisma.media.upsert({
|
||||
where: { mal_id: payload.mal_id },
|
||||
create: constructMediaPayload,
|
||||
update: constructMediaPayload,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new AppError(500, "Failed to insert media", error);
|
||||
|
||||
@ -1,61 +1,15 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||
import { bulkInsertGenresRepository } from "../../repositories/bulkInsertGenres.repository";
|
||||
import { InsertMediaRepository } from "../../repositories/bulkinsertMedia.repository";
|
||||
import { bulkInsertStudiosRepository } from "../../repositories/bulkInsertStudios.repository";
|
||||
import { MediaFullInfoResponse } from "../../types/mediaFullInfo.type";
|
||||
import { generateSlug } from "../../../../helpers/characters/generateSlug";
|
||||
import { bulkInsertCharWithVAService } from "../internal/bulkInsertCharWithVA.service";
|
||||
import { generateUUIDv7 } from "../../../../helpers/databases/uuidv7";
|
||||
import { SystemAccountId } from "../../../../config/account/system";
|
||||
import { getContentReferenceAPI } from "../../../../config/apis/jikan/media.reference";
|
||||
|
||||
export const bulkInsertAnimeService = async (malId: number) => {
|
||||
try {
|
||||
const { baseURL, getMediaFullInfo } = getContentReferenceAPI(malId);
|
||||
const mediaFullInfo = (await fetch(baseURL + getMediaFullInfo).then((res) =>
|
||||
res.json(),
|
||||
)) as MediaFullInfoResponse;
|
||||
const mediaFullInfo = (await fetch(baseURL + getMediaFullInfo).then((res) => res.json())) as MediaFullInfoResponse;
|
||||
|
||||
const insertedGenres = await bulkInsertGenresRepository(mediaFullInfo);
|
||||
const insertedStudios = await bulkInsertStudiosRepository(mediaFullInfo);
|
||||
const insertedCharacters = await bulkInsertCharWithVAService(malId);
|
||||
|
||||
const constructMediaPayload: Prisma.MediaUpsertArgs["create"] = {
|
||||
id: generateUUIDv7(),
|
||||
title: mediaFullInfo.data.title,
|
||||
titleAlternative: mediaFullInfo.data
|
||||
.titles as unknown as Prisma.InputJsonValue,
|
||||
slug: await generateSlug(mediaFullInfo.data.title, {
|
||||
model: "media",
|
||||
target: "slug",
|
||||
}),
|
||||
malId: mediaFullInfo.data.mal_id,
|
||||
genres: {
|
||||
connect: insertedGenres.map((id) => ({ id })),
|
||||
},
|
||||
studios: {
|
||||
connect: insertedStudios.map((id) => ({ id })),
|
||||
},
|
||||
characters: {
|
||||
connect: insertedCharacters.map(({ id }) => ({ id })),
|
||||
},
|
||||
score: mediaFullInfo.data.score,
|
||||
pictureMedium: mediaFullInfo.data.images.webp.image_url,
|
||||
pictureLarge: mediaFullInfo.data.images.webp.large_image_url,
|
||||
status: mediaFullInfo.data.status,
|
||||
startAiring: mediaFullInfo.data.aired.from,
|
||||
endAiring: mediaFullInfo.data.aired.to,
|
||||
synopsis: mediaFullInfo.data.synopsis,
|
||||
ageRating: mediaFullInfo.data.rating,
|
||||
mediaType: mediaFullInfo.data.type,
|
||||
source: mediaFullInfo.data.source,
|
||||
onDraft: false,
|
||||
uploadedBy: SystemAccountId,
|
||||
};
|
||||
const insertedMedia = await InsertMediaRepository({
|
||||
malId: mediaFullInfo.data.mal_id,
|
||||
payload: constructMediaPayload,
|
||||
payload: mediaFullInfo.data,
|
||||
});
|
||||
|
||||
return insertedMedia;
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { MediaFullInfoResponse } from "../../types/mediaFullInfo.type";
|
||||
import { prisma } from "../../../../utils/databases/prisma/connection";
|
||||
|
||||
interface InsertedProducer {
|
||||
producer: string[];
|
||||
licensor: string[];
|
||||
studio: string[];
|
||||
}
|
||||
|
||||
export const bulkInsertProducerService = async (payload: MediaFullInfoResponse, systemAccountId: string) => {
|
||||
const insertedPayload: InsertedProducer = {
|
||||
producer: [],
|
||||
licensor: [],
|
||||
studio: [],
|
||||
};
|
||||
|
||||
const insertingMainProducer = await prisma.producer.createMany({
|
||||
data: payload.data.producers.map((producer) => ({
|
||||
mal_id: producer.mal_id,
|
||||
type: producer.type,
|
||||
name: producer.name,
|
||||
url: producer.url,
|
||||
created_by_id: systemAccountId,
|
||||
})),
|
||||
skipDuplicates: true,
|
||||
});
|
||||
};
|
||||
@ -1,4 +1,4 @@
|
||||
import { MediaType } from "@prisma/client";
|
||||
import { media_season } from "@prisma/client";
|
||||
export interface MediaFullInfoResponse {
|
||||
data: Data;
|
||||
}
|
||||
@ -14,7 +14,7 @@ interface Data {
|
||||
title_english: string;
|
||||
title_japanese: string;
|
||||
title_synonyms: string[];
|
||||
type: MediaType;
|
||||
type: string;
|
||||
source: string;
|
||||
episodes: number;
|
||||
status: string;
|
||||
@ -30,7 +30,7 @@ interface Data {
|
||||
favorites: number;
|
||||
synopsis: string;
|
||||
background: string;
|
||||
season: string;
|
||||
season: media_season;
|
||||
year: number;
|
||||
broadcast: Broadcast;
|
||||
producers: Genre[];
|
||||
|
||||
Reference in New Issue
Block a user