using dy.net.model.dto; using dy.net.model.entity; using Microsoft.AspNetCore.DataProtection; using SqlSugar; using dy.net.utils; using MediaStorageType = dy.net.model.dto.StorageType; namespace dy.net.service { public class WebDavSettingsService { private const string SettingsId = "default"; private readonly ISqlSugarClient _db; private readonly IDataProtector _protector; public WebDavSettingsService(ISqlSugarClient db, IDataProtectionProvider provider) { _db = db; _protector = provider.CreateProtector("dysync.webdav.password.v1"); } public async Task GetAsync() { return await _db.Queryable().InSingleAsync(SettingsId) ?? new WebDavSettings { Id = SettingsId, BasePath = "/dysync" }; } public async Task GetPasswordAsync(WebDavSettings settings = null) { settings ??= await GetAsync(); if (string.IsNullOrWhiteSpace(settings.ProtectedPassword)) return string.Empty; try { return _protector.Unprotect(settings.ProtectedPassword); } catch (Exception ex) { Serilog.Log.Error(ex, "WebDAV 密码解密失败,请重新输入密码"); return string.Empty; } } public async Task BuildCandidateAsync(WebDavTestRequest request) { request ??= new WebDavTestRequest(); var existing = await GetAsync(); var password = string.IsNullOrWhiteSpace(request.Password) ? await GetPasswordAsync(existing) : request.Password; return new WebDavSettings { Id = SettingsId, Endpoint = string.IsNullOrWhiteSpace(request.Endpoint) ? existing.Endpoint : request.Endpoint.Trim(), BasePath = string.IsNullOrWhiteSpace(request.BasePath) ? existing.BasePath : request.BasePath.Trim(), UserName = string.IsNullOrWhiteSpace(request.UserName) ? existing.UserName : request.UserName.Trim(), ProtectedPassword = string.IsNullOrWhiteSpace(password) ? null : _protector.Protect(password), AllowInvalidCertificate = request.AllowInvalidCertificate }; } public async Task SaveAsync(WebDavSettings settings, bool tested, string testMessage) { settings.Id = SettingsId; settings.LastTestedAt = tested ? DateTime.Now : null; settings.LastTestMessage = testMessage; await _db.Storageable(settings).ExecuteCommandAsync(); } public async Task ToDtoAsync(MediaStorageType storageType) { var settings = await GetAsync(); return new WebDavSettingsDto { StorageType = storageType, Endpoint = settings.Endpoint, BasePath = settings.BasePath, UserName = settings.UserName, HasPassword = !string.IsNullOrWhiteSpace(settings.ProtectedPassword), AllowInvalidCertificate = settings.AllowInvalidCertificate, LastTestedAt = settings.LastTestedAt, LastTestMessage = settings.LastTestMessage }; } public async Task InitializeCookiePathsAsync() { var cookies = await _db.Queryable().ToListAsync(); foreach (var cookie in cookies) { ApplyDefaultCookiePaths(cookie); } if (cookies.Count > 0) await _db.Updateable(cookies).ExecuteCommandAsync(); } public void ApplyDefaultCookiePaths(DouyinCookie cookie) { if (cookie == null) return; var root = DouyinFileNameHelper.SanitizeLinuxFileName(cookie.UserName, cookie.Id, true); if (string.IsNullOrWhiteSpace(cookie.WebDavCollectPath)) cookie.WebDavCollectPath = $"/{root}/collect"; if (string.IsNullOrWhiteSpace(cookie.WebDavFavoritePath)) cookie.WebDavFavoritePath = $"/{root}/favorite"; if (string.IsNullOrWhiteSpace(cookie.WebDavFollowPath)) cookie.WebDavFollowPath = $"/{root}/follow"; if (string.IsNullOrWhiteSpace(cookie.WebDavMixPath)) cookie.WebDavMixPath = $"/{root}/mix"; if (string.IsNullOrWhiteSpace(cookie.WebDavSeriesPath)) cookie.WebDavSeriesPath = $"/{root}/series"; } } }