113 lines
3.2 KiB
JavaScript
113 lines
3.2 KiB
JavaScript
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
|
const loadConfig = async () => {
|
|
const configUrl = new URL("../config.local.json", import.meta.url);
|
|
try {
|
|
const raw = await readFile(configUrl, "utf-8");
|
|
return JSON.parse(raw);
|
|
} catch {
|
|
return {};
|
|
}
|
|
};
|
|
|
|
const sanitizeFileName = (value) => {
|
|
const normalized = value
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, "-")
|
|
.replace(/^-+|-+$/g, "");
|
|
return normalized || "spiel";
|
|
};
|
|
|
|
const fetchGogGames = async ({ userId, accessToken }) => {
|
|
if (!userId || !accessToken) {
|
|
console.warn("⚠️ GOG: Keine Credentials - Überspringe");
|
|
console.log(" → Für iOS/Web: Backend mit OAuth benötigt");
|
|
console.log(" → Development: Token aus Browser DevTools kopieren\n");
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
// GOG Galaxy Library API (wie Heroic Launcher)
|
|
const url = `https://galaxy-library.gog.com/users/${userId}/releases`;
|
|
const response = await fetch(url, {
|
|
headers: {
|
|
Authorization: `Bearer ${accessToken}`,
|
|
"User-Agent": "WhatToPlay/1.0",
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`GOG API Fehler: ${response.status}`);
|
|
}
|
|
|
|
const payload = await response.json();
|
|
|
|
// Galaxy API gibt items zurück, nicht owned
|
|
return payload.items || [];
|
|
} catch (error) {
|
|
console.error("GOG API-Aufruf fehlgeschlagen:", error.message);
|
|
console.log("💡 Tipp: Token abgelaufen? Neu aus gog.com holen\n");
|
|
return [];
|
|
}
|
|
};
|
|
|
|
const buildGogEntry = (game) => ({
|
|
// Galaxy Library API gibt external_id (GOG Product ID)
|
|
id: String(game.external_id || game.id),
|
|
title: game.title || `GOG Game ${game.external_id}`,
|
|
platform: "PC",
|
|
lastPlayed: game.date_created
|
|
? new Date(game.date_created * 1000).toISOString()
|
|
: null,
|
|
playtimeHours: 0, // Galaxy API hat keine Spielzeit in /releases endpoint
|
|
tags: [],
|
|
url: `https://www.gog.com/game/${game.external_id}`,
|
|
});
|
|
|
|
const buildTextFile = (entry) => {
|
|
const lines = [
|
|
`Titel: ${entry.title}`,
|
|
`GOG ID: ${entry.id}`,
|
|
`Zuletzt gespielt: ${entry.lastPlayed ?? "-"}`,
|
|
`Spielzeit (h): ${entry.playtimeHours ?? 0}`,
|
|
`Store: ${entry.url}`,
|
|
"Quelle: gog",
|
|
];
|
|
return lines.join("\n") + "\n";
|
|
};
|
|
|
|
const writeOutputs = async (entries) => {
|
|
const dataDir = new URL("../public/data/", import.meta.url);
|
|
const textDir = new URL("../public/data/gog-text/", import.meta.url);
|
|
|
|
await mkdir(dataDir, { recursive: true });
|
|
await mkdir(textDir, { recursive: true });
|
|
|
|
const jsonPath = new URL("gog.json", dataDir);
|
|
await writeFile(jsonPath, JSON.stringify(entries, null, 2) + "\n", "utf-8");
|
|
|
|
await Promise.all(
|
|
entries.map(async (entry) => {
|
|
const fileName = `${sanitizeFileName(entry.title)}__${entry.id}.txt`;
|
|
const filePath = new URL(fileName, textDir);
|
|
await writeFile(filePath, buildTextFile(entry), "utf-8");
|
|
}),
|
|
);
|
|
};
|
|
|
|
const run = async () => {
|
|
const config = await loadConfig();
|
|
const userId = config.gog?.userId || process.env.GOG_USER_ID;
|
|
const accessToken = config.gog?.accessToken || process.env.GOG_ACCESS_TOKEN;
|
|
|
|
const games = await fetchGogGames({ userId, accessToken });
|
|
const entries = games.map(buildGogEntry);
|
|
await writeOutputs(entries);
|
|
console.log(`GOG-Export fertig: ${entries.length} Spiele.`);
|
|
};
|
|
|
|
run().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|