105 lines
2.9 KiB
JavaScript
105 lines
2.9 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 toIsoDate = (unixSeconds) =>
|
|
unixSeconds ? new Date(unixSeconds * 1000).toISOString().slice(0, 10) : null;
|
|
|
|
const sanitizeFileName = (value) => {
|
|
const normalized = value
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, "-")
|
|
.replace(/^-+|-+$/g, "");
|
|
return normalized || "spiel";
|
|
};
|
|
|
|
const fetchOwnedGames = async ({ apiKey, steamId }) => {
|
|
const url = new URL(
|
|
"https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/",
|
|
);
|
|
url.searchParams.set("key", apiKey);
|
|
url.searchParams.set("steamid", steamId);
|
|
url.searchParams.set("include_appinfo", "true");
|
|
url.searchParams.set("include_played_free_games", "true");
|
|
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
throw new Error(`Steam API Fehler: ${response.status}`);
|
|
}
|
|
|
|
const payload = await response.json();
|
|
return payload.response?.games ?? [];
|
|
};
|
|
|
|
const buildSteamEntry = (game) => ({
|
|
id: String(game.appid),
|
|
title: game.name,
|
|
platform: "PC",
|
|
lastPlayed: toIsoDate(game.rtime_last_played),
|
|
playtimeHours: Math.round((game.playtime_forever / 60) * 10) / 10,
|
|
tags: [],
|
|
url: `https://store.steampowered.com/app/${game.appid}`,
|
|
});
|
|
|
|
const buildTextFile = (entry) => {
|
|
const lines = [
|
|
`Titel: ${entry.title}`,
|
|
`Steam AppID: ${entry.id}`,
|
|
`Zuletzt gespielt: ${entry.lastPlayed ?? "-"}`,
|
|
`Spielzeit (h): ${entry.playtimeHours ?? 0}`,
|
|
`Store: ${entry.url}`,
|
|
"Quelle: steam",
|
|
];
|
|
return lines.join("\n") + "\n";
|
|
};
|
|
|
|
const writeOutputs = async (entries) => {
|
|
const dataDir = new URL("../public/data/", import.meta.url);
|
|
const textDir = new URL("../public/data/steam-text/", import.meta.url);
|
|
|
|
await mkdir(dataDir, { recursive: true });
|
|
await mkdir(textDir, { recursive: true });
|
|
|
|
const jsonPath = new URL("steam.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 apiKey = config.steam?.apiKey || process.env.STEAM_API_KEY;
|
|
const steamId = config.steam?.steamId || process.env.STEAM_ID;
|
|
|
|
if (!apiKey || !steamId) {
|
|
console.error(
|
|
"Bitte Steam-Zugangsdaten in config.local.json oder per Umgebungsvariablen setzen.",
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
const games = await fetchOwnedGames({ apiKey, steamId });
|
|
const entries = games.map(buildSteamEntry);
|
|
await writeOutputs(entries);
|
|
console.log(`Steam-Export fertig: ${entries.length} Spiele.`);
|
|
};
|
|
|
|
run().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|