using dy.net.model.dto; using dy.net.model.entity; using dy.net.utils; using Newtonsoft.Json; namespace dy.net.storage { public static class StorageArtifactCleaner { public static async Task DeleteWebDavArtifactsAsync( IMediaStorage storage, DouyinVideo video, CancellationToken cancellationToken = default) { if (storage == null || video == null || !video.StorageType.IsRemote()) return; var paths = new HashSet(StringComparer.Ordinal) { video.VideoSavePath, video.VideoCoverSavePath }; foreach (var nfoPath in NfoContentBuilder.Build(video).Keys) { // tvshow.nfo is shared by every episode in a mix/series directory. if (!Path.GetFileName(nfoPath).Equals("tvshow.nfo", StringComparison.OrdinalIgnoreCase)) paths.Add(nfoPath); } if (!string.IsNullOrWhiteSpace(video.DynamicVideos)) { try { var related = JsonConvert.DeserializeObject>(video.DynamicVideos); foreach (var item in related ?? new List()) { if (!string.IsNullOrWhiteSpace(item.Path)) paths.Add(item.Path); } } catch (JsonException ex) { Serilog.Log.Warning(ex, "解析远端附属文件清单失败:{VideoId}", video.AwemeId); } } foreach (var path in paths.Where(x => !string.IsNullOrWhiteSpace(x))) { try { if (StoragePath.NormalizeRemote(path) != "/") await storage.DeleteAsync(path, cancellationToken); } catch (Exception ex) { Serilog.Log.Warning(ex, "清理远端媒体文件失败:{Path}", path); } } } } }