From 493f48cefe66bcf96194be700c00373b496f6608 Mon Sep 17 00:00:00 2001 From: real-zony Date: Sun, 16 Apr 2023 23:52:57 +0800 Subject: [PATCH 1/4] fix: Fixed the index exception that may be caused by the KuGou music provider. --- .../Lyrics/Providers/KuGou/KuGourLyricsProvider.cs | 7 ++++++- .../Lyrics/KuGouLyricProviderTests.cs | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/KuGou/KuGourLyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/KuGou/KuGourLyricsProvider.cs index 38497c5..712ae4e 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/KuGou/KuGourLyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/KuGou/KuGourLyricsProvider.cs @@ -40,6 +40,11 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou var accessKeyResponse = await _warpHttpClient.GetAsync(KuGouGetLyricAccessKeyUrl, new GetLyricAccessKeyRequest(searchResult.Data.List[0].FileHash)); + if (accessKeyResponse.AccessKeyDataObjects.Count == 0) + { + throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args); + } + var accessKeyObject = accessKeyResponse.AccessKeyDataObjects[0]; return await _warpHttpClient.GetAsync(KuGouGetLyricUrl, new GetLyricRequest(accessKeyObject.Id, accessKeyObject.AccessKey)); @@ -60,7 +65,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou protected virtual void ValidateSongSearchResponse(SongSearchResponse response, LyricsProviderArgs args) { - if (response.ErrorCode != 0 && response.Status != 1 || response.Data.List == null) + if ((response.ErrorCode != 0 && response.Status != 1) || response.Data.List.Count == 0) { throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args); } diff --git a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/KuGouLyricProviderTests.cs b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/KuGouLyricProviderTests.cs index ea36905..0adf68d 100644 --- a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/KuGouLyricProviderTests.cs +++ b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/KuGouLyricProviderTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Shouldly; using Xunit; +using ZonyLrcTools.Common.Infrastructure.Exceptions; using ZonyLrcTools.Common.Lyrics; namespace ZonyLrcTools.Tests.Infrastructure.Lyrics @@ -25,5 +26,18 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyrics lyric.ShouldNotBeNull(); lyric.IsPruneMusic.ShouldBe(false); } + + [Fact] + public async Task DownloadAsync_Issue133_Test() + { + await Should.ThrowAsync(_lyricsProvider.DownloadAsync("天ノ弱", "漆柚").AsTask); + } + + [Fact] + public async Task DownloadAsync_Index_Exception_Test() + { + var lyric = await _lyricsProvider.DownloadAsync("40'z", "ZOOLY"); + lyric.ToString().ShouldNotBeNullOrEmpty(); + } } } \ No newline at end of file From f935f076091b89abe8e3511c539c8438e5c6c0cb Mon Sep 17 00:00:00 2001 From: real-zony Date: Mon, 17 Apr 2023 00:47:23 +0800 Subject: [PATCH 2/4] feat: Modified the lyrics interface for Netease Cloud Music to support higher concurrency. --- .../Commands/SubCommand/DownloadCommand.cs | 2 +- .../Lyrics/LyricsDownloader.cs | 4 +- .../NetEase/JsonModel/GetLyricRequest.cs | 2 +- .../NetEase/JsonModel/SongSearchRequest.cs | 2 +- .../NetEase/NetEaseLyricsProvider.cs | 51 +++++++++++++------ .../ZonyLrcTools.Common.csproj | 1 + .../Lyrics/NetEaseLyricsProviderTests.cs | 7 +++ .../Lyrics/QQLyricsProviderTests.cs | 7 +++ 8 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/ZonyLrcTools.Cli/Commands/SubCommand/DownloadCommand.cs b/src/ZonyLrcTools.Cli/Commands/SubCommand/DownloadCommand.cs index cec3311..083aecb 100644 --- a/src/ZonyLrcTools.Cli/Commands/SubCommand/DownloadCommand.cs +++ b/src/ZonyLrcTools.Cli/Commands/SubCommand/DownloadCommand.cs @@ -47,7 +47,7 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand public bool DownloadAlbum { get; set; } [Option("-n|--number", CommandOptionType.SingleValue, Description = "指定下载时候的线程数量。(默认值 2)")] - public int ParallelNumber { get; set; } = 2; + public int ParallelNumber { get; set; } = 1; #endregion diff --git a/src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs b/src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs index f3fbbf1..74baf1f 100644 --- a/src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs +++ b/src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs @@ -1,5 +1,6 @@ using System.Text; using Microsoft.Extensions.Options; +using Polly; using ZonyLrcTools.Common.Configuration; using ZonyLrcTools.Common.Infrastructure.DependencyInject; using ZonyLrcTools.Common.Infrastructure.Exceptions; @@ -36,7 +37,7 @@ public class LyricsDownloader : ILyricsDownloader, ISingletonDependency } public async Task DownloadAsync(List needDownloadMusicInfos, - int parallelCount = 2, + int parallelCount = 1, CancellationToken cancellationToken = default) { await _logger.InfoAsync("开始下载歌词文件数据..."); @@ -106,6 +107,7 @@ public class LyricsDownloader : ILyricsDownloader, ISingletonDependency { _logger.LogWarningInfo(ex); info.IsSuccessful = false; + throw; } catch (Exception ex) { diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/GetLyricRequest.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/GetLyricRequest.cs index 98a5be8..acc04c5 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/GetLyricRequest.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/GetLyricRequest.cs @@ -8,7 +8,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel { public GetLyricRequest(long songId) { - OS = "ios"; + OS = "pc"; Id = songId; Lv = Kv = Tv = Rv = -1; } diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchRequest.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchRequest.cs index 14df5e8..86072ce 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchRequest.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchRequest.cs @@ -60,7 +60,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel var regex = new Regex(@"\([^)]*\)"); musicName = regex.Replace(musicName, string.Empty); - SearchKey = HttpUtility.UrlEncode($"{musicName}+{artistName}", Encoding.UTF8); + SearchKey = $"{musicName}+{artistName}"; Limit = limit; } } diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs index 56f10d8..3ba76b6 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs @@ -2,6 +2,7 @@ using System.Net.Http.Headers; using Microsoft.Extensions.Options; using Newtonsoft.Json; using ZonyLrcTools.Common.Configuration; +using ZonyLrcTools.Common.Infrastructure.Encryption; using ZonyLrcTools.Common.Infrastructure.Exceptions; using ZonyLrcTools.Common.Infrastructure.Network; using ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel; @@ -16,8 +17,8 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase private readonly ILyricsItemCollectionFactory _lyricsItemCollectionFactory; private readonly GlobalOptions _options; - private const string NetEaseSearchMusicUrl = @"https://music.163.com/api/search/get/web"; - private const string NetEaseGetLyricUrl = @"https://music.163.com/api/song/lyric"; + private const string NetEaseSearchMusicUrl = @"https://music.163.com/weapi/cloudsearch/get/web"; + private const string NetEaseGetLyricUrl = @"https://music.163.com/weapi/song/lyric?csrf_token="; private const string NetEaseRequestReferer = @"https://music.163.com"; private const string NetEaseRequestContentType = @"application/x-www-form-urlencoded"; @@ -33,25 +34,30 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase protected override async ValueTask DownloadDataAsync(LyricsProviderArgs args) { - var searchResult = await _warpHttpClient.PostAsync( - NetEaseSearchMusicUrl, - new SongSearchRequest(args.SongName, args.Artist, _options.Provider.Lyric.GetLyricProviderOption(DownloaderName).Depth), - true, - msg => + var secretKey = NetEaseMusicEncryptionHelper.CreateSecretKey(16); + var encSecKey = NetEaseMusicEncryptionHelper.RsaEncode(secretKey); + + var searchResult = await _warpHttpClient.PostAsync(NetEaseSearchMusicUrl, + requestOption: request => { - msg.Headers.Referrer = new Uri(NetEaseRequestReferer); - if (msg.Content != null) - { - msg.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(NetEaseRequestContentType); - } + request.Headers.Referrer = new Uri(NetEaseRequestReferer); + request.Content = new FormUrlEncodedContent(HandleRequest( + new SongSearchRequest(args.SongName, args.Artist, _options.Provider.Lyric.GetLyricProviderOption(DownloaderName).Depth), + secretKey, + encSecKey)); }); ValidateSongSearchResponse(searchResult, args); - return await _warpHttpClient.GetAsync( - NetEaseGetLyricUrl, - new GetLyricRequest(searchResult.GetFirstMatchSongId(args.SongName, args.Duration)), - msg => msg.Headers.Referrer = new Uri(NetEaseRequestReferer)); + return await _warpHttpClient.PostAsync(NetEaseGetLyricUrl, + requestOption: request => + { + request.Headers.Referrer = new Uri(NetEaseRequestReferer); + request.Content = new FormUrlEncodedContent(HandleRequest( + new GetLyricRequest(searchResult.GetFirstMatchSongId(args.SongName, args.Duration)), + secretKey, + encSecKey)); + }); } protected override async ValueTask GenerateLyricAsync(object lyricsObject, LyricsProviderArgs args) @@ -86,5 +92,18 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args); } } + + private Dictionary HandleRequest(object srcParams, string secretKey, string encSecKey) + { + return new Dictionary + { + { + "params", NetEaseMusicEncryptionHelper.AesEncode( + NetEaseMusicEncryptionHelper.AesEncode( + JsonConvert.SerializeObject(srcParams), NetEaseMusicEncryptionHelper.Nonce), secretKey) + }, + { "encSecKey", encSecKey } + }; + } } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/ZonyLrcTools.Common.csproj b/src/ZonyLrcTools.Common/ZonyLrcTools.Common.csproj index 114c0fd..2a19062 100644 --- a/src/ZonyLrcTools.Common/ZonyLrcTools.Common.csproj +++ b/src/ZonyLrcTools.Common/ZonyLrcTools.Common.csproj @@ -14,6 +14,7 @@ + diff --git a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs index 85a9190..c4c8611 100644 --- a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs +++ b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs @@ -105,5 +105,12 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyrics var lyric = await _lyricsProvider.DownloadAsync("橄榄树", "苏曼"); lyric.ToString().ShouldNotBeNullOrEmpty(); } + + [Fact] + public async Task DownloadAsync_Issue133_Test() + { + var lyric = await _lyricsProvider.DownloadAsync("Everything", "Yinyues"); + lyric.ToString().ShouldNotBeNullOrEmpty(); + } } } \ No newline at end of file diff --git a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/QQLyricsProviderTests.cs b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/QQLyricsProviderTests.cs index c9076d3..c16674f 100644 --- a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/QQLyricsProviderTests.cs +++ b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/QQLyricsProviderTests.cs @@ -37,5 +37,12 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyrics lyric.IsPruneMusic.ShouldBeFalse(); lyric.ToString().ShouldContain("你好像快要不能呼吸"); } + + [Fact] + public async Task DownloadAsync_Issue133_Test() + { + var lyric = await _lyricsProvider.DownloadAsync("天ノ弱", "漆柚"); + lyric.ToString().ShouldNotBeNullOrEmpty(); + } } } \ No newline at end of file From ab5f79bd5072a9b457d712fc2c9802ed75801caf Mon Sep 17 00:00:00 2001 From: real-zony Date: Mon, 17 Apr 2023 01:01:16 +0800 Subject: [PATCH 3/4] fix: Fixed the issue where Netease Cloud Music did not throw the correct exception when a song could not be found. --- .../Album/NetEase/NetEaseAlbumProvider.cs | 2 +- src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs | 1 - .../Providers/NetEase/JsonModel/SongSearchResponse.cs | 9 +++++++-- .../Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs | 5 ++--- .../Lyrics/NetEaseLyricsProviderTests.cs | 10 +++++++++- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/ZonyLrcTools.Common/Album/NetEase/NetEaseAlbumProvider.cs b/src/ZonyLrcTools.Common/Album/NetEase/NetEaseAlbumProvider.cs index 2d08c5c..a849fbf 100644 --- a/src/ZonyLrcTools.Common/Album/NetEase/NetEaseAlbumProvider.cs +++ b/src/ZonyLrcTools.Common/Album/NetEase/NetEaseAlbumProvider.cs @@ -41,7 +41,7 @@ namespace ZonyLrcTools.Common.Album.NetEase true, _defaultOption); - if (searchResult is not { StatusCode: 200 } || searchResult.Items?.SongCount <= 0) + if (searchResult is not { StatusCode: 200 } || searchResult.Items is not { SongCount: > 0 }) { throw new ErrorCodeException(ErrorCodes.NoMatchingSong); } diff --git a/src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs b/src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs index 74baf1f..a78440f 100644 --- a/src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs +++ b/src/ZonyLrcTools.Common/Lyrics/LyricsDownloader.cs @@ -107,7 +107,6 @@ public class LyricsDownloader : ILyricsDownloader, ISingletonDependency { _logger.LogWarningInfo(ex); info.IsSuccessful = false; - throw; } catch (Exception ex) { diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchResponse.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchResponse.cs index 6955e70..67150d5 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchResponse.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchResponse.cs @@ -4,12 +4,17 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel { public class SongSearchResponse { - [JsonProperty("result")] public InnerListItemModel Items { get; set; } + [JsonProperty("result")] public InnerListItemModel? Items { get; set; } [JsonProperty("code")] public int StatusCode { get; set; } public int GetFirstMatchSongId(string songName, long? duration) { + if (Items == null || Items.SongItems == null) + { + Console.Write("xx"); + } + var perfectMatch = Items.SongItems.FirstOrDefault(x => x.Name == songName); if (perfectMatch != null) { @@ -27,7 +32,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel public class InnerListItemModel { - [JsonProperty("songs")] public IList SongItems { get; set; } + [JsonProperty("songs")] public IList? SongItems { get; set; } [JsonProperty("songCount")] public int SongCount { get; set; } } diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs index 3ba76b6..8e52774 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs @@ -21,7 +21,6 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase private const string NetEaseGetLyricUrl = @"https://music.163.com/weapi/song/lyric?csrf_token="; private const string NetEaseRequestReferer = @"https://music.163.com"; - private const string NetEaseRequestContentType = @"application/x-www-form-urlencoded"; public NetEaseLyricsProvider(IWarpHttpClient warpHttpClient, ILyricsItemCollectionFactory lyricsItemCollectionFactory, @@ -49,7 +48,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase ValidateSongSearchResponse(searchResult, args); - return await _warpHttpClient.PostAsync(NetEaseGetLyricUrl, + return await _warpHttpClient.PostAsync(NetEaseGetLyricUrl, requestOption: request => { request.Headers.Referrer = new Uri(NetEaseRequestReferer); @@ -87,7 +86,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase throw new ErrorCodeException(ErrorCodes.TheReturnValueIsIllegal, attachObj: args); } - if (response.Items?.SongCount <= 0) + if (response.Items is not { SongCount: > 0 }) { throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args); } diff --git a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs index c4c8611..04f7b0f 100644 --- a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs +++ b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Options; using Shouldly; using Xunit; using ZonyLrcTools.Common.Configuration; +using ZonyLrcTools.Common.Infrastructure.Exceptions; using ZonyLrcTools.Common.Lyrics; namespace ZonyLrcTools.Tests.Infrastructure.Lyrics @@ -105,12 +106,19 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyrics var lyric = await _lyricsProvider.DownloadAsync("橄榄树", "苏曼"); lyric.ToString().ShouldNotBeNullOrEmpty(); } - + [Fact] public async Task DownloadAsync_Issue133_Test() { var lyric = await _lyricsProvider.DownloadAsync("Everything", "Yinyues"); lyric.ToString().ShouldNotBeNullOrEmpty(); } + + [Fact] + public async Task DownloadAsync_NullException_Test() + { + var result = await Should.ThrowAsync(_lyricsProvider.DownloadAsync("創世記", "りりィ").AsTask); + result.ErrorCode.ShouldBe(ErrorCodes.NoMatchingSong); + } } } \ No newline at end of file From 788ff38be27134f5debada41ecdcecb0d365d3c0 Mon Sep 17 00:00:00 2001 From: real-zony Date: Mon, 17 Apr 2023 01:13:06 +0800 Subject: [PATCH 4/4] fix: Fixed some unhandled exceptions. --- .../Lyrics/ILyricsItemCollectionFactory.cs | 2 +- .../Lyrics/LyricsItemCollectionFactory.cs | 2 +- .../Lyrics/Providers/KuWo/JsonModel/GetLyricsResponse.cs | 2 +- .../Lyrics/Providers/KuWo/KuWoLyricsProvider.cs | 5 +++++ .../Providers/NetEase/JsonModel/GetLyricResponse.cs | 2 +- .../Providers/NetEase/JsonModel/SongSearchResponse.cs | 5 ----- .../Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs | 2 +- .../Infrastructure/Lyrics/KuWoLyricsProviderTests.cs | 9 +++++++++ .../Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs | 9 +++++++++ 9 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/ZonyLrcTools.Common/Lyrics/ILyricsItemCollectionFactory.cs b/src/ZonyLrcTools.Common/Lyrics/ILyricsItemCollectionFactory.cs index 4cc5ad6..f5877c2 100644 --- a/src/ZonyLrcTools.Common/Lyrics/ILyricsItemCollectionFactory.cs +++ b/src/ZonyLrcTools.Common/Lyrics/ILyricsItemCollectionFactory.cs @@ -18,6 +18,6 @@ namespace ZonyLrcTools.Common.Lyrics /// 原始歌词数据。 /// 翻译歌词数据。 /// 构建完成的 对象。 - LyricsItemCollection Build(string sourceLyric, string translationLyric); + LyricsItemCollection Build(string sourceLyric, string? translationLyric); } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollectionFactory.cs b/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollectionFactory.cs index 64b0836..a248322 100644 --- a/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollectionFactory.cs +++ b/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollectionFactory.cs @@ -30,7 +30,7 @@ namespace ZonyLrcTools.Common.Lyrics return lyric; } - public LyricsItemCollection Build(string sourceLyric, string translationLyric) + public LyricsItemCollection Build(string sourceLyric, string? translationLyric) { var lyric = new LyricsItemCollection(_options.Provider.Lyric.Config); if (string.IsNullOrEmpty(sourceLyric)) diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/KuWo/JsonModel/GetLyricsResponse.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/KuWo/JsonModel/GetLyricsResponse.cs index 03f4de6..1805174 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/KuWo/JsonModel/GetLyricsResponse.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/KuWo/JsonModel/GetLyricsResponse.cs @@ -15,7 +15,7 @@ public class GetLyricsResponse public class GetLyricsResponseInnerData { - [JsonProperty("lrclist")] public ICollection Lyrics { get; set; } + [JsonProperty("lrclist")] public ICollection? Lyrics { get; set; } } public class GetLyricsItem diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/KuWo/KuWoLyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/KuWo/KuWoLyricsProvider.cs index e101b58..9d15c46 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/KuWo/KuWoLyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/KuWo/KuWoLyricsProvider.cs @@ -60,6 +60,11 @@ public class KuWoLyricsProvider : LyricsProvider await ValueTask.CompletedTask; var lyricsResponse = (GetLyricsResponse)lyricsObject; + if (lyricsResponse.Data.Lyrics == null) + { + return new LyricsItemCollection(null); + } + var items = lyricsResponse.Data.Lyrics.Select(l => { var position = double.Parse(l.Position); diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/GetLyricResponse.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/GetLyricResponse.cs index 1461b5a..4bb851f 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/GetLyricResponse.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/GetLyricResponse.cs @@ -20,7 +20,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel /// 如果存在翻译歌词,则本项内容为翻译歌词。 /// [JsonProperty("tlyric")] - public InnerLyric TranslationLyric { get; set; } + public InnerLyric? TranslationLyric { get; set; } /// /// 如果存在罗马音歌词,则本项内容为罗马音歌词。 diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchResponse.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchResponse.cs index 67150d5..314e810 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchResponse.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/JsonModel/SongSearchResponse.cs @@ -10,11 +10,6 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel public int GetFirstMatchSongId(string songName, long? duration) { - if (Items == null || Items.SongItems == null) - { - Console.Write("xx"); - } - var perfectMatch = Items.SongItems.FirstOrDefault(x => x.Name == songName); if (perfectMatch != null) { diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs index 8e52774..36f597f 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs @@ -76,7 +76,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase return _lyricsItemCollectionFactory.Build( json.OriginalLyric.Text, - json.TranslationLyric.Text); + json.TranslationLyric?.Text); } protected virtual void ValidateSongSearchResponse(SongSearchResponse response, LyricsProviderArgs args) diff --git a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/KuWoLyricsProviderTests.cs b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/KuWoLyricsProviderTests.cs index 258234a..d24a198 100644 --- a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/KuWoLyricsProviderTests.cs +++ b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/KuWoLyricsProviderTests.cs @@ -25,4 +25,13 @@ public class KuWoLyricsProviderTests : TestBase lyric.ShouldNotBeNull(); lyric.IsPruneMusic.ShouldBeFalse(); } + + [Fact] + public async Task DownloadAsync_Source_Null_Test() + { + var lyric = await _kuwoLyricsProvider.DownloadAsync("Concerto for Piano and Orchestra No. 12 in A major, K414 - 1. Allegro", + "Wolfgang Amadeus Mozart"); + + lyric.IsPruneMusic.ShouldBeTrue(); + } } \ No newline at end of file diff --git a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs index 04f7b0f..656f4e7 100644 --- a/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs +++ b/tests/ZonyLrcTools.Tests/Infrastructure/Lyrics/NetEaseLyricsProviderTests.cs @@ -120,5 +120,14 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyrics var result = await Should.ThrowAsync(_lyricsProvider.DownloadAsync("創世記", "りりィ").AsTask); result.ErrorCode.ShouldBe(ErrorCodes.NoMatchingSong); } + + [Fact] + public async Task DownloadAsync_Source_Null_Test() + { + var lyric = await _lyricsProvider.DownloadAsync("Concerto for Piano and Orchestra No. 12 in A major, K414 - 1. Allegro", + "Wolfgang Amadeus Mozart"); + + lyric.IsPruneMusic.ShouldBeTrue(); + } } } \ No newline at end of file