diff --git a/NextcloudPluginPlan.md b/NextcloudPluginPlan.md index 6fd474d..086bd6f 100644 --- a/NextcloudPluginPlan.md +++ b/NextcloudPluginPlan.md @@ -51,12 +51,61 @@ flowchart TD - `StreamingController` (ASP.NET Controller) - Register virtual folder with `ILibraryManager.RegisterVirtualFolder` on startup. -## 3. Scanning Integration -- Research Jellyfin scan engine provider interfaces. -- Implement `RemoteLibraryProvider` to list directories/files via `WebDavClientService`. -- Map each remote item to a `BaseItem` (e.g., `Video`, `Folder`) with metadata. -- Track ETags or timestamps to support incremental scans. +## 3. Scanning Proof-of-Concept (M2) +```mermaid +flowchart TD + subgraph Plugin Core + Cfg[PluginConfiguration
– holds URL, creds, rootPath, cache settings] + Reg[ServiceRegistrator
– registers DI & virtual folder] + end + + subgraph Scanning POC + WCS[WebDavClientService
– list, HEAD for size] + RLP[RemoteLibraryProvider
– implements scanning] + MI[MediaInfoParser
– extract duration] + Items[BaseItem list] + end + + Cfg --> Reg + Reg --> WCS + Reg --> RLP + WCS --> RLP + RLP --> MI + RLP --> Items + Items --> ScanEngine[Jellyfin Scan Engine] +``` + +**POC Interface Choice:** +Use an `IHostedService` (the existing `WebDavSyncService`) to sync remote content into a local cache directory, then register that directory via `ILibraryManager.AddVirtualFolder`. This leverages the built‑in file system scan engine for enumeration and HEAD/partial reads for metadata retrieval. + +### 3.1 Dependency Injection & Registration +- Add `RemoteLibraryProvider` to DI with `serviceCollection.AddSingleton();`. +- On startup in a hosted service, call `ILibraryManager.RegisterVirtualFolder("Nextcloud", providerInstance)` to hook into Jellyfin's scan pipeline. + +### 3.2 Plugin Configuration +- Ensure `PluginConfiguration` exposes: + - `WebDavUrl`, `Username`, `Password` + - `RootPath`, `CacheDirectory`, `CacheSizeMb` + +### 3.3 RemoteLibraryProvider Implementation +- Inject `WebDavClientService`, `PluginConfiguration`, and `ILogger` in the constructor. +- Implement `GetItemsAsync(BaseItem parent, CancellationToken ct)`: + 1. Call `webDav.ListAsync(cfg.RootPath + parent.Path)` to enumerate remote children. + 2. For directories: create `new BaseItem { Name = dirName, IsFolder = true, Id = GenerateId(path) }`. + 3. For video files: + - Use `webDav.HeadAsync(path)` to get `Content-Length` for size. + - Download a small buffer and parse with `MediaInfoParser.Parse(stream)` to get `Duration`. + - Create `new BaseItem { Name = fileName, RunTimeTicks = durationTicks, MediaSources = { new MediaSourceInfo { Size = size } }, Id = GenerateId(path) }`. + 4. Return the list of `BaseItem`s. + +### 3.4 Logging & Diagnostics +- Log total items found per folder and individual metadata (size, duration) for verification. + +### 3.5 Manual Validation +- Deploy locally, configure plugin with test Nextcloud credentials. +- Restart Jellyfin and trigger a library scan. +- Verify in logs that the `RemoteLibraryProvider` runs and emits items with correct size and duration. ## 4. Streaming & Caching - Create `StreamingController : ControllerBase` with endpoint `/WebDav/Stream/{itemId}`. - Map `itemId` to remote path and stream via `WebDavClientService.GetStream`.