using MoreLinq; using NLog; using Sony.Filtr.ErrorLogging; using Sony.Filtr.Playlists.Spotify; using Sony.Filtr.SpotifyWebAPI; using Sony.Filtr.Utility.Extensions; using System; using System.Collections.Generic; using System.Threading.Tasks; using Sony.Filtr.SpotifyImages; using System.Threading.Tasks.Dataflow; using Sony.Filtr.SpotifyWebAPI.Model; namespace Sony.Filtr.Tasks.Helpers { public class UpdateAlbumsHelper { private readonly SpotifyWebApi _spotifyWebApi; private readonly SpotifyImageDownloader _spotifyImageHandler; private readonly SpotifyAlbumManager _spotifyAlbumManager; private readonly Logger _logger; public UpdateAlbumsHelper(SpotifyWebApi spotifyWebApi, SpotifyImageDownloader spotifyImageHandler, SpotifyAlbumManager spotifyAlbumManager) { _spotifyWebApi = spotifyWebApi; _spotifyImageHandler = spotifyImageHandler; _spotifyAlbumManager = spotifyAlbumManager; _logger = LogManager.GetLogger(nameof(UpdateAlbumsHelper)); } internal async Task SaveSpotifyAlbumImagesAsync(ICollection albumIds) { try { _logger.Debug($"Will fetch images for {albumIds.Count} albums"); var loadAlbumsBlock = new TransformManyBlock, FullAlbumItem>(async ids => { try { return await this._spotifyWebApi.GetAllAlbumInfoAsync(ids); } catch (Exception ex) { _logger.Error(ex, $"Could not load albums batch"); ErrorLoggingManager.Instance.LogError(ex); } return null; }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 }); var saveAlbumDataBlock = new ActionBlock(async album => { try { _logger.Debug($"Getting image for {album.id}"); var filename = await _spotifyImageHandler.SaveSmallestAlbumImageAsync(album); _logger.Debug($"Saving image filename for {album.id}"); await _spotifyAlbumManager.UpdateAlbumImageAsync(album.id, filename); } catch (Exception ex) { _logger.Error(ex, $"Could not save data for album '{album.id}'"); ErrorLoggingManager.Instance.LogError(ex); } }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 15 }); loadAlbumsBlock.LinkTo(saveAlbumDataBlock, new DataflowLinkOptions { PropagateCompletion = true }, dto => dto != null); loadAlbumsBlock.LinkTo(DataflowBlock.NullTarget(), new DataflowLinkOptions { PropagateCompletion = true }); foreach (var batch in albumIds.Batch(20)) { await loadAlbumsBlock.SendAsync(batch); } loadAlbumsBlock.Complete(); await saveAlbumDataBlock.Completion; } catch (Exception ex) { ErrorLoggingManager.Instance.LogError(ex); _logger.Error(ex, "Could not save album Spotify images. Exception: {1}", ex); } } } }