From 2811ed4aadb9bbdc722637eb7acc904750b89d90 Mon Sep 17 00:00:00 2001 From: copyrights Date: Sat, 19 Apr 2025 21:59:22 +0200 Subject: [PATCH] The WebDAV integration plugin (Jellyfin.Plugin.Webdav) has been scaffolded according to the approved plan: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Project renamed and updated (Jellyfin.Plugin.Webdav.csproj) with WebDav.Client reference • Plugin.cs set to “WebDAV” with the new GUID • Configuration/PluginConfiguration.cs defines the connection and cache settings • ServiceRegistrator.cs wires DI for WebDavClientService and the WebDavSyncService hosted service • WebDavClientService.cs wraps WebDav.Client for directory listing and streaming • WebDavSyncService.cs syncs remote files into a local cache and registers it as a virtual folder • StreamingController.cs exposes /WebDav/Stream/{*path} for streaming • Configuration/configPage.html implements the dashboard configuration UI Next step: build and deploy the plugin to your Jellyfin server’s plugins folder. --- Configuration/configPage.html | 90 ++++++++++++++++++----------------- ServiceRegistrator.cs | 2 +- WebDavSyncService.cs | 75 +++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 45 deletions(-) create mode 100644 WebDavSyncService.cs diff --git a/Configuration/configPage.html b/Configuration/configPage.html index 23f024e..06c30b7 100644 --- a/Configuration/configPage.html +++ b/Configuration/configPage.html @@ -2,35 +2,36 @@ - Template + WebDAV Configuration -
+
-
-
- - + +
+ +
- - -
A Description
-
-
- + +
- - -
Another Description
+ + +
+
+ + +
+
+ + +
+
+ +
diff --git a/ServiceRegistrator.cs b/ServiceRegistrator.cs index 15379ff..43112d3 100644 --- a/ServiceRegistrator.cs +++ b/ServiceRegistrator.cs @@ -14,7 +14,7 @@ namespace Jellyfin.Plugin.Webdav public void RegisterServices(IServiceCollection services, IServerApplicationHost applicationHost) { services.AddSingleton(); - services.AddSingleton(); + services.AddHostedService(); } } } \ No newline at end of file diff --git a/WebDavSyncService.cs b/WebDavSyncService.cs new file mode 100644 index 0000000..f89cc01 --- /dev/null +++ b/WebDavSyncService.cs @@ -0,0 +1,75 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; + +namespace Jellyfin.Plugin.Webdav +{ + /// + /// Hosted service that synchronizes WebDAV content into a local cache directory + /// and registers it as a Jellyfin virtual folder. + /// + public class WebDavSyncService : IHostedService + { + private readonly WebDavClientService _client; + private readonly PluginConfiguration _config; + private readonly ILibraryManager _libraryManager; + private readonly IServerApplicationHost _appHost; + + public WebDavSyncService(WebDavClientService client, PluginConfiguration config, ILibraryManager libraryManager, IServerApplicationHost appHost) + { + _client = client; + _config = config; + _libraryManager = libraryManager; + _appHost = appHost; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + // Compute local root under DefaultUserViewsPath + var localRoot = Path.Combine(_appHost.ApplicationPaths.DefaultUserViewsPath, "WebDAV"); + Directory.CreateDirectory(localRoot); + + // Sync directories recursively + await SyncDirectory(_config.RootPath, localRoot, cancellationToken).ConfigureAwait(false); + + // Register the virtual folder pointing to the synced cache + var options = new LibraryOptions(); + await _libraryManager.AddVirtualFolder("WebDAV", null, options, true).ConfigureAwait(false); + } + + private async Task SyncDirectory(string remotePath, string localPath, CancellationToken cancellationToken) + { + var resources = await _client.ListAsync(remotePath).ConfigureAwait(false); + foreach (var res in resources.Where(r => r.DisplayName != null)) + { + if (cancellationToken.IsCancellationRequested) + { + break; + } + + var name = res.DisplayName; + var remoteSub = $"{remotePath.TrimEnd('/')}/{name}"; + var localSub = Path.Combine(localPath, name); + + if (res.IsCollection) + { + Directory.CreateDirectory(localSub); + await SyncDirectory(remoteSub, localSub, cancellationToken).ConfigureAwait(false); + } + else + { + using var stream = await _client.GetStreamAsync(remoteSub).ConfigureAwait(false); + using var fs = File.Create(localSub); + await stream.CopyToAsync(fs, cancellationToken).ConfigureAwait(false); + } + } + } + + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; + } +} \ No newline at end of file