public void Success_Filtered360() { BeatSaverReader reader = new BeatSaverReader() { StoreRawData = true }; int maxSongs = 20; int maxPages = 30; BeatSaverFeedSettings settings = new BeatSaverFeedSettings((int)BeatSaverFeedName.Latest) { MaxSongs = maxSongs, MaxPages = maxPages }; Progress <ReaderProgress> progress = new Progress <ReaderProgress>(p => { if (p.SongCount > 0) { Console.WriteLine($"Progress: Page {p.CurrentPage} found {p.SongCount} songs."); } else { Console.WriteLine($"Progress: Page {p.CurrentPage} did not have any songs."); } }); bool stopAfter(ScrapedSong song) { DateTime uploadDate = song.JsonData["uploaded"].Value <DateTime>(); bool shouldStop = uploadDate < (DateTime.Now - TimeSpan.FromDays(5)); if (shouldStop) { Console.WriteLine($"StopWhenAny reached with {song.Key} ({uploadDate.ToString()})"); } return(shouldStop); } Func <ScrapedSong, bool> filter = SongFeedReaders.Filtering.BuiltInFilters.ThreeSixtyDegree; settings.Filter = filter; settings.StopWhenAny = stopAfter; FeedResult result = reader.GetSongsFromFeedAsync(settings, progress, CancellationToken.None).Result; Assert.IsTrue(result.Count > 0 && result.Count < maxPages * settings.SongsPerPage); int expectedPages = ExpectedPagesForSongs(result.Count); Assert.IsTrue(expectedPages <= result.PagesChecked); Console.WriteLine($"----------------"); foreach (ScrapedSong song in result.Songs.Values) { Console.WriteLine($"{song.Name} by {song.LevelAuthorName}, {song.Hash}"); } }
protected async Task <JobStats> GetBeatSaverAsync(BeatSyncConfig config, IJobBuilder jobBuilder, JobManager jobManager, CancellationToken cancellationToken) { BeatSaverConfig sourceConfig = config.BeatSaver; JobStats sourceStats = new JobStats(); if (!sourceConfig.Enabled) { return(sourceStats); } BeatSaverReader reader = new BeatSaverReader(); FeedConfigBase[] feedConfigs = new FeedConfigBase[] { sourceConfig.Hot, sourceConfig.Downloads, sourceConfig.Latest }; if (!(feedConfigs.Any(f => f.Enabled) || sourceConfig.FavoriteMappers.Enabled)) { Logger.log?.Info($"No feeds enabled for {reader.Name}"); return(sourceStats); } SourceStarted?.Invoke(this, "BeatSaver"); foreach (FeedConfigBase?feedConfig in feedConfigs.Where(c => c.Enabled)) { Logger.log?.Info($" Starting {feedConfig.GetType().Name} feed..."); FeedResult results = await reader.GetSongsFromFeedAsync(feedConfig.ToFeedSettings(), cancellationToken).ConfigureAwait(false); if (results.Successful) { IEnumerable <IJob>?jobs = CreateJobs(results, jobBuilder, jobManager, cancellationToken); JobResult[] jobResults = await Task.WhenAll(jobs.Select(j => j.JobTask).ToArray()); JobStats feedStats = new JobStats(jobResults); ProcessFinishedJobs(jobs, jobBuilder.SongTargets, config, feedConfig); Logger.log?.Info($" Finished {feedConfig.GetType().Name} feed: ({feedStats})."); sourceStats += feedStats; } else { if (results.Exception != null) { Logger.log?.Error($" Error getting results from {feedConfig.GetType().Name}{results.Exception.Message}"); Logger.log?.Debug($"{results.Exception}"); } else { Logger.log?.Error($" Error getting results from {feedConfig.GetType().Name}: Unknown error."); } } } string[] mappers = sourceConfig.FavoriteMappers.Mappers ?? Array.Empty <string>(); if (sourceConfig.FavoriteMappers.Enabled) { FeedConfigBase feedConfig = sourceConfig.FavoriteMappers; if (mappers.Length > 0) { Logger.log?.Info(" Starting FavoriteMappers feed..."); List <IPlaylist> playlists = new List <IPlaylist>(); List <IPlaylist> feedPlaylists = new List <IPlaylist>(); List <IPlaylist> recentPlaylists = new List <IPlaylist>(); JobStats feedStats = new JobStats(); foreach (string?mapper in mappers) { Logger.log?.Info($" Getting songs by {mapper}..."); playlists.Clear(); FeedResult results = await reader.GetSongsFromFeedAsync(sourceConfig.FavoriteMappers.ToFeedSettings(mapper)).ConfigureAwait(false); if (results.Successful) { foreach (ITargetWithPlaylists?targetWithPlaylist in jobBuilder.SongTargets.Where(t => t is ITargetWithPlaylists).Select(t => (ITargetWithPlaylists)t)) { PlaylistManager?playlistManager = targetWithPlaylist.PlaylistManager; if (playlistManager != null) { if (config.RecentPlaylistDays > 0) { recentPlaylists.Add(playlistManager.GetOrAddPlaylist(BuiltInPlaylist.BeatSyncRecent)); } if (config.AllBeatSyncSongsPlaylist) { playlists.Add(playlistManager.GetOrAddPlaylist(BuiltInPlaylist.BeatSyncAll)); } if (sourceConfig.FavoriteMappers.CreatePlaylist) { IPlaylist feedPlaylist; try { if (sourceConfig.FavoriteMappers.SeparateMapperPlaylists) { feedPlaylist = playlistManager.GetOrCreateAuthorPlaylist(mapper); } else { feedPlaylist = playlistManager.GetOrAddPlaylist(BuiltInPlaylist.BeatSaverFavoriteMappers); } feedPlaylists.Add(feedPlaylist); playlists.Add(feedPlaylist); } catch (ArgumentException ex) { Logger.log?.Error($"Error getting playlist for FavoriteMappers: {ex.Message}"); Logger.log?.Debug(ex); } } } } IEnumerable <IJob> jobs = CreateJobs(results, jobBuilder, jobManager, cancellationToken) ?? Array.Empty <IJob>(); JobResult[] jobResults = await Task.WhenAll(jobs.Select(j => j.JobTask).ToArray()); JobStats mapperStats = new JobStats(jobResults); feedStats += mapperStats; if (jobs.Any(j => j.Result?.Successful ?? false) && feedConfig.PlaylistStyle == PlaylistStyle.Replace) { // TODO: This should only apply to successful targets. foreach (IPlaylist?feedPlaylist in feedPlaylists) { feedPlaylist.Clear(); feedPlaylist.RaisePlaylistChanged(); } } ProcessFinishedJobs(jobs, playlists, recentPlaylists); Logger.log?.Info($" Finished getting songs by {mapper}: ({mapperStats})."); } else { if (results.Exception != null) { Logger.log?.Error($"Error getting songs by {mapper}: {results.Exception.Message}"); Logger.log?.Debug(results.Exception); } else { Logger.log?.Error($"Error getting songs by {mapper}"); } } } sourceStats += feedStats; Logger.log?.Info($" Finished {feedConfig.GetType().Name} feed: ({feedStats})."); } else { Logger.log?.Warn(" No FavoriteMappers found, skipping..."); } } Logger.log?.Info($" Finished BeatSaver reading: ({sourceStats})."); return(sourceStats); }