Esempio n. 1
0
 /// <summary>
 /// Creates a SongInfo from a JObject.
 /// </summary>
 /// <param name="song"></param>
 /// <exception cref="ArgumentException">Thrown when a hash can't be found for the given song JObject.</exception>
 /// <returns></returns>
 public static ScrapedSong ParseSongFromJson(JToken song, Uri?sourceUri, bool storeRawData)
 {
     if (song == null)
     {
         throw new ArgumentNullException(nameof(song), "song cannot be null for BeatSaverReader.ParseSongFromJson.");
     }
     if (song["versions"] is JArray versions && versions.Count > 0)
     {
         JObject latest = GetLatestSongVersion(song);
         //JSONObject song = (JSONObject) aKeyValue;
         string?  songKey    = song["id"]?.Value <string>();
         string?  songHash   = latest["hash"]?.Value <string>().ToUpper();
         string?  songName   = song["metadata"]?["songName"]?.Value <string>();
         string?  mapperName = song["uploader"]?["name"]?.Value <string>();
         DateTime uploadDate = song["uploaded"]?.Value <DateTime>() ?? DateTime.MinValue;
         if (songHash == null || songHash.Length == 0)
         {
             throw new ArgumentException("Unable to find hash for the provided song, is this a valid song JObject?");
         }
         Uri         downloadUri = WebUtils.GetDownloadUriByHash(songHash);
         ScrapedSong newSong     = new ScrapedSong(songHash, songName, mapperName, downloadUri, sourceUri, storeRawData ? song as JObject : null)
         {
             Key        = songKey,
             UploadDate = uploadDate
         };
         return(newSong);
     }
Esempio n. 2
0
        /// <summary>
        /// Creates a SongInfo from a JObject.
        /// </summary>
        /// <param name="song"></param>
        /// <exception cref="ArgumentException">Thrown when a hash can't be found for the given song JObject.</exception>
        /// <returns></returns>
        public static ScrapedSong ParseSongFromJson(JObject song, Uri sourceUrl)
        {
            if (song == null)
            {
                throw new ArgumentNullException(nameof(song), "song cannot be null for BeatSaverReader.ParseSongFromJson.");
            }
            //JSONObject song = (JSONObject) aKeyValue;
            string songKey    = song["key"]?.Value <string>();
            string songHash   = song["hash"]?.Value <string>().ToUpper();
            var    songName   = song["name"]?.Value <string>();
            var    mapperName = song["uploader"]?["username"]?.Value <string>();

            if (string.IsNullOrEmpty(songHash))
            {
                throw new ArgumentException("Unable to find hash for the provided song, is this a valid song JObject?");
            }
            string downloadUri = !string.IsNullOrEmpty(songKey) ? BEATSAVER_DOWNLOAD_URL_BASE + songKey : string.Empty;
            var    newSong     = new ScrapedSong(songHash)
            {
                DownloadUri = Utilities.GetUriFromString(downloadUri),
                SourceUri   = sourceUrl,
                SongName    = songName,
                SongKey     = songKey,
                MapperName  = mapperName,
                RawData     = song.ToString()
            };

            return(newSong);
        }
        public async Task AndruzzProviderTest()
        {
            string filePath = Path.Combine("Data", "SongInfoProvider", "songDetails2_20210817");
            var    manager  = new SongInfoManager();

            SongFeedReaders.Logging.LoggingController.DefaultLogger = new SongFeedReaders.Logging.FeedReaderLogger();
            var andruzz = new AndruzzScrapedInfoProvider(filePath)
            {
                CacheToDisk   = false,
                AllowWebFetch = false
            };

            manager.AddProvider(andruzz);
            Assert.IsFalse(andruzz.Available);
            var response = await manager.GetSongByKeyAsync("b");

            Assert.IsTrue(andruzz.Available);
            Assert.IsTrue(response.Success);
            ScrapedSong song = response.Song ?? throw new AssertFailedException("Song is null");

            Assert.AreEqual("B", song.Key);
            Assert.AreEqual("19F2879D11A91B51A5C090D63471C3E8D9B7AEE3", song.Hash);
            Assert.AreEqual("rustic", song.LevelAuthorName);
            Assert.AreEqual("Believer", song.Name);
        }
        public void Success_Authors_LimitedSongs()
        {
            BeatSaverReader reader = new BeatSaverReader()
            {
                StoreRawData = true
            };

            string[] authorList = new string[] { "BlackBlazon", "greatyazer", "joetastic" };
            Dictionary <string, ScrapedSong> songList = new Dictionary <string, ScrapedSong>();
            int maxSongs = 59;
            int maxPages = 10;
            SearchQueryBuilder queryBuilder = new SearchQueryBuilder(BeatSaverSearchType.author, null);

            foreach (string author in authorList)
            {
                queryBuilder.Criteria = author;
                BeatSaverFeedSettings settings = new BeatSaverFeedSettings((int)BeatSaverFeedName.Author)
                {
                    SearchQuery = queryBuilder.GetQuery(), MaxSongs = maxSongs, MaxPages = maxPages
                };
                FeedResult songsByAuthor = reader.GetSongsFromFeed(settings);
                Assert.IsTrue(songsByAuthor.Count > 0);
                Assert.IsTrue(songsByAuthor.Count <= maxSongs);
                int expectedPages = ExpectedPagesForSongs(songsByAuthor.Count);
                Assert.IsTrue(expectedPages <= songsByAuthor.PagesChecked);
                foreach (KeyValuePair <string, ScrapedSong> song in songsByAuthor.Songs)
                {
                    songList.TryAdd(song.Key, song.Value);
                }
            }
            IEnumerable <string> detectedAuthors = songList.Values.Select(s => s.LevelAuthorName.ToLower()).Distinct();

            foreach (KeyValuePair <string, ScrapedSong> song in songList)
            {
                Assert.IsTrue(song.Value.DownloadUri != null);
                Assert.IsTrue(authorList.Any(a => a.ToLower() == song.Value.LevelAuthorName.ToLower()));
            }
            foreach (string author in authorList)
            {
                Assert.IsTrue(songList.Any(s => s.Value.LevelAuthorName.ToLower() == author.ToLower()));
            }

            // BlackBlazon check
            string      blazonHash = "58de2d709a45b68fdb1dbbfefb187f59f629bfc5".ToUpper();
            ScrapedSong blazonSong = songList[blazonHash];

            Assert.IsTrue(blazonSong != null);
            Assert.IsTrue(blazonSong.DownloadUri != null);
            // GreatYazer check
            string      songHash  = "bf8c016dc6b9832ece3030f05277bbbe67db790d".ToUpper();
            ScrapedSong yazerSong = songList[songHash];

            Assert.IsTrue(yazerSong != null);
            Assert.IsTrue(yazerSong.DownloadUri != null);
            var checkedPages = songList.Values.Select(s => s.SourceUri.OriginalString).Distinct().ToList();

            checkedPages.ForEach(p => Console.WriteLine(p));
        }
Esempio n. 5
0
        public void TryAdd_Song_NotInitialized()
        {
            var    historyManager = new HistoryManager(HistoryTestPathDir);
            string hash           = "LKSJDFLKJASDLFKJ";
            string songName       = "TestName";
            string songKey        = "aaaa";
            string mapper         = "SomeMapper";
            ISong  song           = new ScrapedSong(hash, songName, mapper, songKey);

            Assert.ThrowsException <InvalidOperationException>(() => historyManager.TryAdd(song, 0));
        }
        public async Task BeatSaverProviderTest()
        {
            var manager = new SongInfoManager();

            SongFeedReaders.Logging.LoggingController.DefaultLogger = new SongFeedReaders.Logging.FeedReaderLogger();
            var beatSaver = new BeatSaverSongInfoProvider();

            manager.AddProvider(beatSaver);
            var response = await manager.GetSongByKeyAsync("b");

            Assert.IsTrue(response.Success);
            ScrapedSong song = response.Song ?? throw new AssertFailedException("Song is null");

            Assert.AreEqual("B", song.Key);
            Assert.AreEqual("19F2879D11A91B51A5C090D63471C3E8D9B7AEE3", song.Hash);
            Assert.AreEqual("rustic", song.LevelAuthorName);
            Assert.AreEqual("Believer", song.Name);
        }
Esempio n. 7
0
        public void TryAdd_Song()
        {
            var path           = Path.Combine(Path.Combine(HistoryTestPathDir, "BeatSyncHistory.json"));
            var historyManager = new HistoryManager(path);

            historyManager.Initialize();
            string hash     = "LKSJDFLKJASDLFKJ";
            string songName = "TestName";
            string songKey  = "aaaa";
            string mapper   = "SomeMapper";
            ISong  song     = new ScrapedSong(hash, songName, mapper, songKey);
            var    success  = historyManager.TryAdd(song, 0);

            Assert.IsTrue(success);
            success = historyManager.TryGetValue(hash, out var retrieved);
            Assert.IsTrue(success);
            Assert.AreEqual(song.ToString(), retrieved.SongInfo);
        }
Esempio n. 8
0
        public void TryAdd_Song_EmptyHash()
        {
            var path           = Path.Combine(Path.Combine(HistoryTestPathDir, "BeatSyncHistory.json"));
            var historyManager = new HistoryManager(path);

            historyManager.Initialize();
            string hash     = "";
            string songName = "TestName";
            string songKey  = "aaaa";
            string mapper   = "SomeMapper";

            try
            {
                ISong song = new ScrapedSong(hash, songName, mapper, songKey);
                Assert.ThrowsException <InvalidOperationException>(() => historyManager.TryAdd(song, 0));
            }
            catch (ArgumentNullException)
            {
                //Assert.Inconclusive("PlaylistSong.Hash can never be null or empty.");
            }
        }
Esempio n. 9
0
 public static PlaylistSong ToPlaylistSong(this ScrapedSong song)
 {
     return(new PlaylistSong(song.Hash, song.SongName, song.SongKey, song.MapperName));
 }
Esempio n. 10
0
        public static async Task <ScrapedSong> GetSongByKeyAsync(string key, CancellationToken cancellationToken)
        {
            var                 uri      = new Uri(BEATSAVER_DETAILS_BASE_URL + key);
            string              pageText = "";
            ScrapedSong         song     = null;
            IWebResponseMessage response = null;

            try
            {
                response = await WebUtils.GetBeatSaverAsync(uri, cancellationToken).ConfigureAwait(false);

                if (response.IsSuccessStatusCode)
                {
                    pageText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                }
                else
                {
                    Logger?.Error($"Error getting song by key, {uri} responded with {response.StatusCode}:{response.ReasonPhrase}");
                    return(song);
                }
                if (string.IsNullOrEmpty(pageText))
                {
                    Logger?.Warning($"Unable to get web page at {uri}");
                    return(null);
                }
            }
            catch (WebClientException ex)
            {
                string errorText = string.Empty;
                if (ex.Response != null)
                {
                    switch (ex.Response.StatusCode)
                    {
                    case 408:
                        errorText = "Timeout";
                        break;

                    default:
                        errorText = "Site Error";
                        break;
                    }
                }
                Logger?.Error($"{errorText} while trying to populate fields for {key}");
                return(null);
            }
            catch (AggregateException ae)
            {
                ae.WriteExceptions($"Exception while trying to get details for {key}");
            }
            catch (Exception ex)
            {
                Logger?.Exception($"Exception getting page {uri}", ex);
                throw;
            }
            finally
            {
                response?.Dispose();
                response = null;
            }
            song = ParseSongsFromPage(pageText, uri).FirstOrDefault();
            return(song);
        }
Esempio n. 11
0
        public static async Task <PageReadResult> GetSongByHashAsync(string hash, CancellationToken cancellationToken)
        {
            var                 uri       = new Uri(BEATSAVER_GETBYHASH_BASE_URL + hash);
            ScrapedSong         song      = null;
            var                 pageError = PageErrorType.None;
            Exception           exception = null;
            IWebResponseMessage response  = null;

            try
            {
                response = await WebUtils.GetBeatSaverAsync(uri, cancellationToken).ConfigureAwait(false);

                response.EnsureSuccessStatusCode();
                var pageText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                song = ParseSongsFromPage(pageText, uri).FirstOrDefault();
            }
            catch (WebClientException ex)
            {
                string errorText = string.Empty;
                if (ex.Response != null)
                {
                    switch (ex.Response.StatusCode)
                    {
                    case 408:
                        errorText = "Timeout";
                        break;

                    default:
                        errorText = "Site Error";
                        break;
                    }
                }
                string message = $"{errorText} while trying to populate fields for {hash}";
                Logger?.Error(message);
                exception = new FeedReaderException(message, ex, FeedReaderFailureCode.PageFailed);
            }
            catch (OperationCanceledException ex)
            {
                exception = new FeedReaderException(ex.Message, ex, FeedReaderFailureCode.Cancelled);
            }
            catch (AggregateException ae)
            {
                string message = $"Exception while trying to get details for {hash}";
                ae.WriteExceptions(message);
                exception = new FeedReaderException(message, ae, FeedReaderFailureCode.Generic);
            }
            catch (Exception ex)
            {
                string message = $"Exception getting page {uri.ToString()}";
                Logger?.Exception(message, ex);
                exception = new FeedReaderException(message, ex, FeedReaderFailureCode.Generic);
            }
            finally
            {
                response?.Dispose();
                response = null;
            }
            List <ScrapedSong> retList = new List <ScrapedSong>();

            if (song != null)
            {
                retList.Add(song);
            }
            return(new PageReadResult(uri, retList, exception, pageError));
        }