Files
Stardream e3bf77296c
Build and Push Docker Image / build (push) Successful in 17s
Initial release
2026-06-16 20:27:36 +10:00

69 lines
3.2 KiB
JavaScript

'use strict';
const DEFAULT_API_BASE = 'https://api.bgm.tv';
let apiBase = DEFAULT_API_BASE;
// Set by runSync from settings.bgmApiBase (sync is locked/serial, so a module-level value is safe).
function setApiBase(base) { apiBase = (typeof base === 'string' && base.trim()) ? base.trim().replace(/\/+$/, '') : DEFAULT_API_BASE; }
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
async function bgmFetch(path, token) {
const res = await fetch(apiBase + path, {
headers: {
'Accept': 'application/json',
'User-Agent': 'BangumiVaultDocker/1.0',
...(token ? { 'Authorization': 'Bearer ' + String(token).trim() } : {})
}
});
if (!res.ok) {
const t = await res.text().catch(() => res.statusText);
throw new Error(`HTTP ${res.status}: ${String(t).slice(0, 200)}`);
}
return res.json();
}
async function fetchMe(token) {
return bgmFetch('/v0/me', token);
}
async function fetchCollectionAll(username, st, ct, token, onPage) {
const limit = 50; let offset = 0; let total = Infinity; let page = 0; const out = [];
while (offset < total) {
const path = `/v0/users/${encodeURIComponent(username)}/collections?subject_type=${st}&type=${ct}&limit=${limit}&offset=${offset}`;
const js = await bgmFetch(path, token); const data = Array.isArray(js) ? js : (js.data || []);
total = Number.isFinite(js.total) ? js.total : (offset + data.length + (data.length === limit ? limit : 0));
out.push(...data.map(x => ({ ...x, __fallback: { subject_type: st, collection_type: ct } }))); page++;
if (onPage) onPage(page, out.length);
if (!data.length || data.length < limit) break;
offset += limit; await sleep(110);
}
return out;
}
async function fetchCollectionRecent(username, st, ct, token, cutoff, onPage) {
const limit = 50; let offset = 0; let total = Infinity; let page = 0; const out = []; const cutoffMs = cutoff.getTime();
while (offset < total) {
const path = `/v0/users/${encodeURIComponent(username)}/collections?subject_type=${st}&type=${ct}&limit=${limit}&offset=${offset}`;
const js = await bgmFetch(path, token); const data = Array.isArray(js) ? js : (js.data || []);
total = Number.isFinite(js.total) ? js.total : (offset + data.length + (data.length === limit ? limit : 0));
const decorated = data.map(x => ({ ...x, __fallback: { subject_type: st, collection_type: ct } }));
const recent = decorated.filter(x => { const t = Date.parse(x.updated_at || x.updatedAt || ''); return !Number.isFinite(t) || t >= cutoffMs; });
out.push(...recent); page++;
const stopByTime = data.length > 0 && recent.length === 0 && data.every(x => { const t = Date.parse(x.updated_at || x.updatedAt || ''); return Number.isFinite(t) && t < cutoffMs; });
if (onPage) onPage(page, out.length, stopByTime);
if (!data.length || data.length < limit || stopByTime) break;
offset += limit; await sleep(80);
}
return out;
}
async function fetchSubjectDetail(subjectId, token) {
try {
return await bgmFetch(`/v0/subjects/${encodeURIComponent(subjectId)}`, token || '');
} catch {
return null;
}
}
module.exports = { DEFAULT_API_BASE, setApiBase, sleep, bgmFetch, fetchMe, fetchCollectionAll, fetchCollectionRecent, fetchSubjectDetail };