コード例 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="_settings"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="InvalidCastException">Throw when the provided settings object isn't a BeatSaverFeedSettings</exception>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="_settings"/> is null.</exception>
        public async Task <FeedResult> GetSongsFromScoreSaberAsync(ScoreSaberFeedSettings _settings, IProgress <ReaderProgress> progress, CancellationToken cancellationToken)
        {
            if (_settings == null)
            {
                throw new ArgumentNullException(nameof(_settings), "settings cannot be null for ScoreSaberReader.GetSongsFromScoreSaberAsync");
            }
            if (!(_settings is ScoreSaberFeedSettings settings))
            {
                throw new InvalidCastException(INVALIDFEEDSETTINGSMESSAGE);
            }
            // "https://scoresaber.com/api.php?function=get-leaderboards&cat={CATKEY}&limit={LIMITKEY}&page={PAGENUMKEY}&ranked={RANKEDKEY}"
            int songsPerPage = settings.SongsPerPage;

            if (songsPerPage == 0)
            {
                songsPerPage = 100;
            }
            int pageNum = settings.StartingPage;
            //int maxPages = (int)Math.Ceiling(settings.MaxSongs / ((float)songsPerPage));
            int maxPages     = settings.MaxPages;
            int pagesChecked = 0;

            if (pageNum > 1 && maxPages != 0)
            {
                maxPages = maxPages + pageNum - 1;
            }
            //if (settings.MaxPages > 0)
            //    maxPages = maxPages < settings.MaxPages ? maxPages : settings.MaxPages; // Take the lower limit.
            var feed = new ScoreSaberFeed(settings);

            try
            {
                feed.EnsureValidSettings();
            }
            catch (InvalidFeedSettingsException ex)
            {
                return(new FeedResult(null, null, ex, FeedResultError.Error));
            }
            Dictionary <string, ScrapedSong> songs = new Dictionary <string, ScrapedSong>();

            var            pageResults = new List <PageReadResult>();
            Uri            uri         = feed.GetUriForPage(1);
            PageReadResult result      = await feed.GetSongsAsync(uri, cancellationToken).ConfigureAwait(false);

            pageResults.Add(result);
            foreach (var song in result.Songs)
            {
                if (!songs.ContainsKey(song.Hash) && (songs.Count < settings.MaxSongs || settings.MaxSongs == 0))
                {
                    songs.Add(song.Hash, song);
                }
            }
            pagesChecked++;
            progress?.Report(new ReaderProgress(pagesChecked, songs.Count));
            bool continueLooping = true;

            do
            {
                pageNum++;
                //int diffCount = 0;
                if ((maxPages > 0 && pageNum > maxPages) || (settings.MaxSongs > 0 && songs.Count >= settings.MaxSongs))
                {
                    break;
                }
                if (Utilities.IsPaused)
                {
                    await Utilities.WaitUntil(() => !Utilities.IsPaused, 500).ConfigureAwait(false);
                }

                // TODO: Handle PageReadResult here
                uri = feed.GetUriForPage(pageNum);
                var pageResult = await feed.GetSongsAsync(uri, cancellationToken).ConfigureAwait(false);

                pageResults.Add(pageResult);
                if (pageResult.PageError == PageErrorType.Cancelled)
                {
                    return(FeedResult.GetCancelledResult(songs, pageResults));
                }
                int uniqueSongCount = 0;
                foreach (var song in pageResult.Songs)
                {
                    //diffCount++;
                    if (!songs.ContainsKey(song.Hash) && (songs.Count < settings.MaxSongs || settings.MaxSongs == 0))
                    {
                        songs.Add(song.Hash, song);
                        uniqueSongCount++;
                    }
                }

                int prog = Interlocked.Increment(ref pagesChecked);
                progress?.Report(new ReaderProgress(prog, uniqueSongCount));
                if (uniqueSongCount > 0)
                {
                    Logger?.Debug($"Receiving {uniqueSongCount} potential songs from {pageResult.Uri}");
                }
                else
                {
                    Logger?.Debug($"Did not find any new songs on page '{pageResult.Uri}' of {Name}.{settings.FeedName}.");
                }
                if (pageResult.IsLastPage)
                {
                    Logger?.Debug($"Last page reached.");
                    continueLooping = false;
                }
                if (!pageResult.Successful)
                {
                    Logger?.Debug($"Page {pageResult.Uri.ToString()} failed, ending read.");
                    if (pageResult.Exception != null)
                    {
                        Logger?.Debug($"{pageResult.Exception.Message}\n{pageResult.Exception.StackTrace}");
                    }
                    continueLooping = false;
                }

                //pageReadTasks.Add(GetSongsFromPageAsync(url.ToString()));
                if ((maxPages > 0 && pageNum >= maxPages) || (settings.MaxSongs > 0 && songs.Count >= settings.MaxSongs))
                {
                    continueLooping = false;
                }
            } while (continueLooping);


            if (pageResults.Any(r => r.PageError == PageErrorType.Cancelled))
            {
                return(FeedResult.GetCancelledResult(songs, pageResults));
            }
            return(new FeedResult(songs, pageResults));
        }
コード例 #2
0
 public ScoreSaberFeedSettings(ScoreSaberFeed feed)
 {
     Feed         = feed;
     SongsPerPage = 100;
     StartingPage = 1;
 }