using Serilog; namespace TvSyncApp { public class Loader { private readonly Downloader _downloader; public Loader() { _downloader = new Downloader(); } public async Task<(int Success, int Failed)> LoadJsonAsync( Dictionary directories, List updateList, Dictionary updateDict, Settings settings, int maxParallelDownloads = 5) { int success = 0; int failed = 0; int completed = 0; var semaphore = new System.Threading.SemaphoreSlim(maxParallelDownloads); var filesNeeded = new List<(string Directory, string FileName)>(); foreach (var seriesId in updateList) { foreach (var dir in directories.Values) { string filePath = Path.Combine(dir, $"{seriesId}.json"); if (!File.Exists(filePath)) filesNeeded.Add((dir, $"{seriesId}.json")); } } Log.Information("Downloading {Count} files...", filesNeeded.Count); var totalFiles = filesNeeded.Count; var progress = new Progress(value => { completed += value; Console.Write($"\rDownloading files: {completed}/{totalFiles}"); }); var tasks = new List(); foreach (var file in filesNeeded) { tasks.Add(DownloadWithThrottleAsync(file.Directory, file.FileName, settings, semaphore, progress)); } await Task.WhenAll(tasks); Console.WriteLine("\nDownload complete."); foreach (var file in filesNeeded) { string path = Path.Combine(file.Directory, file.FileName); if (File.Exists(path)) success++; else failed++; } return (success, failed); } private async Task DownloadWithThrottleAsync( string directory, string fileName, Settings settings, System.Threading.SemaphoreSlim semaphore, IProgress progress) { await semaphore.WaitAsync(); try { string seriesId = Path.GetFileNameWithoutExtension(fileName); string url; if (directory.Contains("series", StringComparison.OrdinalIgnoreCase)) url = settings.Json.ShowApi.Replace("", seriesId); else if (directory.Contains("episodes", StringComparison.OrdinalIgnoreCase)) url = settings.Json.EpisodeApi.Replace("", seriesId); else if (directory.Contains("cast", StringComparison.OrdinalIgnoreCase)) url = settings.Json.CastApi.Replace("", seriesId); else if (directory.Contains("crew", StringComparison.OrdinalIgnoreCase)) url = settings.Json.CrewApi.Replace("", seriesId); else url = $"https://api.tvmaze.com/shows/{seriesId}"; // Download the file await Task.Run(() => _downloader.Download(url, directory, fileName, Log.Logger)); // Report progress progress?.Report(1); } catch (Exception ex) { Log.Error(ex, "Failed to download {FileName}", fileName); progress?.Report(1); // still report so progress moves forward } finally { semaphore.Release(); } } } }