# Nextcloud/WebDAV Jellyfin Plugin Plan
Below is a high-level plan for a Jellyfin plugin that integrates Nextcloud/WebDAV sources as library content.
```mermaid
flowchart TD
subgraph Plugin Core
A[PluginConfiguration
– holds URL, creds, paths]
B[Plugin
– BasePlugin]
C[IPluginServiceRegistrator
– registers services]
D[IHostedService
– hook on startup]
end
subgraph Services
E[WebDavClientService
– wraps WebDav.Client]
F[RemoteLibraryProvider
– implements virtual folder scanning]
G[CachingLayer
– buffer / temporary file cache]
H[StreamingController
– ControllerBase for proxying streams]
end
subgraph Jellyfin Core
I[ILibraryManager
– library registration]
J[Scan Engine
– calls provider to enumerate items]
K[HTTP Pipeline
– routes to controllers]
end
A --> B
B --> C
C --> E
C --> F
E --> F
F --> J
F --> G
G --> H
H --> K
D --> I
I --> J
```
## 1. Skeleton & Setup
- Copy the `jellyfin-plugin-template` and rename to `Jellyfin.Plugin.Nextcloud`.
- Update project metadata: plugin ID, name, version in `.csproj`.
- Add NuGet reference to `WebDav.Client`.
## 2. Configuration & Dependency Injection
- Define `PluginConfiguration` with URL, credentials, root path, and cache settings.
- Implement `Plugin : BasePlugin` to override `Name`, `Id`, and inject DI.
- Create `IPluginServiceRegistrator` to register services:
- `WebDavClientService` (singleton)
- `RemoteLibraryProvider` (scanning)
- `StreamingController` (ASP.NET Controller)
- Register virtual folder with `ILibraryManager.RegisterVirtualFolder` on startup.
## 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`.
- Implement `CachingLayer` to buffer chunks and write to temp files to prevent stalls.
## 5. Admin UI
- Define `configPage.html` as an embedded resource and implement `IHasWebPages` in `Plugin.cs` to return a `PluginPageInfo` for the settings page.
- Update `build.yaml` to include a `pages` section:
```yaml
pages:
- name: WebDAV
embeddedResourcePath: Jellyfin.Plugin.Webdav.Configuration.configPage.html
```
- Rebuild the plugin so that MSBuild generates a `plugin.json` manifest containing the pages definition.
- Deploy the `plugin.json`, DLL, and dependencies to Jellyfin’s `plugins` folder.
- Restart Jellyfin to verify the “WebDAV” settings page appears under Admin → Plugins.
## 6. Testing & Validation
- Unit-test `WebDavClientService` using a test Nextcloud instance or mock.
- Deploy plugin locally; verify library shows Nextcloud virtual folders.
- Test playback to ensure smooth streaming.
## 7. Documentation & Release
- Write README with installation, configuration, and troubleshooting guidance.
- Bump version, package plugin (`.nupkg`), and publish to GitHub Releases.
### Milestones
- **M1**: Plugin skeleton & DI wiring
- **M2**: Scanning proof-of-concept
- **M3**: Streaming proxy & caching
- **M4**: Admin UI & settings page
- **M5**: Testing, documentation, release