Transcripts: new and existing episodes are transcribed in the background (published transcript first, else whisper), with a status line in Health
build-container / build (push) Successful in 3m29s
build-container / build (push) Successful in 3m29s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e7bd24bbaa
commit
1c089c4a10
6 files changed
+64
-8
No files matched your search
+23
-3
@@ -113,13 +113,33 @@ async function handle(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
/** For transcripts: where an episode came from (its feed, its id in that feed, its file). Anyone may ask about the shows on their own list only. */
|
||||
/** For transcripts: where an episode came from (its feed, its id in that feed, its file). With a person, only the shows on their own list; without one (the server's own background work), any. */
|
||||
async function feedInfo(me, itemId) {
|
||||
if (!BASE || !/^[\w-]+$/.test(String(itemId))) return null;
|
||||
const f = (o, k) => { if (!o) return undefined; const hit = Object.keys(o).find(x => x.toLowerCase() === k.toLowerCase()); return hit === undefined ? undefined : o[hit]; }; // (Podgrab's field names, whatever their capitals)
|
||||
const it = await (await podgrab('/podcastitems/' + itemId)).json().catch(() => null); if (!it) return null;
|
||||
const pid = f(it, 'PodcastID') || f(it, 'podcastId'); if (!pid || !(await mySubs(me)).includes(pid)) return null;
|
||||
const pid = f(it, 'PodcastID') || f(it, 'podcastId'); if (!pid || (me && !(await mySubs(me)).includes(pid))) return null;
|
||||
const sh = await (await podgrab('/podcasts/' + pid)).json().catch(() => null);
|
||||
return { guid: f(it, 'GUID') || f(it, 'guid') || '', fileUrl: f(it, 'FileURL') || f(it, 'fileUrl') || '', feedUrl: (sh && (f(sh, 'URL') || f(sh, 'url'))) || '' };
|
||||
}
|
||||
module.exports = { handle, enabled, feedInfo };
|
||||
/** The newest `n` episodes of every show in Podgrab, newest first overall: [{ id, title, show, guid, fileUrl, feedUrl }]. */
|
||||
async function recentEpisodes(n) {
|
||||
if (!BASE) return [];
|
||||
const f = (o, k) => { const hit = Object.keys(o || {}).find(x => x.toLowerCase() === k.toLowerCase()); return hit === undefined ? undefined : o[hit]; };
|
||||
const shows = await (await podgrab('/podcasts')).json().catch(() => []), out = [];
|
||||
for (const sh of Array.isArray(shows) ? shows : []) {
|
||||
const sid = idOf(sh); if (!sid) continue;
|
||||
const items = await (await podgrab('/podcasts/' + sid + '/items')).json().catch(() => []);
|
||||
for (const it of (Array.isArray(items) ? items : []).sort((x, y) => String(f(y, 'PubDate')).localeCompare(String(f(x, 'PubDate')))).slice(0, n))
|
||||
out.push({ id: String(idOf(it)), title: f(it, 'Title') || '', show: f(sh, 'Title') || '', date: String(f(it, 'PubDate') || ''), guid: f(it, 'GUID') || '', fileUrl: f(it, 'FileURL') || '', feedUrl: f(sh, 'URL') || '' });
|
||||
}
|
||||
return out.sort((x, y) => y.date.localeCompare(x.date));
|
||||
}
|
||||
/** The audio of one episode, straight from Podgrab (for the server's own background work). */
|
||||
async function episodeAudio(itemId) {
|
||||
if (!BASE || !/^[\w-]+$/.test(String(itemId))) throw new Error('Bad episode');
|
||||
const r = await podgrab('/podcastitems/' + itemId + '/file'), loc = r.headers.get('location');
|
||||
if (r.status >= 300 && r.status < 400 && loc && /^https?:\/\//i.test(loc)) return fetch(loc, { signal: AbortSignal.timeout(2 * 3600e3) }); // (Podgrab has no copy of its own: the original)
|
||||
return r;
|
||||
}
|
||||
module.exports = { handle, enabled, feedInfo, recentEpisodes, episodeAudio };
|
||||
Reference in new issue
Block a user