Audiobooks: each person's listening positions are their own (the whole library stays shared)
build-container / build (push) Successful in 9m2s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-22 16:52:38 -04:00
1 parent 2635e4615d
commit 3f57e4bde1
3 files changed
+12 -13

No files matched your search

+8 -12
View File
@@ -61,22 +61,18 @@ async function handle(req, res) {
const u = new URL(req.url, 'http://x'), p = u.pathname.slice('/api/ab'.length) || '/';
const ctl = new AbortController(); res.on('close', () => ctl.abort());
try {
if (p === '/progress') {
if (OA) { // positions live in the hub
if (req.method === 'GET') return json(res, 200, progLoad());
if (req.method !== 'POST') return json(res, 405, { error: 'Method not allowed' });
const chunks = []; let n = 0; for await (const c of req) { n += c.length; if (n > 1e6) return json(res, 413, { error: 'Too large' }); chunks.push(c); }
let body; try { body = JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}'); } catch { return json(res, 400, { error: 'Bad request' }); }
return json(res, 200, progMerge(body));
}
if (p === '/progress') { // each person's own positions are kept by the hub; with a personal sign-in on the audiobook player they are also kept in step with it
const personal = !OA && (c => !!(c && c.u && c.p))(settings.get('ab_creds'));
if (req.method === 'POST') {
const chunks = []; let n = 0; for await (const c of req) { n += c.length; if (n > 1e6) return json(res, 413, { error: 'Too large' }); chunks.push(c); }
const r = await upstream(me, '/sync/progress', { method: 'POST', body: Buffer.concat(chunks), headers: { 'content-type': 'application/json' }, signal: ctl.signal });
res.writeHead(r.status, { 'content-type': 'application/json', 'cache-control': 'no-store' }); return res.end(Buffer.from(await r.arrayBuffer()));
let body; try { body = JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}'); } catch { return json(res, 400, { error: 'Bad request' }); }
const merged = progMerge(body);
if (personal) upstream(me, '/sync/progress', { method: 'POST', body: JSON.stringify(body), headers: { 'content-type': 'application/json' } }).then(r => r.body?.cancel()).catch(() => {});
return json(res, 200, merged);
}
if (req.method !== 'GET') return json(res, 405, { error: 'Method not allowed' });
const r = await upstream(me, '/sync/progress', { signal: ctl.signal });
res.writeHead(r.status, { 'content-type': 'application/json', 'cache-control': 'no-store' }); return res.end(Buffer.from(await r.arrayBuffer()));
if (personal) { try { const r = await upstream(me, '/sync/progress', { signal: ctl.signal }); if (r.ok) progMerge(await r.json()); } catch { /* the hub's own copy is enough */ } }
return json(res, 200, progLoad());
}
if (req.method !== 'GET') return json(res, 405, { error: 'Method not allowed' });
let to = null; for (const [re, f] of ROUTES) { const m = re.exec(p); if (m) { to = f(m); break; } }