From 7d17fc0b97a65e2d399e8c3426e98f8ade1d17d6 Mon Sep 17 00:00:00 2001 From: real-zony Date: Sun, 23 Oct 2022 13:38:51 +0800 Subject: [PATCH] refactor: Refactor lyrics download logic and abstract a new logger. --- .../Commands/SubCommand/DownloadCommand.cs | 140 +++--------------- .../Logging/SerilogWarpLogger.cs | 42 ++++++ .../Infrastructure/Extensions/LoggerHelper.cs | 13 +- .../Infrastructure/IO/FileScanner.cs | 9 +- .../Infrastructure/Logging/IWarpLogger.cs | 9 ++ .../Lyrics/DefaultLyricsDownloader.cs | 127 ++++++++++++++++ .../Lyrics/ILyricsDownloader.cs | 6 +- .../Lyrics/ILyricsItemCollectionFactory.cs | 14 +- .../Lyrics/ILyricsProvider.cs | 2 +- .../Lyrics/ILyricsTextResolver.cs | 2 +- src/ZonyLrcTools.Common/Lyrics/LyricsItem.cs | 2 +- ...mCollection.cs => LyricsItemCollection.cs} | 10 +- .../Lyrics/LyricsItemCollectionFactory.cs | 16 +- .../Lyrics/LyricsProvider.cs | 4 +- .../Providers/KuGou/KuGourLyricsProvider.cs | 2 +- .../NetEase/NetEaseLyricsProvider.cs | 6 +- .../Providers/QQMusic/QQLyricsProvider.cs | 2 +- .../Lyric/LyricCollectionTests.cs | 2 +- 18 files changed, 245 insertions(+), 163 deletions(-) create mode 100644 src/ZonyLrcTools.Cli/Infrastructure/Logging/SerilogWarpLogger.cs create mode 100644 src/ZonyLrcTools.Common/Infrastructure/Logging/IWarpLogger.cs create mode 100644 src/ZonyLrcTools.Common/Lyrics/DefaultLyricsDownloader.cs rename src/ZonyLrcTools.Common/Lyrics/{LyricItemCollection.cs => LyricsItemCollection.cs} (91%) diff --git a/src/ZonyLrcTools.Cli/Commands/SubCommand/DownloadCommand.cs b/src/ZonyLrcTools.Cli/Commands/SubCommand/DownloadCommand.cs index 3f87fdf..b1a126e 100644 --- a/src/ZonyLrcTools.Cli/Commands/SubCommand/DownloadCommand.cs +++ b/src/ZonyLrcTools.Cli/Commands/SubCommand/DownloadCommand.cs @@ -1,12 +1,9 @@ -using System; using System.Collections.Generic; using System.Collections.Immutable; using System.IO; using System.Linq; -using System.Text; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using ZonyLrcTools.Cli.Infrastructure.Tag; using ZonyLrcTools.Common; @@ -15,6 +12,7 @@ using ZonyLrcTools.Common.Configuration; using ZonyLrcTools.Common.Infrastructure.Exceptions; using ZonyLrcTools.Common.Infrastructure.Extensions; using ZonyLrcTools.Common.Infrastructure.IO; +using ZonyLrcTools.Common.Infrastructure.Logging; using ZonyLrcTools.Common.Infrastructure.Threading; using ZonyLrcTools.Common.Lyrics; using File = System.IO.File; @@ -24,26 +22,25 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand [Command("download", Description = "下载歌词文件或专辑图像。")] public class DownloadCommand : ToolCommandBase { - private readonly ILogger _logger; + private readonly ILyricsDownloader _lyricsDownloader; private readonly IFileScanner _fileScanner; - private readonly ITagLoader _tagLoader; - private readonly IEnumerable _lyricDownloaderList; private readonly IEnumerable _albumDownloaderList; + private readonly ITagLoader _tagLoader; + private readonly IWarpLogger _logger; private readonly GlobalOptions _options; - public DownloadCommand(ILogger logger, - IFileScanner fileScanner, + public DownloadCommand(IFileScanner fileScanner, IOptions options, + IEnumerable albumDownloaderList, ITagLoader tagLoader, - IEnumerable lyricDownloaderList, - IEnumerable albumDownloaderList) + ILyricsDownloader lyricsDownloader, IWarpLogger logger) { - _logger = logger; _fileScanner = fileScanner; - _tagLoader = tagLoader; - _lyricDownloaderList = lyricDownloaderList; _albumDownloaderList = albumDownloaderList; + _tagLoader = tagLoader; + _lyricsDownloader = lyricsDownloader; + _logger = logger; _options = options.Value; } @@ -62,18 +59,14 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand [Option("-n|--number", CommandOptionType.SingleValue, Description = "指定下载时候的线程数量。(默认值 2)")] public int ParallelNumber { get; set; } = 2; - [Option] public string ErrorMessage { get; set; } = Path.Combine(Directory.GetCurrentDirectory(), "error.log"); - #endregion protected override async Task OnExecuteAsync(CommandLineApplication app) { if (DownloadLyric) { - await DownloadLyricFilesAsync( - await LoadMusicInfoAsync( - RemoveExistLyricFiles( - await ScanMusicFilesAsync()))); + var musicInfos = await LoadMusicInfoAsync(RemoveExistLyricFiles(await ScanMusicFilesAsync())); + await _lyricsDownloader.DownloadAsync(musicInfos.ToList(), ParallelNumber); } if (DownloadAlbum) @@ -94,11 +87,11 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand if (files.Count == 0) { - _logger.LogError("没有找到任何音乐文件。"); + await _logger.ErrorAsync("没有找到任何音乐文件。"); throw new ErrorCodeException(ErrorCodes.NoFilesWereScanned); } - _logger.LogInformation($"已经扫描到了 {files.Count} 个音乐文件。"); + await _logger.InfoAsync($"已经扫描到了 {files.Count} 个音乐文件。"); return files; } @@ -118,7 +111,7 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand return true; } - _logger.LogWarning($"已经存在歌词文件 {path},跳过。"); + _logger.WarnAsync($"已经存在歌词文件 {path},跳过。").GetAwaiter().GetResult(); return false; }) .ToList(); @@ -126,7 +119,7 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand private async Task> LoadMusicInfoAsync(IReadOnlyCollection files) { - _logger.LogInformation("开始加载音乐文件的标签信息..."); + await _logger.InfoAsync("开始加载音乐文件的标签信息..."); var warpTask = new WarpTask(ParallelNumber); var warpTaskList = files.Select(file => warpTask.RunAsync(() => Task.Run(async () => await _tagLoader.LoadTagAsync(file)))); @@ -138,111 +131,16 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand // Load music total time info. // result.Foreach(m => { m.TotalTime = (long?)new AudioFileReader(m.FilePath).TotalTime.TotalMilliseconds; }); - _logger.LogInformation($"已成功加载 {files.Count} 个音乐文件的标签信息。"); + await _logger.InfoAsync($"已成功加载 {files.Count} 个音乐文件的标签信息。"); return result.ToImmutableList(); } - private IEnumerable GetLyricDownloaderList() - { - var downloader = _options.Provider.Lyric.Plugin - .Where(op => op.Priority != -1) - .OrderBy(op => op.Priority) - .Join(_lyricDownloaderList, - op => op.Name, - loader => loader.DownloaderName, - (op, loader) => loader); - - return downloader; - } - - #region > Lyric download logic < - - private async ValueTask DownloadLyricFilesAsync(ImmutableList musicInfos) - { - _logger.LogInformation("开始下载歌词文件数据..."); - - var downloaderList = GetLyricDownloaderList(); - var warpTask = new WarpTask(ParallelNumber); - var warpTaskList = musicInfos.Select(info => - warpTask.RunAsync(() => Task.Run(async () => await DownloadLyricTaskLogicAsync(downloaderList, info)))); - - await Task.WhenAll(warpTaskList); - - _logger.LogInformation($"歌词数据下载完成,成功: {musicInfos.Count(m => m.IsSuccessful)} 失败{musicInfos.Count(m => m.IsSuccessful == false)}。"); - } - - private async Task DownloadLyricTaskLogicAsync(IEnumerable downloaderList, MusicInfo info) - { - async Task InternalDownloadLogicAsync(ILyricsProvider downloader) - { - try - { - var lyric = await downloader.DownloadAsync(info.Name, info.Artist, info.TotalTime); - var lyricFilePath = Path.Combine(Path.GetDirectoryName(info.FilePath)!, - $"{Path.GetFileNameWithoutExtension(info.FilePath)}.lrc"); - - if (File.Exists(lyricFilePath)) - { - File.Delete(lyricFilePath); - } - - info.IsSuccessful = true; - - if (lyric.IsPruneMusic) - { - return; - } - - await using var stream = new FileStream(lyricFilePath, FileMode.Create); - await using var sw = new BinaryWriter(stream); - - sw.Write(EncodingConvert(lyric)); - await stream.FlushAsync(); - } - catch (ErrorCodeException ex) - { - info.IsSuccessful = ex.ErrorCode == ErrorCodes.NoMatchingSong; - - _logger.LogWarningInfo(ex); - } - catch (Exception ex) - { - _logger.LogError($"下载歌词文件时发生错误:{ex.Message},歌曲名: {info.Name},歌手: {info.Artist}。"); - info.IsSuccessful = false; - } - } - - foreach (var downloader in downloaderList) - { - await InternalDownloadLogicAsync(downloader); - - if (info.IsSuccessful) - { - _logger.LogSuccessful(info); - return; - } - } - } - - private byte[] EncodingConvert(LyricItemCollection lyric) - { - var supportEncodings = Encoding.GetEncodings(); - if (supportEncodings.All(x => x.Name != _options.Provider.Lyric.Config.FileEncoding)) - { - throw new ErrorCodeException(ErrorCodes.NotSupportedFileEncoding); - } - - return Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(_options.Provider.Lyric.Config.FileEncoding), lyric.GetUtf8Bytes()); - } - - #endregion - #region > Ablum image download logic < private async ValueTask DownloadAlbumAsync(ImmutableList musicInfos) { - _logger.LogInformation("开始下载专辑图像数据..."); + await _logger.InfoAsync("开始下载专辑图像数据..."); var downloader = _albumDownloaderList.FirstOrDefault(d => d.DownloaderName == InternalAlbumDownloaderNames.NetEase); var warpTask = new WarpTask(ParallelNumber); @@ -251,7 +149,7 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand await Task.WhenAll(warpTaskList); - _logger.LogInformation($"专辑数据下载完成,成功: {musicInfos.Count(m => m.IsSuccessful)} 失败{musicInfos.Count(m => m.IsSuccessful == false)}。"); + await _logger.InfoAsync($"专辑数据下载完成,成功: {musicInfos.Count(m => m.IsSuccessful)} 失败{musicInfos.Count(m => m.IsSuccessful == false)}。"); } private async Task DownloadAlbumTaskLogicAsync(IAlbumDownloader downloader, MusicInfo info) diff --git a/src/ZonyLrcTools.Cli/Infrastructure/Logging/SerilogWarpLogger.cs b/src/ZonyLrcTools.Cli/Infrastructure/Logging/SerilogWarpLogger.cs new file mode 100644 index 0000000..f859c95 --- /dev/null +++ b/src/ZonyLrcTools.Cli/Infrastructure/Logging/SerilogWarpLogger.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using ZonyLrcTools.Common.Infrastructure.DependencyInject; +using ZonyLrcTools.Common.Infrastructure.Logging; + +namespace ZonyLrcTools.Cli.Infrastructure.Logging; + +public class SerilogWarpLogger : IWarpLogger, ITransientDependency +{ + private readonly ILogger _logger; + + public SerilogWarpLogger(ILogger logger) + { + _logger = logger; + } + + public Task DebugAsync(string message, Exception exception = null) + { + _logger.LogDebug(message, exception); + + return Task.CompletedTask; + } + + public Task InfoAsync(string message, Exception exception = null) + { + _logger.LogInformation(message, exception); + return Task.CompletedTask; + } + + public Task WarnAsync(string message, Exception exception = null) + { + _logger.LogWarning(message, exception); + return Task.CompletedTask; + } + + public Task ErrorAsync(string message, Exception exception = null) + { + _logger.LogError(message, exception); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Infrastructure/Extensions/LoggerHelper.cs b/src/ZonyLrcTools.Common/Infrastructure/Extensions/LoggerHelper.cs index 87a950d..ca999bc 100644 --- a/src/ZonyLrcTools.Common/Infrastructure/Extensions/LoggerHelper.cs +++ b/src/ZonyLrcTools.Common/Infrastructure/Extensions/LoggerHelper.cs @@ -2,6 +2,7 @@ using System.Text; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using ZonyLrcTools.Common.Infrastructure.Exceptions; +using ZonyLrcTools.Common.Infrastructure.Logging; namespace ZonyLrcTools.Common.Infrastructure.Extensions { @@ -16,9 +17,9 @@ namespace ZonyLrcTools.Common.Infrastructure.Extensions /// 日志记录器实例。 /// 错误码,具体请参考 类的定义。 /// 异常实例,可为空。 - public static void LogWarningWithErrorCode(this ILogger logger, int errorCode, Exception e = null) + public static void LogWarningWithErrorCode(this IWarpLogger logger, int errorCode, Exception e = null) { - logger.LogWarning($"错误代码: {errorCode}\n堆栈异常: {e?.StackTrace}"); + logger.WarnAsync($"错误代码: {errorCode}\n堆栈异常: {e?.StackTrace}").GetAwaiter().GetResult(); } /// @@ -26,7 +27,7 @@ namespace ZonyLrcTools.Common.Infrastructure.Extensions /// /// 日志记录器的实例。 /// 错误码异常实例。 - public static void LogWarningInfo(this ILogger logger, ErrorCodeException exception) + public static void LogWarningInfo(this IWarpLogger logger, ErrorCodeException exception) { if (exception.ErrorCode < 50000) { @@ -36,7 +37,7 @@ namespace ZonyLrcTools.Common.Infrastructure.Extensions var sb = new StringBuilder(); sb.Append($"错误代码: {exception.ErrorCode},信息: {ErrorCodeHelper.GetMessage(exception.ErrorCode)}"); sb.Append($"\n附加信息:\n {JsonConvert.SerializeObject(exception.AttachObject)}"); - logger.LogWarning(sb.ToString()); + logger.WarnAsync(sb.ToString()).GetAwaiter().GetResult(); } /// @@ -44,9 +45,9 @@ namespace ZonyLrcTools.Common.Infrastructure.Extensions /// /// 日志记录器的实例。 /// 需要打印的歌曲信息。 - public static void LogSuccessful(this ILogger logger, MusicInfo musicInfo) + public static void LogSuccessful(this IWarpLogger logger, MusicInfo musicInfo) { - logger.LogInformation($"歌曲名: {musicInfo.Name}, 艺术家: {musicInfo.Artist}, 下载成功."); + logger.InfoAsync($"歌曲名: {musicInfo.Name}, 艺术家: {musicInfo.Artist}, 下载成功.").GetAwaiter().GetResult(); } } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Infrastructure/IO/FileScanner.cs b/src/ZonyLrcTools.Common/Infrastructure/IO/FileScanner.cs index c519d47..3ea9218 100644 --- a/src/ZonyLrcTools.Common/Infrastructure/IO/FileScanner.cs +++ b/src/ZonyLrcTools.Common/Infrastructure/IO/FileScanner.cs @@ -4,16 +4,17 @@ using Microsoft.Extensions.Logging.Abstractions; using ZonyLrcTools.Common.Infrastructure.DependencyInject; using ZonyLrcTools.Common.Infrastructure.Exceptions; using ZonyLrcTools.Common.Infrastructure.Extensions; +using ZonyLrcTools.Common.Infrastructure.Logging; namespace ZonyLrcTools.Common.Infrastructure.IO { public class FileScanner : IFileScanner, ITransientDependency { - public ILogger Logger { get; set; } + private readonly IWarpLogger _logger; - public FileScanner() + public FileScanner(IWarpLogger logger) { - Logger = NullLogger.Instance; + _logger = logger; } public Task> ScanAsync(string path, IEnumerable extensions) @@ -58,7 +59,7 @@ namespace ZonyLrcTools.Common.Infrastructure.IO } catch (Exception e) { - Logger.LogWarningWithErrorCode(ErrorCodes.ScanFileError, e); + _logger.LogWarningWithErrorCode(ErrorCodes.ScanFileError, e); } } } diff --git a/src/ZonyLrcTools.Common/Infrastructure/Logging/IWarpLogger.cs b/src/ZonyLrcTools.Common/Infrastructure/Logging/IWarpLogger.cs new file mode 100644 index 0000000..c522a63 --- /dev/null +++ b/src/ZonyLrcTools.Common/Infrastructure/Logging/IWarpLogger.cs @@ -0,0 +1,9 @@ +namespace ZonyLrcTools.Common.Infrastructure.Logging; + +public interface IWarpLogger +{ + Task DebugAsync(string message, Exception? exception = null); + Task InfoAsync(string message, Exception? exception = null); + Task WarnAsync(string message, Exception? exception = null); + Task ErrorAsync(string message, Exception? exception = null); +} \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Lyrics/DefaultLyricsDownloader.cs b/src/ZonyLrcTools.Common/Lyrics/DefaultLyricsDownloader.cs new file mode 100644 index 0000000..740afcb --- /dev/null +++ b/src/ZonyLrcTools.Common/Lyrics/DefaultLyricsDownloader.cs @@ -0,0 +1,127 @@ +using System.Text; +using Microsoft.Extensions.Options; +using ZonyLrcTools.Common.Configuration; +using ZonyLrcTools.Common.Infrastructure.DependencyInject; +using ZonyLrcTools.Common.Infrastructure.Exceptions; +using ZonyLrcTools.Common.Infrastructure.Extensions; +using ZonyLrcTools.Common.Infrastructure.Logging; +using ZonyLrcTools.Common.Infrastructure.Threading; + +namespace ZonyLrcTools.Common.Lyrics; + +public class DefaultLyricsDownloader : ILyricsDownloader, ISingletonDependency +{ + private readonly IEnumerable _lyricDownloaderList; + private readonly GlobalOptions _options; + private readonly IWarpLogger _logger; + + public IEnumerable AvailableProviders => new Lazy>(() => + { + return _options.Provider.Lyric.Plugin + .Where(op => op.Priority != -1) + .OrderBy(op => op.Priority) + .Join(_lyricDownloaderList, + op => op.Name, + loader => loader.DownloaderName, + (op, loader) => loader); + }).Value; + + public DefaultLyricsDownloader(IEnumerable lyricDownloaderList, + IOptions options, + IWarpLogger logger) + { + _lyricDownloaderList = lyricDownloaderList; + _logger = logger; + _options = options.Value; + } + + public async Task> DownloadAsync(List needDownloadMusicInfos, + int parallelCount = 2, + CancellationToken cancellationToken = default) + { + await _logger.InfoAsync("开始下载歌词文件数据..."); + if (parallelCount <= 0) + { + parallelCount = 1; + } + + var warpTask = new WarpTask(parallelCount); + var downloadTasks = needDownloadMusicInfos.Select(info => + warpTask.RunAsync(() => + Task.Run(async () => + { + // Try to download lyrics from all available providers. + foreach (var lyricsProvider in AvailableProviders) + { + await DownloadAndWriteLyricsAsync(lyricsProvider, info); + + if (info.IsSuccessful) + { + _logger.LogSuccessful(info); + return; + } + } + }, cancellationToken), cancellationToken)); + + await Task.WhenAll(downloadTasks); + + await _logger.InfoAsync($"歌词数据下载完成,成功: {needDownloadMusicInfos.Count(m => m.IsSuccessful)} 失败{needDownloadMusicInfos.Count(m => m.IsSuccessful == false)}。"); + + return needDownloadMusicInfos; + } + + private async Task DownloadAndWriteLyricsAsync(ILyricsProvider provider, MusicInfo info) + { + try + { + var lyrics = await provider.DownloadAsync(info.Name, info.Artist); + + if (lyrics.IsPruneMusic) + { + info.IsSuccessful = true; + return; + } + + var newLyricsFilePath = Path.Combine(Path.GetDirectoryName(info.FilePath)!, + $"{Path.GetFileNameWithoutExtension(info.FilePath)}.lrc"); + + if (File.Exists(newLyricsFilePath)) + { + File.Delete(newLyricsFilePath); + } + + // Write lyrics to file. + await using (var fileStream = new FileStream(newLyricsFilePath, FileMode.CreateNew, FileAccess.Write)) + { + await using (var binaryWriter = new BinaryWriter(fileStream, Encoding.UTF8)) + { + binaryWriter.Write(Utf8ToSelectedEncoding(lyrics)); + binaryWriter.Flush(); + } + } + + info.IsSuccessful = true; + } + catch (ErrorCodeException ex) + { + _logger.LogWarningInfo(ex); + info.IsSuccessful = false; + } + catch (Exception ex) + { + await _logger.ErrorAsync($"下载歌词文件时发生错误:{ex.Message},歌曲名: {info.Name},歌手: {info.Artist}。"); + info.IsSuccessful = false; + } + } + + private byte[] Utf8ToSelectedEncoding(LyricsItemCollection lyrics) + { + var supportEncodings = Encoding.GetEncodings(); + if (supportEncodings.All(x => x.Name != _options.Provider.Lyric.Config.FileEncoding)) + { + throw new ErrorCodeException(ErrorCodes.NotSupportedFileEncoding); + } + + return Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(_options.Provider.Lyric.Config.FileEncoding), lyrics.GetUtf8Bytes()); + } +} \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Lyrics/ILyricsDownloader.cs b/src/ZonyLrcTools.Common/Lyrics/ILyricsDownloader.cs index f7eecbb..d5a9da3 100644 --- a/src/ZonyLrcTools.Common/Lyrics/ILyricsDownloader.cs +++ b/src/ZonyLrcTools.Common/Lyrics/ILyricsDownloader.cs @@ -2,5 +2,9 @@ public interface ILyricsDownloader { - + Task> DownloadAsync(List needDownloadMusicInfos, + int parallelCount = 2, + CancellationToken cancellationToken = default); + + IEnumerable AvailableProviders { get; } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Lyrics/ILyricsItemCollectionFactory.cs b/src/ZonyLrcTools.Common/Lyrics/ILyricsItemCollectionFactory.cs index ecb2208..5085801 100644 --- a/src/ZonyLrcTools.Common/Lyrics/ILyricsItemCollectionFactory.cs +++ b/src/ZonyLrcTools.Common/Lyrics/ILyricsItemCollectionFactory.cs @@ -1,23 +1,23 @@ namespace ZonyLrcTools.Common.Lyrics { /// - /// 构建 对象的工厂。 + /// 构建 对象的工厂。 /// public interface ILyricsItemCollectionFactory { /// - /// 根据指定的歌曲数据构建新的 实例。 + /// 根据指定的歌曲数据构建新的 实例。 /// /// 原始歌词数据。 - /// 构建完成的 对象。 - LyricItemCollection Build(string sourceLyric); + /// 构建完成的 对象。 + LyricsItemCollection Build(string sourceLyric); /// - /// 根据指定的歌曲数据构建新的 实例。 + /// 根据指定的歌曲数据构建新的 实例。 /// /// 原始歌词数据。 /// 翻译歌词数据。 - /// 构建完成的 对象。 - LyricItemCollection Build(string sourceLyric, string translationLyric); + /// 构建完成的 对象。 + LyricsItemCollection Build(string sourceLyric, string translationLyric); } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Lyrics/ILyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/ILyricsProvider.cs index 37c11ce..b9d16b3 100644 --- a/src/ZonyLrcTools.Common/Lyrics/ILyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/ILyricsProvider.cs @@ -12,7 +12,7 @@ namespace ZonyLrcTools.Common.Lyrics /// 歌曲的作者。 /// 歌曲的时长。 /// 歌曲的歌词数据对象。 - ValueTask DownloadAsync(string songName, string artist, long? duration = null); + ValueTask DownloadAsync(string songName, string artist, long? duration = null); /// /// 下载器的名称。 diff --git a/src/ZonyLrcTools.Common/Lyrics/ILyricsTextResolver.cs b/src/ZonyLrcTools.Common/Lyrics/ILyricsTextResolver.cs index 0c577dd..de63cdc 100644 --- a/src/ZonyLrcTools.Common/Lyrics/ILyricsTextResolver.cs +++ b/src/ZonyLrcTools.Common/Lyrics/ILyricsTextResolver.cs @@ -2,6 +2,6 @@ namespace ZonyLrcTools.Common.Lyrics { public interface ILyricsTextResolver { - LyricItemCollection Resolve(string lyricText); + LyricsItemCollection Resolve(string lyricText); } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Lyrics/LyricsItem.cs b/src/ZonyLrcTools.Common/Lyrics/LyricsItem.cs index 0e96ee7..c47e006 100644 --- a/src/ZonyLrcTools.Common/Lyrics/LyricsItem.cs +++ b/src/ZonyLrcTools.Common/Lyrics/LyricsItem.cs @@ -3,7 +3,7 @@ using System.Text.RegularExpressions; namespace ZonyLrcTools.Common.Lyrics { /// - /// 歌词的行对象,是 的最小单位。。 + /// 歌词的行对象,是 的最小单位。。 /// public class LyricsItem : IComparable { diff --git a/src/ZonyLrcTools.Common/Lyrics/LyricItemCollection.cs b/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollection.cs similarity index 91% rename from src/ZonyLrcTools.Common/Lyrics/LyricItemCollection.cs rename to src/ZonyLrcTools.Common/Lyrics/LyricsItemCollection.cs index ce54589..5ffe206 100644 --- a/src/ZonyLrcTools.Common/Lyrics/LyricItemCollection.cs +++ b/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollection.cs @@ -7,7 +7,7 @@ namespace ZonyLrcTools.Common.Lyrics /// /// 歌词数据,包含多条歌词行对象()。 /// - public class LyricItemCollection : List + public class LyricsItemCollection : List { /// /// 是否为纯音乐,当没有任何歌词数据的时候,属性值为 True。 @@ -16,12 +16,12 @@ namespace ZonyLrcTools.Common.Lyrics public GlobalLyricsConfigOptions Options { get; private set; } - public LyricItemCollection(GlobalLyricsConfigOptions options) + public LyricsItemCollection(GlobalLyricsConfigOptions options) { Options = options; } - public static LyricItemCollection operator +(LyricItemCollection left, LyricItemCollection right) + public static LyricsItemCollection operator +(LyricsItemCollection left, LyricsItemCollection right) { if (right.IsPruneMusic) { @@ -29,7 +29,7 @@ namespace ZonyLrcTools.Common.Lyrics } var option = left.Options; - var newCollection = new LyricItemCollection(option); + var newCollection = new LyricsItemCollection(option); var indexDiff = left.Count - right.Count; if (!option.IsOneLine) { @@ -91,7 +91,7 @@ namespace ZonyLrcTools.Common.Lyrics /// 这个索引字典用于标识每个索引的歌词是否被处理,为 True 则为已处理,为 False 为未处理。 /// /// 等待构建的歌词集合实例。 - private static Dictionary BuildMarkDictionary(LyricItemCollection items) + private static Dictionary BuildMarkDictionary(LyricsItemCollection items) { return items .Select((item, index) => new { index, item }) diff --git a/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollectionFactory.cs b/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollectionFactory.cs index b31f592..874adf4 100644 --- a/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollectionFactory.cs +++ b/src/ZonyLrcTools.Common/Lyrics/LyricsItemCollectionFactory.cs @@ -17,9 +17,9 @@ namespace ZonyLrcTools.Common.Lyrics _options = options.Value; } - public LyricItemCollection Build(string sourceLyric) + public LyricsItemCollection Build(string sourceLyric) { - var lyric = new LyricItemCollection(_options.Provider.Lyric.Config); + var lyric = new LyricsItemCollection(_options.Provider.Lyric.Config); if (string.IsNullOrEmpty(sourceLyric)) { return lyric; @@ -30,9 +30,9 @@ namespace ZonyLrcTools.Common.Lyrics return lyric; } - public LyricItemCollection Build(string sourceLyric, string translationLyric) + public LyricsItemCollection Build(string sourceLyric, string translationLyric) { - var lyric = new LyricItemCollection(_options.Provider.Lyric.Config); + var lyric = new LyricsItemCollection(_options.Provider.Lyric.Config); if (string.IsNullOrEmpty(sourceLyric)) { return lyric; @@ -42,7 +42,7 @@ namespace ZonyLrcTools.Common.Lyrics if (_options.Provider.Lyric.Config.IsEnableTranslation && !string.IsNullOrEmpty(translationLyric)) { - var translatedLyric = InternalBuildLyricObject(new LyricItemCollection(_options.Provider.Lyric.Config), translationLyric); + var translatedLyric = InternalBuildLyricObject(new LyricsItemCollection(_options.Provider.Lyric.Config), translationLyric); if (_options.Provider.Lyric.Config.IsOnlyOutputTranslation) { return translatedLyric; @@ -54,15 +54,15 @@ namespace ZonyLrcTools.Common.Lyrics return lyric; } - private LyricItemCollection InternalBuildLyricObject(LyricItemCollection lyric, string sourceText) + private LyricsItemCollection InternalBuildLyricObject(LyricsItemCollection lyrics, string sourceText) { var regex = new Regex(@"\[\d+:\d+.\d+\].+\n?"); foreach (Match match in regex.Matches(sourceText)) { - lyric.Add(new LyricsItem(match.Value)); + lyrics.Add(new LyricsItem(match.Value)); } - return lyric; + return lyrics; } } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Lyrics/LyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/LyricsProvider.cs index 5f10326..e335f1b 100644 --- a/src/ZonyLrcTools.Common/Lyrics/LyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/LyricsProvider.cs @@ -17,7 +17,7 @@ namespace ZonyLrcTools.Common.Lyrics /// 歌曲作者/艺术家。 /// 歌曲的时长。 /// 下载完成的歌曲数据。 - public virtual async ValueTask DownloadAsync(string songName, string artist, long? duration = null) + public virtual async ValueTask DownloadAsync(string songName, string artist, long? duration = null) { var args = new LyricsProviderArgs(songName, artist, duration ?? 0); await ValidateAsync(args); @@ -53,6 +53,6 @@ namespace ZonyLrcTools.Common.Lyrics /// 根据指定的歌词二进制数据,生成歌词数据。 /// /// 歌词的原始二进制数据。 - protected abstract ValueTask GenerateLyricAsync(byte[] data, LyricsProviderArgs args); + protected abstract ValueTask GenerateLyricAsync(byte[] data, LyricsProviderArgs args); } } \ No newline at end of file diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/KuGou/KuGourLyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/KuGou/KuGourLyricsProvider.cs index 6ec43c4..6ef2114 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/KuGou/KuGourLyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/KuGou/KuGourLyricsProvider.cs @@ -47,7 +47,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou return Encoding.UTF8.GetBytes(lyricResponse); } - protected override async ValueTask GenerateLyricAsync(byte[] data, LyricsProviderArgs args) + protected override async ValueTask GenerateLyricAsync(byte[] data, LyricsProviderArgs args) { await ValueTask.CompletedTask; var lyricJsonObj = JObject.Parse(Encoding.UTF8.GetString(data)); diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs index 94b2b3c..39db86c 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/NetEase/NetEaseLyricsProvider.cs @@ -57,19 +57,19 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase return Encoding.UTF8.GetBytes(lyricResponse); } - protected override async ValueTask GenerateLyricAsync(byte[] data, LyricsProviderArgs args) + protected override async ValueTask GenerateLyricAsync(byte[] data, LyricsProviderArgs args) { await ValueTask.CompletedTask; var json = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data)); if (json?.OriginalLyric == null || string.IsNullOrEmpty(json.OriginalLyric.Text)) { - return new LyricItemCollection(null); + return new LyricsItemCollection(null); } if (json.OriginalLyric.Text.Contains("纯音乐,请欣赏")) { - return new LyricItemCollection(null); + return new LyricsItemCollection(null); } return _lyricsItemCollectionFactory.Build( diff --git a/src/ZonyLrcTools.Common/Lyrics/Providers/QQMusic/QQLyricsProvider.cs b/src/ZonyLrcTools.Common/Lyrics/Providers/QQMusic/QQLyricsProvider.cs index a613174..5fe5388 100644 --- a/src/ZonyLrcTools.Common/Lyrics/Providers/QQMusic/QQLyricsProvider.cs +++ b/src/ZonyLrcTools.Common/Lyrics/Providers/QQMusic/QQLyricsProvider.cs @@ -42,7 +42,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.QQMusic return Encoding.UTF8.GetBytes(lyricJsonString); } - protected override async ValueTask GenerateLyricAsync(byte[] data, LyricsProviderArgs args) + protected override async ValueTask GenerateLyricAsync(byte[] data, LyricsProviderArgs args) { await ValueTask.CompletedTask; diff --git a/tests/ZonyLrcTools.Tests/Infrastructure/Lyric/LyricCollectionTests.cs b/tests/ZonyLrcTools.Tests/Infrastructure/Lyric/LyricCollectionTests.cs index d127455..3603c02 100644 --- a/tests/ZonyLrcTools.Tests/Infrastructure/Lyric/LyricCollectionTests.cs +++ b/tests/ZonyLrcTools.Tests/Infrastructure/Lyric/LyricCollectionTests.cs @@ -10,7 +10,7 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyric [Fact] public void LyricCollectionLineBreak_Test() { - var lyricObject = new LyricItemCollection(new GlobalLyricsConfigOptions + var lyricObject = new LyricsItemCollection(new GlobalLyricsConfigOptions { IsOneLine = false, LineBreak = LineBreakType.MacOs