public ProcessPlaylistsJob( ILogger <ProcessPlaylistsJob> logger, UserManager <ApplicationUser> userManager, IPlaylistRepository playlistRepository, IEntryRepository entryRepository, IUnitOfWork unitOfWork, IOptions <StorageSettings> storageSettings, IOptions <ImageFileStorageSettings> imageFileStorageSettings, IOptions <AppSettings> appSettings, IYouTubeParser youTubeParser, MixcloudParser mixcloudParser) : base(logger) { _userManager = userManager; _unitOfWork = unitOfWork; _imageFileStorageSettings = imageFileStorageSettings.Value; _youTubeParser = youTubeParser; _mixcloudParser = mixcloudParser; _playlistRepository = playlistRepository; _entryRepository = entryRepository; _storageSettings = storageSettings.Value; _appSettings = appSettings.Value; }
public async Task <bool> Execute(Guid playlistId, PerformContext context) { Log($"Starting playlist processing for {playlistId}"); context.WriteLine($"Starting playlist processing for {playlistId}"); try { var playlist = await _playlistRepository.GetAsync(playlistId); var cutoffDate = await _playlistRepository.GetCutoffDate(playlistId); var user = playlist.Podcast.AppUser; //first check user has a valid subscription var subs = user.GetCurrentSubscription(); var isGod = await _userManager.IsInRoleAsync(user, "god-mode"); if (subs is null && !isGod) { LogWarning($"User: {user.Id} does not have a valid subscription"); return(false); } //next check quotas Log("Checking quotas"); var quota = user.DiskQuota ?? _storageSettings.DefaultUserQuota; var totalUsed = (await _entryRepository.GetAllForUserAsync(user.Id)) .Select(x => x.AudioFileSize) .Sum(); if (totalUsed >= quota) { LogError($"Storage quota exceeded for {user.GetBestGuessName()}"); BackgroundJob.Enqueue <INotifyJobCompleteService>( service => service.NotifyUser( user.Id.ToString(), $"Failure processing playlist\n{playlist.Podcast.Title}\n", $"Your have exceeded your storage quota of {quota.Bytes().ToString()}", playlist.Podcast.GetAuthenticatedUrl(_appSettings.SiteUrl), playlist.Podcast.GetThumbnailUrl(_storageSettings.CdnUrl, _imageFileStorageSettings.ContainerName), NotificationOptions.StorageExceeded )); return(false); } Log("Quotas passed"); //check for active subscription var resultList = new List <ParsedItemResult>(); var count = user.PlaylistAllowedEntryCount ?? _storageSettings.DefaultEntryCount; if (_youTubeParser.ValidateUrl(playlist.SourceUrl)) { Log("Parsing YouTube"); var url = playlist.SourceUrl; resultList = await _youTubeParser .GetEntries( url, user.Id, cutoffDate, count); } else if (MixcloudParser.ValidateUrl(playlist.SourceUrl)) { Log("Parsing MixCloud"); var entries = await _mixcloudParser .GetEntries(playlist.SourceUrl, count); resultList = entries .OrderBy(r => r.UploadDate) .Take(_storageSettings.DefaultEntryCount) .ToList(); } Log($"Found {resultList.Count} candidates"); //order in reverse so the newest item is added first foreach (var item in resultList.Where(item => playlist.PodcastEntries.All(e => e.SourceItemId != item.Id))) { await _trimPlaylist(playlist, count); Log($"Found candidate\n\tParsedId:{item.Id}\n\tPodcastId:{playlist.Podcast.Id}\n\t{playlist.Id}"); BackgroundJob .Enqueue <ProcessPlaylistItemJob>( service => service.Execute(item, playlist.Id, null) ); } Log($"Finished playlists"); return(true); } catch (PlaylistExpiredException) { //TODO: Remove playlist and notify user LogError($"Playlist: {playlistId} cannot be found"); } catch (Exception ex) { LogError(ex.Message); context.WriteLine($"ERROR(ProcessPlayListJob): {ex.Message}"); } return(false); }