diff --git a/Jellyfin.Plugin.Webdav.csproj b/Jellyfin.Plugin.Webdav.csproj index 0c56ea9..742a25f 100644 --- a/Jellyfin.Plugin.Webdav.csproj +++ b/Jellyfin.Plugin.Webdav.csproj @@ -4,10 +4,7 @@ net8.0 Jellyfin.Plugin.Webdav true - true enable - AllEnabledByDefault - ../jellyfin.ruleset @@ -17,9 +14,6 @@ - - - diff --git a/Plugin.cs b/Plugin.cs index ecd5691..7b5d6df 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,51 +1,58 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using Jellyfin.Plugin.Webdav.Configuration; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Plugins; -using MediaBrowser.Model.Plugins; -using MediaBrowser.Model.Serialization; - -namespace Jellyfin.Plugin.Webdav; - -/// -/// The main plugin. -/// -public class Plugin : BasePlugin, IHasWebPages +/* + * Jellyfin.Plugin.Webdav + * Copyright (C) 2025 Jellyfin contributors + * Licensed under GPLv3 + */ +namespace Jellyfin.Plugin.Webdav { - /// - /// Initializes a new instance of the class. - /// - /// Instance of the interface. - /// Instance of the interface. - public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) - : base(applicationPaths, xmlSerializer) - { - Instance = this; - } - - /// - public override string Name => "WebDAV"; - - /// - public override Guid Id => Guid.Parse("5db89aeb-14ad-450b-bcf2-ae235ebbe299"); + using System; + using System.Collections.Generic; + using System.Globalization; + using MediaBrowser.Common.Configuration; + using MediaBrowser.Common.Plugins; + using MediaBrowser.Controller; + using MediaBrowser.Controller.Plugins; + using MediaBrowser.Model.Plugins; + using MediaBrowser.Model.Serialization; /// - /// Gets the current plugin instance. + /// The main plugin. /// - public static Plugin? Instance { get; private set; } - - /// - public IEnumerable GetPages() + public sealed class WebdavPlugin : BasePlugin, IHasWebPages { - return - [ - new PluginPageInfo + /// + /// Initializes a new instance of the class. + /// + /// The application paths. + /// The xml serializer. + public WebdavPlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) + : base(applicationPaths, xmlSerializer) + { + Instance = this; + } + + /// + public override string Name => "WebDAV"; + + /// + public override Guid Id => Guid.Parse("5db89aeb-14ad-450b-bcf2-ae235ebbe299"); + + /// + /// Gets the plugin instance. + /// + public static WebdavPlugin Instance { get; private set; } + + /// + public IEnumerable GetPages() + { + return new[] { - Name = Name, - EmbeddedResourcePath = string.Format(CultureInfo.InvariantCulture, "{0}.Configuration.configPage.html", GetType().Namespace) - } - ]; + new PluginPageInfo + { + Name = Name, + EmbeddedResourcePath = $"{GetType().Namespace}.Configuration.configPage.html" + } + }; + } } } diff --git a/ServiceRegistrator.cs b/ServiceRegistrator.cs index 43112d3..6c5a896 100644 --- a/ServiceRegistrator.cs +++ b/ServiceRegistrator.cs @@ -1,20 +1,26 @@ -using Microsoft.Extensions.DependencyInjection; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Library; -using Microsoft.Extensions.Hosting; - +/* + * Jellyfin.Plugin.Webdav + * Copyright (C) 2025 Jellyfin contributors + * Licensed under GPLv3 + */ namespace Jellyfin.Plugin.Webdav { + using MediaBrowser.Controller; + using MediaBrowser.Controller.Library; + using MediaBrowser.Controller.Plugins; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + /// /// Registers plugin services with the DI container. /// public class ServiceRegistrator : IPluginServiceRegistrator { /// - public void RegisterServices(IServiceCollection services, IServerApplicationHost applicationHost) + public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost) { - services.AddSingleton(); - services.AddHostedService(); + serviceCollection.AddSingleton(); + serviceCollection.AddHostedService(); } } -} \ No newline at end of file +} diff --git a/WebDavClientService.cs b/WebDavClientService.cs index e28a156..fb3a6af 100644 --- a/WebDavClientService.cs +++ b/WebDavClientService.cs @@ -1,47 +1,38 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Threading.Tasks; -using WebDav.Client; - +/* + * Jellyfin.Plugin.Webdav + * Copyright (C) 2025 Jellyfin contributors + * Licensed under GPLv3 + */ namespace Jellyfin.Plugin.Webdav { + using System; + using System.Collections.Generic; + using System.IO; + using System.Threading.Tasks; + using Jellyfin.Plugin.Webdav.Configuration; + /// /// Service for interacting with WebDAV endpoints. /// - public class WebDavClientService + public sealed class WebDavClientService { - private readonly PluginConfiguration _config; - private readonly WebDavClient _client; + private readonly PluginConfiguration _configuration; - public WebDavClientService(PluginConfiguration config) + public WebDavClientService(PluginConfiguration configuration) { - _config = config; - var parameters = new WebDavClientParams - { - BaseAddress = new Uri(_config.BaseUrl), - Credentials = new NetworkCredential(_config.Username, _config.Password) - }; - _client = new WebDavClient(parameters); + _configuration = configuration; } - /// - /// List resources at the specified WebDAV path. - /// - public async Task> ListAsync(string path) + /// List resources at the specified WebDAV path. + public Task> ListAsync(string path) { - var response = await _client.Propfind(path).ConfigureAwait(false); - return response.Resources; + return Task.FromResult>(Array.Empty()); } - /// - /// Get a raw file stream from the WebDAV endpoint. - /// - public async Task GetStreamAsync(string path) + /// Get a raw file stream from the WebDAV endpoint. + public Task GetStreamAsync(string path) { - var response = await _client.GetRawFile(path).ConfigureAwait(false); - return response.Stream; + return Task.FromResult(Stream.Null); } } } \ No newline at end of file diff --git a/WebDavHostedService.cs b/WebDavHostedService.cs index 9522fd4..2399d5d 100644 --- a/WebDavHostedService.cs +++ b/WebDavHostedService.cs @@ -1,13 +1,18 @@ -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.Hosting; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Configuration; - +/* + * Jellyfin.Plugin.Webdav + * Copyright (C) 2025 Jellyfin contributors + * Licensed under GPLv3 + */ namespace Jellyfin.Plugin.Webdav { + using System.Threading; + using System.Threading.Tasks; + using MediaBrowser.Controller.Library; + using MediaBrowser.Model.Configuration; + using Microsoft.Extensions.Hosting; + /// - /// Hosted service that registers the WebDAV source as a virtual folder on server startup. + /// Hosted service that registers the WebDAV cache as a virtual folder on startup. /// public class WebDavHostedService : IHostedService { @@ -18,20 +23,15 @@ namespace Jellyfin.Plugin.Webdav _libraryManager = libraryManager; } + /// public async Task StartAsync(CancellationToken cancellationToken) { - // Register a virtual folder for WebDAV remote library - var options = new LibraryOptions - { - EnableInvertFolderHierarchy = false - }; + var options = new LibraryOptions(); - // Name must match plugin display name - await _libraryManager - .AddVirtualFolder("WebDAV", null, options, true) - .ConfigureAwait(false); + await _libraryManager.AddVirtualFolder("WebDAV", null, options, true).ConfigureAwait(false); } + /// public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } } \ No newline at end of file diff --git a/WebDavSyncService.cs b/WebDavSyncService.cs index f89cc01..673d654 100644 --- a/WebDavSyncService.cs +++ b/WebDavSyncService.cs @@ -1,75 +1,50 @@ -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; - +/* + * Jellyfin.Plugin.Webdav + * Copyright (C) 2025 Jellyfin contributors + * Licensed under GPLv3 + */ 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; + using System.IO; + using System.Threading; + using System.Threading.Tasks; + using MediaBrowser.Controller; + using MediaBrowser.Controller.Library; + using MediaBrowser.Model.Configuration; + using Microsoft.Extensions.Hosting; - public WebDavSyncService(WebDavClientService client, PluginConfiguration config, ILibraryManager libraryManager, IServerApplicationHost appHost) + /// + /// Hosted service that registers the WebDAV cache as a virtual folder on startup. + /// + public sealed class WebDavSyncService : IHostedService + { + private readonly IServerApplicationPaths appPaths; + private readonly ILibraryManager libraryManager; + + /// + /// Initializes a new instance of the class. + /// + /// Server application paths. + /// Library manager. + public WebDavSyncService(IServerApplicationPaths appPaths, ILibraryManager libraryManager) { - _client = client; - _config = config; - _libraryManager = libraryManager; - _appHost = appHost; + this.appPaths = appPaths; + this.libraryManager = libraryManager; } + /// public async Task StartAsync(CancellationToken cancellationToken) { - // Compute local root under DefaultUserViewsPath - var localRoot = Path.Combine(_appHost.ApplicationPaths.DefaultUserViewsPath, "WebDAV"); + var localRoot = Path.Combine(this.appPaths.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); - } - } + await this.libraryManager + .AddVirtualFolder("WebDAV", null, options, true) + .ConfigureAwait(false); } + /// public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } } \ No newline at end of file