mirror of
https://github.com/Floriansylvain/ParisMuseesQuizz.git
synced 2026-08-19 11:43:22 +02:00
Added DB interactions with paintings routes
This commit is contained in:
+201
-18
@@ -1,14 +1,53 @@
|
|||||||
import { PrismaClient } from "@prisma/client"
|
import { PrismaClient, PaintingAuthor, Painting, Author } from "@prisma/client"
|
||||||
import express, { RequestHandler } from "express"
|
import express, { RequestHandler } from "express"
|
||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
import { getPaintingQuery } from "../utils/queries.js"
|
import { getPaintingQuery } from "../utils/queries.js"
|
||||||
|
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
|
|
||||||
const paintingsRouter = express.Router()
|
interface GraphQlPainting {
|
||||||
// const prisma = new PrismaClient()
|
data: {
|
||||||
|
nodeQuery: {
|
||||||
|
entities: {
|
||||||
|
entityUuid: string
|
||||||
|
title: string
|
||||||
|
absolutePath: string
|
||||||
|
fieldOeuvreAuteurs: {
|
||||||
|
entity: {
|
||||||
|
fieldAuteurAuteur: {
|
||||||
|
entity: {
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}[]
|
||||||
|
fieldVisuels: {
|
||||||
|
entity: {
|
||||||
|
publicUrl: string
|
||||||
|
}
|
||||||
|
}[]
|
||||||
|
fieldMusee: {
|
||||||
|
entity: {
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const paintingParser = z
|
interface ParsedPainting {
|
||||||
|
image_url: string
|
||||||
|
name: string
|
||||||
|
link: string
|
||||||
|
musuem: string
|
||||||
|
author: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const paintingsRouter = express.Router()
|
||||||
|
const prisma = new PrismaClient()
|
||||||
|
|
||||||
|
const paintingParamsParser = z
|
||||||
.object({
|
.object({
|
||||||
uuid: z.string(),
|
uuid: z.string(),
|
||||||
})
|
})
|
||||||
@@ -20,7 +59,18 @@ const randomParser = z
|
|||||||
})
|
})
|
||||||
.required()
|
.required()
|
||||||
|
|
||||||
async function fetchPainting(uuid: string): Promise<unknown> {
|
function parseGraphQlPainting(painting: GraphQlPainting): ParsedPainting {
|
||||||
|
const graphQlPainting = painting.data.nodeQuery.entities[0]
|
||||||
|
return {
|
||||||
|
image_url: graphQlPainting.fieldVisuels[0].entity.publicUrl,
|
||||||
|
name: graphQlPainting.title,
|
||||||
|
link: graphQlPainting.absolutePath,
|
||||||
|
musuem: graphQlPainting.fieldMusee.entity.name,
|
||||||
|
author: graphQlPainting.fieldOeuvreAuteurs[0].entity.fieldAuteurAuteur.entity.name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchPainting(uuid: string): Promise<GraphQlPainting> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fetch("https://apicollections.parismusees.paris.fr/graphql", {
|
fetch("https://apicollections.parismusees.paris.fr/graphql", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -35,32 +85,165 @@ async function fetchPainting(uuid: string): Promise<unknown> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getRandomPaintings(limit: number): Promise<unknown[]> {
|
async function getRandomPaintings(limit: number): Promise<(Painting | null)[]> {
|
||||||
const paintingsUUIDs = JSON.parse(
|
const paintingsUUIDs = JSON.parse(fs.readFileSync("src/assets/paintingsUUID.json", "utf8"))
|
||||||
fs.readFileSync("src/assets/paintingsUUID.json", "utf8")
|
const randomUUIDs = paintingsUUIDs.paintings.sort(() => Math.random() - 0.5).slice(0, limit)
|
||||||
)
|
|
||||||
const randomUUIDs = paintingsUUIDs.paintings
|
|
||||||
.sort(() => Math.random() - 0.5)
|
|
||||||
.slice(0, limit)
|
|
||||||
|
|
||||||
const paintings = []
|
const paintings = []
|
||||||
for (const uuid of randomUUIDs) {
|
for (const uuid of randomUUIDs) {
|
||||||
const painting = await fetchPainting(uuid)
|
const fetchedPainting = await fetchPainting(uuid)
|
||||||
paintings.push(painting)
|
const parsedPainting = parseGraphQlPainting(fetchedPainting)
|
||||||
|
|
||||||
|
const painting = await getPainting(undefined, parsedPainting.name)
|
||||||
|
if (!painting) {
|
||||||
|
const createdPaintingAuthor = await createPainting(parsedPainting)
|
||||||
|
paintings.push(await getPainting(createdPaintingAuthor.painting_id, undefined))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
await updatePaintingIfNeeded(painting, parsedPainting)
|
||||||
|
paintings.push(await getPainting(undefined, parsedPainting.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
return paintings
|
return paintings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function createPainting(painting: ParsedPainting): Promise<PaintingAuthor> {
|
||||||
|
return await prisma.paintingAuthor.create({
|
||||||
|
data: {
|
||||||
|
painting: {
|
||||||
|
create: {
|
||||||
|
image_url: painting.image_url,
|
||||||
|
name: painting.name,
|
||||||
|
link: painting.link,
|
||||||
|
Musuem: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
name: painting.musuem,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
name: painting.musuem,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
fullname: painting.author,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
fullname: painting.author,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPainting(id?: number, name?: string): Promise<Painting | null> {
|
||||||
|
if (!id && !name) return null
|
||||||
|
|
||||||
|
return await prisma.painting.findUnique({
|
||||||
|
where: id ? { id } : { name },
|
||||||
|
include: { PaintingAuthor: { select: { author: true } } },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPaintingAuthors(paintingId: number): Promise<(Author | null)[]> {
|
||||||
|
const paintingAuthors = (
|
||||||
|
await prisma.painting.findUnique({
|
||||||
|
where: { id: paintingId },
|
||||||
|
include: { PaintingAuthor: true },
|
||||||
|
})
|
||||||
|
)?.PaintingAuthor
|
||||||
|
|
||||||
|
if (!paintingAuthors) return []
|
||||||
|
|
||||||
|
const authors = []
|
||||||
|
|
||||||
|
for (const paintingAuthor of paintingAuthors) {
|
||||||
|
const author = await prisma.author.findUnique({
|
||||||
|
where: { id: paintingAuthor.author_id },
|
||||||
|
})
|
||||||
|
authors.push(author)
|
||||||
|
}
|
||||||
|
|
||||||
|
return authors
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updatePainting(id: number, painting: ParsedPainting): Promise<Painting> {
|
||||||
|
return await prisma.painting.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
image_url: painting.image_url,
|
||||||
|
name: painting.name,
|
||||||
|
link: painting.link,
|
||||||
|
Musuem: {
|
||||||
|
connectOrCreate: {
|
||||||
|
where: {
|
||||||
|
name: painting.musuem,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
name: painting.musuem,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updatePaintingIfNeeded(
|
||||||
|
painting: Painting,
|
||||||
|
parsedPainting: ParsedPainting
|
||||||
|
): Promise<void> {
|
||||||
|
const paintingMusuem = (
|
||||||
|
await prisma.painting.findUnique({
|
||||||
|
where: {
|
||||||
|
id: painting.id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
Musuem: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)?.Musuem
|
||||||
|
const paintingAuthors = await getPaintingAuthors(painting.id)
|
||||||
|
|
||||||
|
if (
|
||||||
|
painting.image_url !== parsedPainting.image_url ||
|
||||||
|
painting.name !== parsedPainting.name ||
|
||||||
|
painting.link !== parsedPainting.link ||
|
||||||
|
paintingMusuem?.name !== parsedPainting.musuem ||
|
||||||
|
paintingAuthors?.[0]?.fullname !== parsedPainting.author
|
||||||
|
) {
|
||||||
|
updatePainting(painting.id, parsedPainting)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const paintingRouterGet: RequestHandler = async (req, res) => {
|
const paintingRouterGet: RequestHandler = async (req, res) => {
|
||||||
const parsedPainting = paintingParser.safeParse(req.params)
|
const parsedPaintingParams = paintingParamsParser.safeParse(req.params)
|
||||||
if (!parsedPainting.success) {
|
if (!parsedPaintingParams.success) {
|
||||||
res.status(400).send({ message: "Please provide valid painting UUID." })
|
res.status(400).send({ message: "Please provide valid painting UUID." })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const painting = await fetchPainting(parsedPainting.data.uuid)
|
const fetchedPainting = await fetchPainting(parsedPaintingParams.data.uuid)
|
||||||
res.send({ painting })
|
const parsedPainting = parseGraphQlPainting(fetchedPainting)
|
||||||
|
|
||||||
|
const painting = await getPainting(undefined, parsedPainting.name)
|
||||||
|
if (!painting) {
|
||||||
|
const createdPaintingAuthor = await createPainting(parsedPainting)
|
||||||
|
res.send({ painting: await getPainting(createdPaintingAuthor.painting_id, undefined) })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await updatePaintingIfNeeded(painting, parsedPainting)
|
||||||
|
|
||||||
|
res.send({ painting: await getPainting(undefined, parsedPainting.name) })
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const paintingRouterGetRandoms: RequestHandler = async (req, res) => {
|
const paintingRouterGetRandoms: RequestHandler = async (req, res) => {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ export function getPaintingQuery(uuid: string) {
|
|||||||
... on NodeOeuvre {
|
... on NodeOeuvre {
|
||||||
title
|
title
|
||||||
absolutePath
|
absolutePath
|
||||||
fieldUrlAlias
|
|
||||||
fieldOeuvreAuteurs {
|
fieldOeuvreAuteurs {
|
||||||
entity {
|
entity {
|
||||||
fieldAuteurAuteur {
|
fieldAuteurAuteur {
|
||||||
@@ -22,7 +21,6 @@ export function getPaintingQuery(uuid: string) {
|
|||||||
fieldVisuels {
|
fieldVisuels {
|
||||||
entity {
|
entity {
|
||||||
name
|
name
|
||||||
vignette
|
|
||||||
publicUrl
|
publicUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user