319 lines
8.1 KiB
JavaScript
319 lines
8.1 KiB
JavaScript
import { createWriteStream, existsSync, mkdirSync } from "fs";
|
|
import sharp from "sharp";
|
|
import fs from "fs/promises";
|
|
import { pipeline } from "stream";
|
|
import { promisify } from "util";
|
|
const streamPipeline = promisify(pipeline);
|
|
const apiUrl = "https://admin.ceiba-conseil.com";
|
|
|
|
async function fetchJSONApi(path) {
|
|
const url = `${apiUrl}${path}`;
|
|
const options = {
|
|
method: "GET",
|
|
headers: {
|
|
"content-type": "application/json",
|
|
},
|
|
};
|
|
console.log(`fetchJSONApi: ${url}`);
|
|
const response = await fetch(url, options);
|
|
|
|
if (!response.ok) {
|
|
const errors = await response.json();
|
|
throw errors.errors[0].message;
|
|
}
|
|
|
|
return response.json();
|
|
}
|
|
|
|
async function fetchAsset(uuid) {
|
|
const url = `${apiUrl}/assets/${uuid}`;
|
|
return fetch(url);
|
|
}
|
|
|
|
async function fetchScoresData() {
|
|
const fields = [
|
|
"*",
|
|
"translations.*",
|
|
"questions.sort",
|
|
"questions.questions_id.*",
|
|
"questions.questions_id.translations.*",
|
|
"questions.questions_id.answers.*",
|
|
"questions.questions_id.answers.answers_id.*",
|
|
"questions.questions_id.answers.answers_id.translations.*",
|
|
"results.*",
|
|
"results.results_id.*",
|
|
"results.results_id.translations.*",
|
|
];
|
|
const url = `/items/scores?${fields
|
|
.map((item) => `fields[]=${item}`)
|
|
.join("&")}`;
|
|
let scores = (await fetchJSONApi(url)).data;
|
|
if (process.env.NODE_ENV == "production") {
|
|
console.log("Suppresion des scores avec le mode brouillon en production");
|
|
scores = scores.filter((score) => !score.draft);
|
|
} else if (process.env.NODE_ENV == "test") {
|
|
console.log("Suppresion des scores sans l'environnement test");
|
|
scores = scores.filter((score) => score.env_test);
|
|
}
|
|
await fs.writeFile("./src/data.json", JSON.stringify(scores), "utf8");
|
|
|
|
const folder = "public/answers";
|
|
if (!existsSync(folder)) mkdirSync(folder);
|
|
for (const score of scores) {
|
|
const uuid_score = score.image;
|
|
if (uuid_score) {
|
|
console.log(`Score image : ${folder}/${uuid_score}`);
|
|
const response = await fetchAsset(uuid_score);
|
|
try {
|
|
const thumbnail = sharp().resize({ height: 200 }).webp();
|
|
await streamPipeline(
|
|
response.body,
|
|
thumbnail,
|
|
createWriteStream(`${folder}/${uuid_score}.webp`),
|
|
);
|
|
} catch (err) {
|
|
console.log(err);
|
|
}
|
|
}
|
|
for (const question of score.questions) {
|
|
for (const answer of question.questions_id.answers) {
|
|
const uuid = answer.answers_id.image;
|
|
if (uuid) {
|
|
await downloadImage(uuid, `${folder}/${uuid}.webp`, { height: 200 });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// await sharp('src/assets/arbre.png').resize({ width: 440, height: 690 }).webp().toFile('public/arbre.webp')
|
|
}
|
|
|
|
async function transformImage(response, path, options, format = "webp") {
|
|
try {
|
|
let thumbnail;
|
|
console.log(path);
|
|
if (format == "webp") {
|
|
thumbnail = sharp().resize(options).webp();
|
|
} else {
|
|
thumbnail = sharp().resize(options).toFormat("png");
|
|
}
|
|
const stream = createWriteStream(path);
|
|
await streamPipeline(response.body, thumbnail, stream);
|
|
await stream;
|
|
} catch (err) {
|
|
console.log(err);
|
|
}
|
|
}
|
|
|
|
async function downloadImage(uuid, path, options, format = "webp") {
|
|
const response = await fetchAsset(uuid);
|
|
await transformImage(response, path, options, format);
|
|
}
|
|
|
|
async function fetchHomepageData() {
|
|
const fields = ["*"];
|
|
const url = `/items/homepage?${fields
|
|
.map((item) => `fields[]=${item}`)
|
|
.join("&")}`;
|
|
const homepage = (await fetchJSONApi(url)).data;
|
|
|
|
await downloadImage(homepage.image, `public/homepage.webp`, {
|
|
width: 1280,
|
|
height: 720,
|
|
fit: sharp.fit.cover,
|
|
});
|
|
|
|
const favicons = [
|
|
{
|
|
path: `public/favicon/android-icon-192x192.png`,
|
|
options: {
|
|
width: 192,
|
|
height: 192,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-57x57.png`,
|
|
options: {
|
|
width: 57,
|
|
height: 57,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-60x60.png`,
|
|
options: {
|
|
width: 60,
|
|
height: 60,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-72x72.png`,
|
|
options: {
|
|
width: 72,
|
|
height: 72,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-76x76.png`,
|
|
options: {
|
|
width: 76,
|
|
height: 76,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-114x114.png`,
|
|
options: {
|
|
width: 114,
|
|
height: 114,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-120x120.png`,
|
|
options: {
|
|
width: 120,
|
|
height: 120,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-144x144.png`,
|
|
options: {
|
|
width: 144,
|
|
height: 144,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-152x152.png`,
|
|
options: {
|
|
width: 152,
|
|
height: 152,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/apple-icon-180x180.png`,
|
|
options: {
|
|
width: 180,
|
|
height: 180,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/favicon-16x16.png`,
|
|
options: {
|
|
width: 16,
|
|
height: 16,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/favicon-32x32.png`,
|
|
options: {
|
|
width: 32,
|
|
height: 32,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/favicon-96x96.png`,
|
|
options: {
|
|
width: 96,
|
|
height: 96,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/favicon-256x256.png`,
|
|
options: {
|
|
width: 256,
|
|
height: 256,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/ms-icon-70x70.png`,
|
|
options: {
|
|
width: 70,
|
|
height: 70,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/ms-icon-144x144.png`,
|
|
options: {
|
|
width: 144,
|
|
height: 144,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/ms-icon-150x150.png`,
|
|
options: {
|
|
width: 150,
|
|
height: 150,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
{
|
|
path: `public/favicon/ms-icon-310x310.png`,
|
|
options: {
|
|
width: 310,
|
|
height: 310,
|
|
fit: sharp.fit.contain,
|
|
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
|
},
|
|
format: "png",
|
|
},
|
|
];
|
|
for (const favicon of favicons) {
|
|
downloadImage(homepage.logo, favicon.path, favicon.options, favicon.format);
|
|
}
|
|
}
|
|
|
|
async function fetchData() {
|
|
await fetchHomepageData();
|
|
await fetchScoresData();
|
|
}
|
|
|
|
fetchData();
|