Audiobooks: each person's listening positions are their own (the whole library stays shared)
build-container / build (push) Successful in 9m2s
build-container / build (push) Successful in 9m2s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2635e4615d
commit
3f57e4bde1
3 files changed
+12
-13
No files matched your search
@@ -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; } }
|
||||
|
||||
Reference in new issue
Block a user