Fix: the server crashed on every Search; Search now covers tasks and events and explains itself
build-container / build (push) Successful in 1m55s
build-container / build (push) Successful in 1m55s
- Restore ddgAnswer, which an earlier edit deleted: /api/ddg threw a ReferenceError and killed the whole server process whenever Search ran - One failing request can no longer take the server down (errors are logged and answered with a 500) - tools/smoke-test.js starts the real server and calls every endpoint; the Gitea workflow runs it before building the image, so a missing function or a crash stops the build - Search: also searches NE Hub tasks and calendar events; Seafile file search falls back to scanning file names when the search index returns nothing; Plex search falls back to the library's artists/albums; a status line shows what was searched, per-source counts and errors, with sign-in links Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ea882cafbf
commit
489ea0aaf0
8 files changed
+229
-40
No files matched your search
@@ -247,6 +247,22 @@ const readBody = req => new Promise((ok, no) => { const c = []; req.on('data', d
|
||||
const json = (res, code, obj) => { res.writeHead(code, { 'content-type': 'application/json' }); res.end(JSON.stringify(obj)); };
|
||||
const COLORS = ['#4f7cff', '#2f9e6e', '#e0742b', '#d9453a', '#8a5cf0', '#e5a00d'];
|
||||
|
||||
/** Every event in the window from all calendars (ICS links, iCloud, NE Hub): { events, errors } */
|
||||
async function collectEvents(win) {
|
||||
const all = [], errors = [];
|
||||
await Promise.all(load().map(async c => {
|
||||
try { for (const e of expand(parseEvents(await getIcs(c.url)), win)) all.push({ ...e, cal: c.name, color: c.color }); }
|
||||
catch (e) { errors.push(`${c.name}: ${e.message}`); }
|
||||
}));
|
||||
try {
|
||||
for (const r of await caldav.listRaw(win.from, win.to))
|
||||
for (const e of expand(parseEvents(r.ics), win)) all.push({ ...e, cal: r.name, calId: r.calId, color: r.color, editable: true, href: r.href, etag: r.etag });
|
||||
} catch (e) { errors.push('iCloud: ' + e.message); }
|
||||
try { for (const e of expand(parseEvents(localIcs()), win)) all.push({ ...e, cal: LOCAL.name, calId: 'local', color: LOCAL.color, editable: true }); }
|
||||
catch (e) { errors.push('NE Hub: ' + e.message); }
|
||||
return { events: all, errors };
|
||||
}
|
||||
|
||||
async function handle(req, res) {
|
||||
const u = new URL(req.url, 'http://x');
|
||||
try {
|
||||
@@ -269,18 +285,7 @@ async function handle(req, res) {
|
||||
const q = u.searchParams;
|
||||
const win = { from: +q.get('from'), to: +q.get('to'), fd: q.get('fd'), td: q.get('td') };
|
||||
if (!win.from || !win.to || !win.fd || !win.td) throw new Error('from/to required');
|
||||
const all = [], errors = [];
|
||||
await Promise.all(load().map(async c => {
|
||||
try { for (const e of expand(parseEvents(await getIcs(c.url)), win)) all.push({ ...e, cal: c.name, color: c.color }); }
|
||||
catch (e) { errors.push(`${c.name}: ${e.message}`); }
|
||||
}));
|
||||
try {
|
||||
for (const r of await caldav.listRaw(win.from, win.to))
|
||||
for (const e of expand(parseEvents(r.ics), win)) all.push({ ...e, cal: r.name, calId: r.calId, color: r.color, editable: true, href: r.href, etag: r.etag });
|
||||
} catch (e) { errors.push('iCloud: ' + e.message); }
|
||||
try { for (const e of expand(parseEvents(localIcs()), win)) all.push({ ...e, cal: LOCAL.name, calId: 'local', color: LOCAL.color, editable: true }); }
|
||||
catch (e) { errors.push('NE Hub: ' + e.message); }
|
||||
return json(res, 200, { events: all, errors });
|
||||
return json(res, 200, await collectEvents(win));
|
||||
}
|
||||
if (u.pathname === '/api/cal/event' && req.method === 'GET') {
|
||||
const q = u.searchParams, tz = q.get('tz') || 'UTC';
|
||||
@@ -339,4 +344,4 @@ async function handle(req, res) {
|
||||
} catch (e) { json(res, 400, { error: e.message }); }
|
||||
}
|
||||
|
||||
module.exports = { unfold, parseLine, parseDate, unesc, handle, feed, parseEvents, expand, zonedToUtc, assertPublic, localIcs };
|
||||
module.exports = { collectEvents, unfold, parseLine, parseDate, unesc, handle, feed, parseEvents, expand, zonedToUtc, assertPublic, localIcs };
|
||||
Reference in new issue
Block a user