// Змейка по графику активности EDeev на git.deev.su → ветка output репозитория EDeev/.profile. // Запуск: node generate.mjs (без FORGEJO_TOKEN — только пишет snake.svg рядом, ничего не публикует). import { writeFileSync } from "node:fs"; import { generateSnakeAnimation } from "generate-snake-animation"; const BASE = "https://git.deev.su"; const USER = "EDeev"; const REPO = ".profile"; const BRANCH = "output"; const FILE = "snake.svg"; // палитра forgejo-dark из generate-snake-animation const drawOptions = { sizeDotBorderRadius: 2, sizeCell: 16, sizeDot: 12, colorBackground: "#1f2937", colorDotBorder: "#ffffff10", colorEmpty: "#2b3642", colorDots: ["#2b3642", "#9a3412", "#ea580c", "#fb923c", "#fed7aa"], colorSnake: "#fed7aa", }; const [svg] = await generateSnakeAnimation( { platform: "forgejo", username: USER, baseUrl: BASE }, // baseUrl без «/» в конце, иначе Forgejo отвечает 404 [{ format: "svg", drawOptions, animationOptions: { frameByStep: 1, stepDurationMs: 100 } }], ); writeFileSync(FILE, svg); console.log(`${FILE}: ${svg.length} байт`); const token = process.env.FORGEJO_TOKEN; if (!token) process.exit(0); const api = async (method, path, body) => { const res = await fetch(`${BASE}/api/v1/repos/${USER}/${REPO}${path}`, { method, headers: { Authorization: `token ${token}`, "Content-Type": "application/json" }, body: body && JSON.stringify(body), }); if (!res.ok && res.status !== 404) throw new Error(`${method} ${path}: ${res.status} ${await res.text()}`); return res.status === 404 ? null : res.json(); }; const content = Buffer.from(svg).toString("base64"); const current = await api("GET", `/contents/${FILE}?ref=${BRANCH}`); const message = "Обновить змейку"; if (!current) { // первый запуск: ветки output ещё нет — создаём её из main вместе с файлом const branch = await api("GET", `/branches/${BRANCH}`); await api("POST", `/contents/${FILE}`, branch ? { content, message, branch: BRANCH } : { content, message, branch: "main", new_branch: BRANCH }); console.log("опубликовано (новый файл)"); } else if (current.content.replace(/\n/g, "") !== content) { await api("PUT", `/contents/${FILE}`, { content, message, branch: BRANCH, sha: current.sha }); console.log("опубликовано (обновлено)"); } else { console.log("без изменений"); }