refactor: Common components are moved to the Common library.

This commit is contained in:
real-zony
2022-10-06 13:02:20 +08:00
parent ecab0e0f5c
commit 740e8f4c63
64 changed files with 84 additions and 150 deletions

View File

@@ -0,0 +1,23 @@
using Newtonsoft.Json;
namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou.JsonModel
{
public class GetLyricAccessKeyRequest
{
[JsonProperty("ver")] public int UnknownParameters1 { get; }
[JsonProperty("man")] public string UnknownParameters2 { get; }
[JsonProperty("client")] public string UnknownParameters3 { get; }
[JsonProperty("hash")] public string FileHash { get; }
public GetLyricAccessKeyRequest(string fileHash)
{
UnknownParameters1 = 1;
UnknownParameters2 = "yes";
UnknownParameters3 = "mobi";
FileHash = fileHash;
}
}
}

View File

@@ -0,0 +1,20 @@
using Newtonsoft.Json;
namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou.JsonModel
{
public class GetLyricAccessKeyResponse
{
[JsonProperty("status")] public int Status { get; set; }
[JsonProperty("errcode")] public int ErrorCode { get; set; }
[JsonProperty("candidates")] public List<GetLyricAccessKeyDataObject> AccessKeyDataObjects { get; set; }
}
public class GetLyricAccessKeyDataObject
{
[JsonProperty("accesskey")] public string AccessKey { get; set; }
[JsonProperty("id")] public string Id { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
using Newtonsoft.Json;
namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou.JsonModel
{
public class GetLyricRequest
{
[JsonProperty("ver")] public int UnknownParameters1 { get; }
[JsonProperty("client")] public string UnknownParameters2 { get; }
[JsonProperty("fmt")] public string UnknownParameters3 { get; }
[JsonProperty("charset")] public string UnknownParameters4 { get; }
[JsonProperty("id")] public string Id { get; }
[JsonProperty("accesskey")] public string AccessKey { get; }
public GetLyricRequest(string id, string accessKey)
{
UnknownParameters1 = 1;
UnknownParameters2 = "iphone";
UnknownParameters3 = "lrc";
UnknownParameters4 = "utf8";
Id = id;
AccessKey = accessKey;
}
}
public class GetLyricResponse
{
}
}

View File

@@ -0,0 +1,28 @@
using System.Text;
using System.Web;
using Newtonsoft.Json;
namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou.JsonModel
{
public class SongSearchRequest
{
[JsonProperty("filter")] public int Filter { get; }
[JsonProperty("platform")] public string Platform { get; }
[JsonProperty("keyword")] public string Keyword { get; }
[JsonProperty("pagesize")] public int PageSize { get; }
[JsonProperty("page")] public int Page { get; }
public SongSearchRequest(string musicName, string artistName, int pageSize = 30)
{
Filter = 2;
Platform = "WebFilter";
Keyword = HttpUtility.UrlEncode($"{musicName}+{artistName}", Encoding.UTF8);
PageSize = pageSize;
Page = 1;
}
}
}

View File

@@ -0,0 +1,25 @@
using Newtonsoft.Json;
namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou.JsonModel
{
public class SongSearchResponse
{
[JsonProperty("status")] public int Status { get; set; }
[JsonProperty("data")] public SongSearchResponseInnerData Data { get; set; }
[JsonProperty("error_code")] public int ErrorCode { get; set; }
[JsonProperty("error_msg")] public string ErrorMessage { get; set; }
}
public class SongSearchResponseInnerData
{
[JsonProperty("lists")] public List<SongSearchResponseSongDetail> List { get; set; }
}
public class SongSearchResponseSongDetail
{
public string FileHash { get; set; }
}
}

View File

@@ -0,0 +1,71 @@
using System.Text;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using ZonyLrcTools.Common.Configuration;
using ZonyLrcTools.Common.Infrastructure.Exceptions;
using ZonyLrcTools.Common.Infrastructure.Network;
using ZonyLrcTools.Common.Lyrics.Providers.KuGou.JsonModel;
namespace ZonyLrcTools.Common.Lyrics.Providers.KuGou
{
public class KuGourLyricDownloader : LyricDownloader
{
public override string DownloaderName => InternalLyricDownloaderNames.KuGou;
private readonly IWarpHttpClient _warpHttpClient;
private readonly ILyricItemCollectionFactory _lyricItemCollectionFactory;
private readonly GlobalOptions _options;
private const string KuGouSearchMusicUrl = @"https://songsearch.kugou.com/song_search_v2";
private const string KuGouGetLyricAccessKeyUrl = @"http://lyrics.kugou.com/search";
private const string KuGouGetLyricUrl = @"http://lyrics.kugou.com/download";
public KuGourLyricDownloader(IWarpHttpClient warpHttpClient,
ILyricItemCollectionFactory lyricItemCollectionFactory,
IOptions<GlobalOptions> options)
{
_warpHttpClient = warpHttpClient;
_lyricItemCollectionFactory = lyricItemCollectionFactory;
_options = options.Value;
}
protected override async ValueTask<byte[]> DownloadDataAsync(LyricDownloaderArgs args)
{
var searchResult = await _warpHttpClient.GetAsync<SongSearchResponse>(KuGouSearchMusicUrl,
new SongSearchRequest(args.SongName, args.Artist, _options.Provider.Lyric.GetLyricProviderOption(DownloaderName).Depth));
ValidateSongSearchResponse(searchResult, args);
// 获得特殊的 AccessToken 与 Id真正请求歌词数据。
var accessKeyResponse = await _warpHttpClient.GetAsync<GetLyricAccessKeyResponse>(KuGouGetLyricAccessKeyUrl,
new GetLyricAccessKeyRequest(searchResult.Data.List[0].FileHash));
var accessKeyObject = accessKeyResponse.AccessKeyDataObjects[0];
var lyricResponse = await _warpHttpClient.GetAsync(KuGouGetLyricUrl,
new GetLyricRequest(accessKeyObject.Id, accessKeyObject.AccessKey));
return Encoding.UTF8.GetBytes(lyricResponse);
}
protected override async ValueTask<LyricItemCollection> GenerateLyricAsync(byte[] data, LyricDownloaderArgs args)
{
await ValueTask.CompletedTask;
var lyricJsonObj = JObject.Parse(Encoding.UTF8.GetString(data));
if (lyricJsonObj.SelectToken("$.status").Value<int>() != 200)
{
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
}
var lyricText = Encoding.UTF8.GetString(Convert.FromBase64String(lyricJsonObj.SelectToken("$.content").Value<string>()));
return _lyricItemCollectionFactory.Build(lyricText);
}
protected virtual void ValidateSongSearchResponse(SongSearchResponse response, LyricDownloaderArgs args)
{
if (response.ErrorCode != 0 && response.Status != 1 || response.Data.List == null)
{
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
}
}
}
}