🚧 wip: try to create character with VA in bulk
This commit is contained in:
@ -77,6 +77,37 @@ Table studios {
|
|||||||
medias medias [not null]
|
medias medias [not null]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Table characters {
|
||||||
|
id String [pk]
|
||||||
|
malId Int [unique, not null]
|
||||||
|
name String [not null]
|
||||||
|
role CharacterRole [not null]
|
||||||
|
favorites Int [not null, default: 0]
|
||||||
|
imageUrl String
|
||||||
|
smallImageUrl String
|
||||||
|
createdBy users [not null]
|
||||||
|
creatorId String [not null]
|
||||||
|
deletedAt DateTime
|
||||||
|
createdAt DateTime [default: `now()`, not null]
|
||||||
|
updatedAt DateTime [default: `now()`, not null]
|
||||||
|
}
|
||||||
|
|
||||||
|
Table voice_actors {
|
||||||
|
id String [pk]
|
||||||
|
malId Int [unique, not null]
|
||||||
|
name String [not null]
|
||||||
|
birthday DateTime
|
||||||
|
description String [not null]
|
||||||
|
aboutUrl String [not null]
|
||||||
|
imageUrl String
|
||||||
|
websiteUrl String
|
||||||
|
createdBy users [not null]
|
||||||
|
creatorId String [not null]
|
||||||
|
deletedAt DateTime
|
||||||
|
createdAt DateTime [default: `now()`, not null]
|
||||||
|
updatedAt DateTime [default: `now()`, not null]
|
||||||
|
}
|
||||||
|
|
||||||
Table episodes {
|
Table episodes {
|
||||||
id String [pk]
|
id String [pk]
|
||||||
media medias [not null]
|
media medias [not null]
|
||||||
@ -172,6 +203,8 @@ Table users {
|
|||||||
media_approveds media_logs [not null]
|
media_approveds media_logs [not null]
|
||||||
genres genres [not null]
|
genres genres [not null]
|
||||||
studios studios [not null]
|
studios studios [not null]
|
||||||
|
characters characters [not null]
|
||||||
|
voice_actor voice_actors [not null]
|
||||||
episodes episodes [not null]
|
episodes episodes [not null]
|
||||||
episode_likes episode_likes [not null]
|
episode_likes episode_likes [not null]
|
||||||
videos videos [not null]
|
videos videos [not null]
|
||||||
@ -501,6 +534,11 @@ Enum Country {
|
|||||||
KR
|
KR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Enum CharacterRole {
|
||||||
|
Main
|
||||||
|
Supporting
|
||||||
|
}
|
||||||
|
|
||||||
Enum MediaOperation {
|
Enum MediaOperation {
|
||||||
create
|
create
|
||||||
update
|
update
|
||||||
@ -605,6 +643,10 @@ Ref: genres.createdBy > users.id
|
|||||||
|
|
||||||
Ref: studios.createdBy > users.id
|
Ref: studios.createdBy > users.id
|
||||||
|
|
||||||
|
Ref: characters.creatorId > users.id
|
||||||
|
|
||||||
|
Ref: voice_actors.creatorId > users.id
|
||||||
|
|
||||||
Ref: episodes.mediaId > medias.id
|
Ref: episodes.mediaId > medias.id
|
||||||
|
|
||||||
Ref: episodes.uploadedBy > users.id
|
Ref: episodes.uploadedBy > users.id
|
||||||
|
|||||||
@ -111,24 +111,25 @@ model Studio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Character {
|
model Character {
|
||||||
id String @id @default(uuid()) @db.Uuid
|
id String @id @default(uuid()) @db.Uuid
|
||||||
name String
|
malId Int @unique
|
||||||
role CharacterRole
|
name String
|
||||||
favorites Int @default(0)
|
role CharacterRole
|
||||||
imageUrl String?
|
favorites Int @default(0)
|
||||||
|
imageUrl String?
|
||||||
smallImageUrl String?
|
smallImageUrl String?
|
||||||
createdBy User @relation("UserCreatedCharacters", fields: [creatorId], references: [id])
|
createdBy User @relation("UserCreatedCharacters", fields: [creatorId], references: [id])
|
||||||
creatorId String
|
creatorId String
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
|
|
||||||
@@map("characters")
|
@@map("characters")
|
||||||
}
|
}
|
||||||
|
|
||||||
model VoiceActor {
|
model VoiceActor {
|
||||||
id String @id @default(uuid()) @db.Uuid
|
id String @id @default(uuid()) @db.Uuid
|
||||||
malId Int
|
malId Int @unique
|
||||||
name String
|
name String
|
||||||
birthday DateTime?
|
birthday DateTime?
|
||||||
description String @db.Text
|
description String @db.Text
|
||||||
|
|||||||
@ -2,5 +2,6 @@ export const getContentReferenceAPI = (malId: number) => {
|
|||||||
return {
|
return {
|
||||||
baseURL: "https://api.jikan.moe/v4",
|
baseURL: "https://api.jikan.moe/v4",
|
||||||
getMediaFullInfo: `/anime/${malId}/full`,
|
getMediaFullInfo: `/anime/${malId}/full`,
|
||||||
|
getMediaCharactersWithVA: `/anime/${malId}/characters`,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,12 +2,14 @@ import { Context } from "elysia";
|
|||||||
import { mainErrorHandler } from "../../../helpers/error/handler";
|
import { mainErrorHandler } from "../../../helpers/error/handler";
|
||||||
import { bulkInsertAnimeService } from "../services/bulkInsertAnime.service";
|
import { bulkInsertAnimeService } from "../services/bulkInsertAnime.service";
|
||||||
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
import { returnWriteResponse } from "../../../helpers/callback/httpResponse";
|
||||||
|
import { bulkInsertCharWithVAService } from "../services/internal/bulkInsertCharWithVA.service";
|
||||||
|
|
||||||
export const bulkInsertAnimeController = async (
|
export const bulkInsertAnimeController = async (
|
||||||
ctx: Context & { body: { mal_id: number } },
|
ctx: Context & { body: { mal_id: number } },
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const bulkInsertResult = await bulkInsertAnimeService(ctx.body.mal_id);
|
// const bulkInsertResult = await bulkInsertAnimeService(ctx.body.mal_id);
|
||||||
|
const bulkInsertResult = await bulkInsertCharWithVAService(ctx.body.mal_id);
|
||||||
return returnWriteResponse(
|
return returnWriteResponse(
|
||||||
ctx.set,
|
ctx.set,
|
||||||
201,
|
201,
|
||||||
|
|||||||
19
src/modules/internal/repositories/bulkInsertVA.repository.ts
Normal file
19
src/modules/internal/repositories/bulkInsertVA.repository.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
import { AppError } from "../../../helpers/error/instances/app";
|
||||||
|
import { prisma } from "../../../utils/databases/prisma/connection";
|
||||||
|
|
||||||
|
export const bulkInsertVARepository = async (
|
||||||
|
payload: Prisma.VoiceActorUpsertArgs["create"],
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const insertedVA = await prisma.voiceActor.upsert({
|
||||||
|
where: { malId: payload.malId },
|
||||||
|
create: payload,
|
||||||
|
update: payload,
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
return insertedVA.id;
|
||||||
|
} catch (error) {
|
||||||
|
throw new AppError(500, "Failed to bulk insert VAs", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -2,7 +2,7 @@ import { Prisma } from "@prisma/client";
|
|||||||
import { getContentReferenceAPI } from "../../../config/apis/media.reference";
|
import { getContentReferenceAPI } from "../../../config/apis/media.reference";
|
||||||
import { ErrorForwarder } from "../../../helpers/error/instances/forwarder";
|
import { ErrorForwarder } from "../../../helpers/error/instances/forwarder";
|
||||||
import { bulkInsertGenresRepository } from "../repositories/bulkInsertGenres.repository";
|
import { bulkInsertGenresRepository } from "../repositories/bulkInsertGenres.repository";
|
||||||
import { InsertMediaRepository } from "../repositories/bulkinsertMediaa.repository";
|
import { InsertMediaRepository } from "../repositories/bulkinsertMedia.repository";
|
||||||
import { bulkInsertStudiosRepository } from "../repositories/bulkInsertStudios.repository";
|
import { bulkInsertStudiosRepository } from "../repositories/bulkInsertStudios.repository";
|
||||||
import { MediaFullInfoResponse } from "../types/mediaFullInfo.type";
|
import { MediaFullInfoResponse } from "../types/mediaFullInfo.type";
|
||||||
import { generateSlug } from "../../../helpers/characters/generateSlug";
|
import { generateSlug } from "../../../helpers/characters/generateSlug";
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
import { getContentReferenceAPI } from "../../../../config/apis/media.reference";
|
||||||
|
import { ErrorForwarder } from "../../../../helpers/error/instances/forwarder";
|
||||||
|
import { MediaCharWithVAInfo } from "../../types/mediaCharWithVAInfo";
|
||||||
|
|
||||||
|
export const bulkInsertCharWithVAService = async (malId: number) => {
|
||||||
|
try {
|
||||||
|
const { baseURL, getMediaCharactersWithVA } = getContentReferenceAPI(malId);
|
||||||
|
const charactersWithVAData = (await fetch(
|
||||||
|
`${baseURL}${getMediaCharactersWithVA}`,
|
||||||
|
).then((res) => res.json())) as MediaCharWithVAInfo;
|
||||||
|
|
||||||
|
return;
|
||||||
|
} catch (error) {
|
||||||
|
ErrorForwarder(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
59
src/modules/internal/types/mediaCharWithVAInfo.ts
Normal file
59
src/modules/internal/types/mediaCharWithVAInfo.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
export interface MediaCharWithVAInfo {
|
||||||
|
data: Datum[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Datum {
|
||||||
|
character: Character;
|
||||||
|
role: Role;
|
||||||
|
favorites: number;
|
||||||
|
voice_actors: VoiceActor[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Character {
|
||||||
|
mal_id: number;
|
||||||
|
url: string;
|
||||||
|
images: CharacterImages;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CharacterImages {
|
||||||
|
jpg: Jpg;
|
||||||
|
webp: Webp;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Jpg {
|
||||||
|
image_url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Webp {
|
||||||
|
image_url: string;
|
||||||
|
small_image_url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Role {
|
||||||
|
Main = "Main",
|
||||||
|
Supporting = "Supporting",
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VoiceActor {
|
||||||
|
person: Person;
|
||||||
|
language: Language;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Language {
|
||||||
|
English = "English",
|
||||||
|
Japanese = "Japanese",
|
||||||
|
PortugueseBR = "Portuguese (BR)",
|
||||||
|
Spanish = "Spanish",
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Person {
|
||||||
|
mal_id: number;
|
||||||
|
url: string;
|
||||||
|
images: PersonImages;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PersonImages {
|
||||||
|
jpg: Jpg;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user