Open Library in the book store; podcast topic search and transcript search; Recipes (Mealie) with a shopping list synced to Tasks; Contacts linked to Mail and the Calendar
build-container / build (push) Successful in 7m21s

- Store: Open Library search, books fetched from the Internet Archive (free editions only)
- Podcast: Podcast Index discovery by name and topic (optional key); search what is said across transcripts and play from that moment
- Recipes: browse, import from a link, add ingredients to Mealie's shopping list, mirrored two ways with a Shopping list in Tasks
- Contacts: per-person address book, vCard import/export, recipient suggestions in Mail, birthdays in the Calendar

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-26 08:55:32 -04:00
1 parent 0617664d97
commit 176b1b8169
28 files changed
+799 -46

No files matched your search

+8 -1
View File
@@ -41,6 +41,8 @@ const abapi = require('./abapi'); // audiobook player library, audio and progre
const bible = require('./bible'); // Bible: each person's place, highlights and notes (the text is a static file)
const savefiles = require('./savefiles'); // "Save to Files": copy books, lessons and audiobooks into the person's Seafile
const vbv = require('./vbv'); // Verse By Verse Ministry teaching (free Bible studies)
const recipes = require('./recipes'); // recipes and the shopping list, from Mealie (MEALIE_URL, MEALIE_TOKEN)
const contacts = require('./contacts'); // each person's address book (mail suggestions, calendar birthdays, vCard import and export)
const radio = require('./radio'); // internet radio (Radio Browser directory, The Journey FM)
const librivox = require('./librivox'); // free audiobooks from LibriVox
const books = require('./books'); // e-book reader: EPUB, PDF and DOCX library with synced progress and notes
@@ -551,9 +553,11 @@ const ACCESS = [
[/^\/api\/bible\//, ['bible']],
[/^\/api\/read\//, ['read']],
[/^\/api\/radio\//, ['radio']],
[/^\/api\/recipes(\/|$)/, ['recipes']],
[/^\/api\/contacts(\/|$)/, ['contacts']],
[/^\/api\/signal\//, ['signal']],
[/^\/api\/lyrics$/, ['music', 'radio']],
[/^\/api\/transcript$/, ['podcast', 'audio']],
[/^\/api\/transcript(\/search)?$/, ['podcast', 'audio']],
[/^\/api\/mail\//, ['mail']],
[/^\/api\/cal\//, ['calendar']],
[/^\/api\/tasks/, ['tasks']],
@@ -638,6 +642,7 @@ async function handleRequest(req, res) {
const to = audiobooksLogin(user);
res.writeHead(302, { location: to || AUDIOBOOKS_URL, 'cache-control': 'no-store', 'referrer-policy': 'no-referrer' }); return res.end();
}
if (pathname === '/api/transcript/search') return transcripts.searchHandle(req, res);
if (pathname === '/api/transcript') return transcripts.handle(req, res);
if (pathname === '/api/lyrics') return lyrics.enabled() ? lyrics.handle(req, res) : forbidden(res, 'Lyrics are not set up on this server');
if (pathname.startsWith('/api/ab/free/')) return librivox.handle(req, res);
@@ -645,6 +650,8 @@ async function handleRequest(req, res) {
if (pathname.startsWith('/api/podcast/')) return podcast.handle(req, res);
if (pathname.startsWith('/api/read/')) return books.handle(req, res);
if (pathname.startsWith('/api/radio/')) return radio.handle(req, res);
if (pathname === '/api/recipes' || pathname.startsWith('/api/recipes/')) return recipes.handle(req, res);
if (pathname === '/api/contacts' || pathname.startsWith('/api/contacts/')) return contacts.handle(req, res);
if (pathname.startsWith('/api/vbv/')) return vbv.handle(req, res);
if (pathname.startsWith('/api/save/')) return savefiles.handle(req, res);
if (pathname.startsWith('/api/bible/')) return bible.handle(req, res);