feat(podcasts): scanner exclusion — podcasts libraries are feed-managed (task 1.2)
WHY: podcast download roots hold fetcher-written episode files; the FS
walker must never discover them (invariant 4) — a walk would double-
ingest episodes as scanner items and fight the fetcher's sole-writer
rule (D9). Every scan/watch path funnels through MediaScanner.SetFolders
(StartScanner, ScanLibrary jobs incl. scoped single-folder scans,
watch mode), so the filter lives there once: folders resolving to a
podcasts-type library are dropped before registration, with a log line.
Belt and braces: ScanLibrary's per-folder scope refuses purpose='podcast'
folders explicitly (400) — the panel-level path that bypasses type
resolution. AddLibraryFolder now derives purpose from the library type
('podcast' for podcasts libraries, enforced single download root;
'scan' default elsewhere), so folder purpose and library type cannot
diverge through the API.
This commit is contained in:
1 parent
0b7ad0f376
commit
c0e6993273
6 files changed
+77
-3
No files matched your search
@@ -85,6 +85,11 @@ func (h *Handler) ScanLibrary(c *echo.Context) error {
|
||||
for _, folder := range libraryFolders {
|
||||
if folder.FolderPath == req.FolderPath {
|
||||
registered = true
|
||||
// Podcast download roots are feed-managed (invariant
|
||||
// 4): never scanner-ingestible, even scoped.
|
||||
if folder.Purpose == services.FolderPurposePodcast {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "podcast download roots are feed-managed and cannot be scanned"})
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user