json_server_myapps/server/appMetadata.js
2026-01-27 12:51:43 +01:00

132 lines
3.7 KiB
JavaScript

// appMetadata.js
import axios from "axios";
import * as cheerio from "cheerio";
import sizeOf from "image-size";
import sharp from "sharp";
export async function getAppMetadata(baseUrl) {
console.log(baseUrl);
try {
const res = await axios.get(baseUrl, { timeout: 3000 });
const $ = cheerio.load(res.data);
// -------------------------------
// 1. Nome più corto
// -------------------------------
const nameCandidates = [
$('meta[property="og:site_name"]').attr("content"),
$('meta[name="application-name"]').attr("content"),
$('meta[property="og:title"]').attr("content"),
$("title").text().trim()
].filter(Boolean);
const name = nameCandidates.length > 0
? nameCandidates.sort((a, b) => a.length - b.length)[0]
: "no_name";
// -------------------------------
// 2. Icone HTML
// -------------------------------
const htmlIcons = [];
$("link[rel*='icon']").each((_, el) => {
const href = $(el).attr("href");
const sizes = $(el).attr("sizes") || "";
if (href) htmlIcons.push({ href, sizes });
});
// -------------------------------
// 3. Manifest.json
// -------------------------------
let manifestIcons = [];
const manifestHref = $('link[rel="manifest"]').attr("href");
if (manifestHref) {
try {
const manifestUrl = new URL(manifestHref, baseUrl).href;
const manifestRes = await axios.get(manifestUrl, { timeout: 3000 });
const manifest = manifestRes.data;
if (manifest.icons && Array.isArray(manifest.icons)) {
manifestIcons = manifest.icons.map(icon => ({
href: icon.src,
sizes: icon.sizes || ""
}));
}
} catch {}
}
// -------------------------------
// 4. Fallback 4 icone
// -------------------------------
const fallbackPaths = [
"/favicon.ico",
"/favicon.png",
"/icon.png",
"/apple-touch-icon.png"
];
const fallbackIcons = fallbackPaths.map(p => ({
href: p,
sizes: ""
}));
// -------------------------------
// 5. Unisci tutte le icone
// -------------------------------
const allIcons = [...htmlIcons, ...manifestIcons, ...fallbackIcons];
// -------------------------------
// 6. Determina dimensione reale (PNG, ICO, SVG)
// -------------------------------
const iconsWithRealSize = [];
for (const icon of allIcons) {
try {
const url = new URL(icon.href, baseUrl).href;
const imgRes = await axios.get(url, { responseType: "arraybuffer" });
let width = 0;
// ---- PNG / JPG / ICO ----
try {
const dim = sizeOf(imgRes.data);
if (dim.width) width = dim.width;
} catch {
// Non è un formato supportato da image-size
}
// ---- SVG → converti in PNG e misura ----
if (width === 0) {
try {
const pngBuffer = await sharp(imgRes.data).png().toBuffer();
const dim = sizeOf(pngBuffer);
if (dim.width) width = dim.width;
} catch {
// SVG non convertibile → ignora
}
}
if (width > 0) {
iconsWithRealSize.push({ url, size: width });
}
} catch {
// icona non accessibile → ignora
}
}
// -------------------------------
// 7. Scegli la più grande
// -------------------------------
iconsWithRealSize.sort((a, b) => b.size - a.size);
const icon = iconsWithRealSize.length > 0
? iconsWithRealSize[0].url
: null;
return { name, icon };
} catch {
return { name: "no_name", icon: null };
}
}