mirror of
https://github.com/real-zony/ZonyLrcToolsX.git
synced 2025-09-05 21:16:52 +00:00
Compare commits
20 Commits
ZonyLrcToo
...
ZonyLrcToo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2ce7b00d14 | ||
![]() |
ad6ea732f8 | ||
![]() |
06bf733ae9 | ||
![]() |
558cca3c0e | ||
![]() |
93cc31b1e2 | ||
![]() |
dfe18d8541 | ||
![]() |
40b73c3dfa | ||
![]() |
243a0e2559 | ||
![]() |
d83bff1516 | ||
![]() |
8d946ebbd5 | ||
![]() |
4c3d554885 | ||
![]() |
14c78f9a83 | ||
![]() |
b9d6da5f72 | ||
![]() |
c8ffbc55af | ||
![]() |
b0835dcf01 | ||
![]() |
4e1c4d1519 | ||
![]() |
3d96b96edf | ||
![]() |
7f81a3edea | ||
![]() |
24624a6d21 | ||
![]() |
d860632327 |
46
Directory.Packages.props
Normal file
46
Directory.Packages.props
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageVersion Include="McMaster.Extensions.CommandLineUtils" Version="4.1.0"/>
|
||||||
|
<PackageVersion Include="McMaster.Extensions.Hosting.CommandLine" Version="4.1.0"/>
|
||||||
|
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0"/>
|
||||||
|
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0"/>
|
||||||
|
<PackageVersion Include="QRCoder" Version="1.4.3"/>
|
||||||
|
<PackageVersion Include="Serilog.Extensions.Hosting" Version="8.0.0"/>
|
||||||
|
<PackageVersion Include="Serilog.Sinks.Async" Version="1.5.0"/>
|
||||||
|
<PackageVersion Include="Serilog.Sinks.Console" Version="4.1.0"/>
|
||||||
|
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0"/>
|
||||||
|
<PackageVersion Include="System.Text.Encoding.CodePages" Version="8.0.0"/>
|
||||||
|
<PackageVersion Include="Polly" Version="8.2.0"/>
|
||||||
|
<PackageVersion Include="TagLibSharp" Version="2.3.0"/>
|
||||||
|
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3"/>
|
||||||
|
<PackageVersion Include="NetEscapades.Configuration.Yaml" Version="3.1.0"/>
|
||||||
|
<PackageVersion Include="MusicDecrypto.Library" Version="2.3.0"/>
|
||||||
|
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0"/>
|
||||||
|
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0"/>
|
||||||
|
<PackageVersion Include="AutoMapper" Version="12.0.1"/>
|
||||||
|
<PackageVersion Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1"/>
|
||||||
|
<PackageVersion Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="8.0.0"/>
|
||||||
|
<PackageVersion Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.0"/>
|
||||||
|
<PackageVersion Include="SuperSocket.WebSocket" Version="2.0.0-beta.11"/>
|
||||||
|
<PackageVersion Include="SuperSocket.WebSocket.Server" Version="2.0.0-beta.11"/>
|
||||||
|
|
||||||
|
<!-- Testing Projects -->
|
||||||
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
|
||||||
|
<PackageVersion Include="Shouldly" Version="4.2.1"/>
|
||||||
|
<PackageVersion Include="xunit" Version="2.6.3"/>
|
||||||
|
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.5"/>
|
||||||
|
<PackageVersion Include="coverlet.collector" Version="6.0.0"/>
|
||||||
|
|
||||||
|
<!-- Avalonia -->
|
||||||
|
<PackageVersion Include="Avalonia" Version="11.0.6"/>
|
||||||
|
<PackageVersion Include="Avalonia.Desktop" Version="11.0.6"/>
|
||||||
|
<PackageVersion Include="Avalonia.Themes.Fluent" Version="11.0.6"/>
|
||||||
|
<PackageVersion Include="Avalonia.Fonts.Inter" Version="11.0.6"/>
|
||||||
|
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.0.6"/>
|
||||||
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.6"/>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
193
README.md
193
README.md
@@ -15,194 +15,11 @@ ZonyLrcToolX 4 是一个基于 CEF 的跨平台歌词下载工具,**QQ 群:337
|
|||||||
|
|
||||||
# 下载
|
# 下载
|
||||||
|
|
||||||
工具会执行每日构建动作,请访问 **[Release](https://github.com/real-zony/ZonyLrcToolsX/releases)** 页面进行下载。
|
如果你要获取最新版本,请访问 **[Release](https://github.com/real-zony/ZonyLrcToolsX/releases)** 页面进行下载。
|
||||||
|
|
||||||
# 用法
|
# 用法
|
||||||
|
|
||||||
Windows 用户请在软件目录当中,按住 Shift + 右键呼出菜单,然后选择 PowerShell/命令提示符/Windows 终端,根据下述说明执行命令即可。
|
软件的具体使用方法已经迁移到了全新的文档站点,请跳转到 [https://docs.myzony.com](https://docs.myzony.com),里面包含完整的说明文档。
|
||||||
|
|
||||||
macOS 和 Linux 用户请打开终端,切换到软件目录,一样执行命令即可。
|
|
||||||
|
|
||||||
## 子命令
|
|
||||||
|
|
||||||
### 下载功能
|
|
||||||
|
|
||||||
子命令为 `download`,可用于下载歌词数据和专辑图像,支持多个下载器进行下载。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
.\ZonyLrcTools.Cli.exe download -d|dir <WAIT_SCAN_DIRECTORY> [-l|--lyric] [-a|--album] [-n|--number]
|
|
||||||
|
|
||||||
.\ZonyLrcTools.Cli.exe download -h|--help
|
|
||||||
```
|
|
||||||
|
|
||||||
**例子**
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# 下载歌词
|
|
||||||
.\ZonyLrcTools.Cli.exe download -d "C:\歌曲目录" -l -n 2
|
|
||||||
|
|
||||||
# 下载专辑封面
|
|
||||||
.\ZonyLrcTools.Cli.exe download -d "C:\歌曲目录" -a -n 2
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 指定歌曲文件源
|
|
||||||
|
|
||||||
目前程序支持从本地目录、CSV 文件、网易云歌单获取歌曲数据,然后下载 LRC 歌词数据。
|
|
||||||
|
|
||||||
指定歌词源的参数是 `-sc|--scanner`,可以通过这个参数指定歌曲信息的来源。它拥有以下选值,默认情况下是 `local`。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
-sc local # 从目录获取歌曲信息。
|
|
||||||
-sc netease # 从网易云歌单获取歌曲信息。
|
|
||||||
-sc csv # 从 CSV 文件获取歌曲信息。
|
|
||||||
```
|
|
||||||
|
|
||||||
**从网易云歌单获取歌曲数据**
|
|
||||||
|
|
||||||
完整的命令如下:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
.\ZonyLrcTools.Cli.exe download -sc netease -o "D:\TempFiles" -s "7224428149" -l
|
|
||||||
```
|
|
||||||
|
|
||||||
其中 `-sc` 参数用于指定歌词信息的来源是网易云歌单; `-o` 参数指定的是歌词文件的输出目录,请尽量使用绝对路径; `-s` 参数指定的的是歌单的 ID,该 ID 可以从网页版的网易云音乐获得。
|
|
||||||
|
|
||||||
例如获取地址 [https://music.163.com/#/playlist?id=158010361](https://music.163.com/#/playlist?id=158010361) 的歌单信息,那么歌单 ID 就应该传递 158010361。
|
|
||||||
|
|
||||||
如果你需要获取多个歌单的歌曲数据,请在传递歌单 ID 时使用分号 `;` 指定多个 ID,例如下面的命令就是下载两个歌单的歌曲数据。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
.\ZonyLrcTools.Cli.exe download -sc netease -o "D:\TempFiles" -s "7224428149;158010361" -l
|
|
||||||
```
|
|
||||||
|
|
||||||
由于网易云音乐的限制,要想获取完整的歌单信息,必须扫码登录程序,还是以最上面的为例,我需要下载歌单内的歌词数据,就必须扫码之后程序才会执行。
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
**从 CSV 文件获取歌曲数据**
|
|
||||||
|
|
||||||
应 [Issue 126](https://github.com/real-zony/ZonyLrcToolsX/issues/126) 的请求,增加了从 CSV 获取歌曲信息的方式。这样可以在没有原始歌曲的情况下载歌词数据。
|
|
||||||
|
|
||||||
示例命令:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
.\ZonyLrcTools.Cli.exe download -sc csv -o "D:\TempFiles" -f "D:\TempFiles\demo.csv" -l
|
|
||||||
```
|
|
||||||
|
|
||||||
其中 `-f` 参数用于指定 csv 文件的路径,csv 文件的格式应该如下所示,保证第一行是列信息,一共要包含两列。
|
|
||||||
|
|
||||||
```csv
|
|
||||||
Song,Artist
|
|
||||||
刀马旦,李玟
|
|
||||||
发如雪,周杰伦
|
|
||||||
说书人,寅子
|
|
||||||
爱的供养,张国荣
|
|
||||||
七里香,周杰伦
|
|
||||||
```
|
|
||||||
|
|
||||||
### 加密格式转换
|
|
||||||
|
|
||||||
子命令为 `util`,可用于转换部分加密歌曲,**仅供个人研究学习使用,思路与源码都来自于网络**。
|
|
||||||
|
|
||||||
具体支持的格式请参考项目 [MusicDecrypto](https://github.com/davidxuang/MusicDecrypto/blob/master/MusicDecrypto.Library/DecryptoFactory.cs#L23),本工具仅做一个集成,替换掉原本自己的一些实现。现在不需要指定对应的类型参数,程序会自动根据文件后缀选择适合的解密算法。
|
|
||||||
|
|
||||||
命令只需要一个参数 `-s`,指定需要转换的文件夹或者是文件路径。
|
|
||||||
|
|
||||||
```shell
|
|
||||||
.\ZonyLrcTools.Cli.exe util -s D:\CloudMusic
|
|
||||||
```
|
|
||||||
|
|
||||||
## 配置文件
|
|
||||||
|
|
||||||
程序的所有的配置信息,都在 `config.yaml` 进行更改,下面标注了各个配置的说明。
|
|
||||||
|
|
||||||
其中是否开启的可选项为 `true` 或者 `false`,等同于中文的是和否。
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
globalOption:
|
|
||||||
# 允许扫描的歌曲文件后缀名。
|
|
||||||
supportFileExtensions:
|
|
||||||
- '*.mp3'
|
|
||||||
- '*.flac'
|
|
||||||
- '*.wav'
|
|
||||||
# 网络代理服务设置,仅支持 HTTP 代理。
|
|
||||||
networkOptions:
|
|
||||||
isEnable: false # 是否启用代理。
|
|
||||||
ip: 127.0.0.1 # 代理服务 IP 地址。
|
|
||||||
port: 4780 # 代理服务端口号。
|
|
||||||
updateUrl: https://api.myzony.com/lrc-tools/update # 更新检查地址。
|
|
||||||
|
|
||||||
# 下载器的相关参数配置。
|
|
||||||
provider:
|
|
||||||
# 标签扫描器的相关参数配置。
|
|
||||||
tag:
|
|
||||||
# 支持的标签扫描器。
|
|
||||||
plugin:
|
|
||||||
- name: Taglib # 基于 Taglib 库的标签扫描器。
|
|
||||||
priority: 1 # 优先级,升序排列。
|
|
||||||
- name: FileName # 基于文件名的标签扫描器。
|
|
||||||
priority: 2
|
|
||||||
# 基于文件名扫描器的扩展参数。
|
|
||||||
extensions:
|
|
||||||
# 正则表达式,用于匹配文件名中的作者信息和歌曲信息,可根据
|
|
||||||
# 自己的需求进行调整。
|
|
||||||
regularExpressions: "(?'artist'.+)\\s-\\s(?'name'.+)"
|
|
||||||
# 歌曲标签屏蔽字典替换功能。
|
|
||||||
blockWord:
|
|
||||||
isEnable: false # 是否启用屏蔽字典。
|
|
||||||
filePath: 'BlockWords.json' # 屏蔽字典的路径。
|
|
||||||
# 歌词下载器的相关参数配置。
|
|
||||||
lyric:
|
|
||||||
# 支持的歌词下载器。
|
|
||||||
plugin:
|
|
||||||
- name: NetEase # 基于网易云音乐的歌词下载器。
|
|
||||||
priority: 1 # 优先级,升序排列,改为 -1 时禁用。
|
|
||||||
depth: 10 # 搜索深度,值越大搜索结果越多,但搜索时间越长。
|
|
||||||
- name: QQ # 基于 QQ 音乐的歌词下载器。
|
|
||||||
priority: 2
|
|
||||||
# depth: 10 # 暂时不支持。
|
|
||||||
- name: KuGou # 基于酷狗音乐的歌词下载器。
|
|
||||||
priority: 3
|
|
||||||
depth: 10
|
|
||||||
- name: KuWo # 基于酷我音乐的歌词下载器。
|
|
||||||
priority: 4
|
|
||||||
depth: 10
|
|
||||||
# 歌词下载的一些共有配置参数。
|
|
||||||
config:
|
|
||||||
isOneLine: true # 双语歌词是否合并为一行展示。
|
|
||||||
lineBreak: "\n" # 换行符的类型,记得使用双引号指定。
|
|
||||||
isEnableTranslation: true # 是否启用翻译歌词。
|
|
||||||
isOnlyOutputTranslation: false # 是否只输出翻译歌词。
|
|
||||||
isSkipExistLyricFiles: false # 如果歌词文件已经存在,是否跳过这些文件。
|
|
||||||
fileEncoding: 'utf-8' # 歌词文件的编码格式。
|
|
||||||
```
|
|
||||||
|
|
||||||
### 支持的编码格式
|
|
||||||
|
|
||||||
详细信息请参考: [MSDN Encoding 列表](https://learn.microsoft.com/en-us/dotnet/api/System.Text.Encoding.GetEncodings?view=net-6.0#examples),使用 `identifier and name` 作为参数值填入 `config.yaml` 文件当中的 `fileEncoding`。
|
|
||||||
|
|
||||||
> 针对 UTF-8 BOM 格式,程序进行了特殊处理,请在 `fileEncoding` 里面填写 "utf-8-bom" 以支持。
|
|
||||||
|
|
||||||
### 支持的歌词源
|
|
||||||
|
|
||||||
| 歌词源 | 默认优先级 |
|
|
||||||
| ---------- | ---------- |
|
|
||||||
| 网易云音乐 | 1 |
|
|
||||||
| QQ 音乐 | 2 |
|
|
||||||
| 酷狗音乐 | 3 |
|
|
||||||
| 酷我音乐 | 4 |
|
|
||||||
|
|
||||||
## 屏蔽字典
|
|
||||||
|
|
||||||
屏蔽字典适用于网易云音乐歌词下载,针对某些单词,网易云音乐使用了 * 号进行屏蔽,这个时候可以使用屏蔽字典,设置歌曲名的关键词替换。例如有一首歌曲叫做 *Fucking ABC* ,这个时候网易云实际的名字是 *Fu****ing* ,用户只需要在屏蔽字典加入替换逻辑即可,例如:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Fuckking": "Fu****ing"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
屏蔽字典默认路径为程序所在目录的 *BlockWords.json* 文件,用户可以在 *appsettings.json* 文件中配置其他路径。
|
|
||||||
|
|
||||||
# 捐赠
|
# 捐赠
|
||||||
|
|
||||||
@@ -211,9 +28,3 @@ globalOption:
|
|||||||
# Star History
|
# Star History
|
||||||
|
|
||||||
[](https://star-history.com/#real-zony/ZonyLrcToolsX&Timeline)
|
[](https://star-history.com/#real-zony/ZonyLrcToolsX&Timeline)
|
||||||
|
|
||||||
# 路线图
|
|
||||||
|
|
||||||
- [x] 支持跨平台的 CLI 工具。
|
|
||||||
- [x] 基于 Web GUI 的操作站点。
|
|
||||||
- [ ] 支持插件系统(Lua 引擎)。
|
|
||||||
|
@@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZonyLrcTools.LocalServer",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZonyLrcTools.Common", "src\ZonyLrcTools.Common\ZonyLrcTools.Common.csproj", "{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZonyLrcTools.Common", "src\ZonyLrcTools.Common\ZonyLrcTools.Common.csproj", "{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZonyLrcTools.Desktop", "src\ZonyLrcTools.Desktop\ZonyLrcTools.Desktop.csproj", "{DC92902B-4303-4E43-AFB3-3F93FD3986AD}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -37,6 +39,10 @@ Global
|
|||||||
{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67}.Release|Any CPU.Build.0 = Release|Any CPU
|
{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{DC92902B-4303-4E43-AFB3-3F93FD3986AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{DC92902B-4303-4E43-AFB3-3F93FD3986AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{DC92902B-4303-4E43-AFB3-3F93FD3986AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DC92902B-4303-4E43-AFB3-3F93FD3986AD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -49,5 +55,6 @@ Global
|
|||||||
{FFBD3200-568F-455B-8390-5E76C51D522C} = {AF8ADB2F-E46C-4DEE-8316-652D9FE1A69B}
|
{FFBD3200-568F-455B-8390-5E76C51D522C} = {AF8ADB2F-E46C-4DEE-8316-652D9FE1A69B}
|
||||||
{2875A08A-FFD6-4863-B815-5384DCFE88FC} = {C29FB05C-54B1-4020-94D2-87E192EB2F98}
|
{2875A08A-FFD6-4863-B815-5384DCFE88FC} = {C29FB05C-54B1-4020-94D2-87E192EB2F98}
|
||||||
{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67} = {C29FB05C-54B1-4020-94D2-87E192EB2F98}
|
{9B42E4CA-61AA-4798-8D2B-2D8A7035EB67} = {C29FB05C-54B1-4020-94D2-87E192EB2F98}
|
||||||
|
{DC92902B-4303-4E43-AFB3-3F93FD3986AD} = {C29FB05C-54B1-4020-94D2-87E192EB2F98}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@@ -46,7 +46,7 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand
|
|||||||
[Option("-a|--album", CommandOptionType.NoValue, Description = "指定程序需要下载专辑图像。")]
|
[Option("-a|--album", CommandOptionType.NoValue, Description = "指定程序需要下载专辑图像。")]
|
||||||
public bool DownloadAlbum { get; set; }
|
public bool DownloadAlbum { get; set; }
|
||||||
|
|
||||||
[Option("-n|--number", CommandOptionType.SingleValue, Description = "指定下载时候的线程数量。(默认值 2)")]
|
[Option("-n|--number", CommandOptionType.SingleValue, Description = "指定下载时候的线程数量。(默认值 1)")]
|
||||||
public int ParallelNumber { get; set; } = 1;
|
public int ParallelNumber { get; set; } = 1;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using McMaster.Extensions.CommandLineUtils;
|
using McMaster.Extensions.CommandLineUtils;
|
||||||
@@ -79,7 +78,7 @@ namespace ZonyLrcTools.Cli
|
|||||||
private static Task<int> BuildHostedService(string[] args)
|
private static Task<int> BuildHostedService(string[] args)
|
||||||
{
|
{
|
||||||
return new HostBuilder()
|
return new HostBuilder()
|
||||||
.ConfigureLogging(builder => builder.AddSerilog())
|
.ConfigureLogging(l => l.AddSerilog())
|
||||||
.ConfigureHostConfiguration(builder =>
|
.ConfigureHostConfiguration(builder =>
|
||||||
{
|
{
|
||||||
builder
|
builder
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<AssemblyVersion>0.0.0.1</AssemblyVersion>
|
<AssemblyVersion>0.0.0.1</AssemblyVersion>
|
||||||
<FileVersion>0.0.0.1</FileVersion>
|
<FileVersion>0.0.0.1</FileVersion>
|
||||||
@@ -10,37 +10,34 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.2" />
|
<PackageReference Include="McMaster.Extensions.CommandLineUtils"/>
|
||||||
<PackageReference Include="McMaster.Extensions.Hosting.CommandLine" Version="4.0.2" />
|
<PackageReference Include="McMaster.Extensions.Hosting.CommandLine"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
<PackageReference Include="Serilog.Extensions.Hosting"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
<PackageReference Include="Serilog.Sinks.Async"/>
|
||||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
<PackageReference Include="Serilog.Sinks.Console"/>
|
||||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
|
<PackageReference Include="Serilog.Sinks.File"/>
|
||||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages"/>
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="appsettings.json" />
|
<None Remove="appsettings.json"/>
|
||||||
<None Remove="Resources\error_msg.json" />
|
<None Remove="Resources\error_msg.json"/>
|
||||||
<Content Include="Resources\error_msg.json">
|
<Content Include="Resources\error_msg.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<None Remove="BlockWords.json" />
|
<None Remove="BlockWords.json"/>
|
||||||
<Content Include="BlockWords.json">
|
<Content Include="BlockWords.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<None Remove="config.yaml" />
|
<None Remove="config.yaml"/>
|
||||||
<Content Include="config.yaml">
|
<Content Include="config.yaml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ZonyLrcTools.Common\ZonyLrcTools.Common.csproj" />
|
<ProjectReference Include="..\ZonyLrcTools.Common\ZonyLrcTools.Common.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -4,6 +4,9 @@ globalOption:
|
|||||||
- '*.mp3'
|
- '*.mp3'
|
||||||
- '*.flac'
|
- '*.flac'
|
||||||
- '*.wav'
|
- '*.wav'
|
||||||
|
- '*.m4a'
|
||||||
|
- '*.ogg'
|
||||||
|
- '*.opus'
|
||||||
# 网络代理服务设置,仅支持 HTTP 代理。
|
# 网络代理服务设置,仅支持 HTTP 代理。
|
||||||
networkOptions:
|
networkOptions:
|
||||||
isEnable: false # 是否启用代理。
|
isEnable: false # 是否启用代理。
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
$Platforms = @('win-x64', 'linux-x64', 'osx-x64')
|
$Platforms = @('win-x64', 'linux-x64', 'osx-x64', 'win-arm64', 'linux-arm64', 'osx-arm64')
|
||||||
|
|
||||||
if (-not (Test-Path ./TempFiles)) {
|
if (-not (Test-Path ./TempFiles)) {
|
||||||
New-Item -ItemType Directory -Path ./TempFiles | Out-Null
|
New-Item -ItemType Directory -Path ./TempFiles | Out-Null
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
Platforms=('win-x64' 'linux-x64' 'osx-x64')
|
Platforms=('win-x64' 'linux-x64' 'osx-x64' 'win-arm64' 'linux-arm64' 'osx-arm64')
|
||||||
|
|
||||||
if ! [ -d './TempFiles' ];
|
if ! [ -d './TempFiles' ];
|
||||||
then
|
then
|
||||||
@@ -12,9 +12,9 @@ for platform in "${Platforms[@]}"
|
|||||||
do
|
do
|
||||||
dotnet publish -r "$platform" -c Release -p:PublishSingleFile=true -p:DebugType=none --self-contained true || exit 1
|
dotnet publish -r "$platform" -c Release -p:PublishSingleFile=true -p:DebugType=none --self-contained true || exit 1
|
||||||
|
|
||||||
cd ./bin/Release/net7.0/"$platform"/publish/ || exit 1
|
cd ./bin/Release/net8.0/"$platform"/publish/ || exit 1
|
||||||
zip -r ./ZonyLrcTools_"$platform"_"${PUBLISH_VERSION}".zip ./ || exit 1
|
zip -r ./ZonyLrcTools_"$platform"_"${PUBLISH_VERSION}".zip ./ || exit 1
|
||||||
cd ../../../../../ || exit 1
|
cd ../../../../../ || exit 1
|
||||||
|
|
||||||
mv ./bin/Release/net7.0/"$platform"/publish/ZonyLrcTools_"$platform"_"$PUBLISH_VERSION".zip ./TempFiles
|
mv ./bin/Release/net8.0/"$platform"/publish/ZonyLrcTools_"$platform"_"$PUBLISH_VERSION".zip ./TempFiles
|
||||||
done
|
done
|
@@ -1,10 +1,22 @@
|
|||||||
namespace ZonyLrcTools.Common.Lyrics;
|
namespace ZonyLrcTools.Common.Lyrics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 歌词下载核心逻辑的接口定义。
|
||||||
|
/// </summary>
|
||||||
public interface ILyricsDownloader
|
public interface ILyricsDownloader
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 使用给定的歌词信息下载歌词,并输出文件到指定的路径。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="needDownloadMusicInfos">需要下载的歌词信息。</param>
|
||||||
|
/// <param name="parallelCount">下载线程/并发量。</param>
|
||||||
|
/// <param name="cancellationToken">任务取消标记。</param>
|
||||||
Task DownloadAsync(List<MusicInfo> needDownloadMusicInfos,
|
Task DownloadAsync(List<MusicInfo> needDownloadMusicInfos,
|
||||||
int parallelCount = 2,
|
int parallelCount = 2,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取目前可用的歌词下载器。
|
||||||
|
/// </summary>
|
||||||
IEnumerable<ILyricsProvider> AvailableProviders { get; }
|
IEnumerable<ILyricsProvider> AvailableProviders { get; }
|
||||||
}
|
}
|
@@ -17,7 +17,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase
|
|||||||
private readonly ILyricsItemCollectionFactory _lyricsItemCollectionFactory;
|
private readonly ILyricsItemCollectionFactory _lyricsItemCollectionFactory;
|
||||||
private readonly GlobalOptions _options;
|
private readonly GlobalOptions _options;
|
||||||
|
|
||||||
private const string NetEaseSearchMusicUrl = @"https://music.163.com/weapi/cloudsearch/get/web";
|
private const string NetEaseSearchMusicUrl = @"https://music.163.com/weapi/search/get";
|
||||||
private const string NetEaseGetLyricUrl = @"https://music.163.com/weapi/song/lyric?csrf_token=";
|
private const string NetEaseGetLyricUrl = @"https://music.163.com/weapi/song/lyric?csrf_token=";
|
||||||
|
|
||||||
private const string NetEaseRequestReferer = @"https://music.163.com";
|
private const string NetEaseRequestReferer = @"https://music.163.com";
|
||||||
|
@@ -139,7 +139,7 @@ public class NetEaseMusicSongListMusicScanner : ISingletonDependency
|
|||||||
var asciiQrCodeString = qrCode.GetGraphic(1, drawQuietZones: false);
|
var asciiQrCodeString = qrCode.GetGraphic(1, drawQuietZones: false);
|
||||||
|
|
||||||
_logger.LogInformation("请使用网易云 APP 扫码登录:");
|
_logger.LogInformation("请使用网易云 APP 扫码登录:");
|
||||||
_logger.LogInformation(asciiQrCodeString);
|
_logger.LogInformation("\n{AsciiQrCodeString}", asciiQrCodeString);
|
||||||
|
|
||||||
// Wait for login success.
|
// Wait for login success.
|
||||||
var isLogin = false;
|
var isLogin = false;
|
||||||
|
@@ -1,26 +1,25 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Version>4.0.0.55</Version>
|
<Version>4.0.0.57</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
<PackageReference Include="MusicDecrypto.Library"/>
|
||||||
<PackageReference Include="MusicDecrypto.Library" Version="2.2.0" />
|
<PackageReference Include="Newtonsoft.Json"/>
|
||||||
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="3.1.0" />
|
<PackageReference Include="NetEscapades.Configuration.Yaml"/>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Polly"/>
|
||||||
<PackageReference Include="Polly" Version="7.2.3" />
|
<PackageReference Include="QRCoder"/>
|
||||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
<PackageReference Include="TagLibSharp"/>
|
||||||
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Lyrics\Providers\Kugeci\KugeciDownloader.cs" />
|
<Compile Remove="Lyrics\Providers\Kugeci\KugeciDownloader.cs"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
15
src/ZonyLrcTools.Desktop/App.axaml
Normal file
15
src/ZonyLrcTools.Desktop/App.axaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Application xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
x:Class="ZonyLrcTools.Desktop.App"
|
||||||
|
xmlns:local="using:ZonyLrcTools.Desktop"
|
||||||
|
RequestedThemeVariant="Default">
|
||||||
|
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||||
|
|
||||||
|
<Application.DataTemplates>
|
||||||
|
<local:ViewLocator/>
|
||||||
|
</Application.DataTemplates>
|
||||||
|
|
||||||
|
<Application.Styles>
|
||||||
|
<FluentTheme />
|
||||||
|
</Application.Styles>
|
||||||
|
</Application>
|
28
src/ZonyLrcTools.Desktop/App.axaml.cs
Normal file
28
src/ZonyLrcTools.Desktop/App.axaml.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using ZonyLrcTools.Desktop.ViewModels;
|
||||||
|
using ZonyLrcTools.Desktop.Views;
|
||||||
|
|
||||||
|
namespace ZonyLrcTools.Desktop;
|
||||||
|
|
||||||
|
public partial class App : Application
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnFrameworkInitializationCompleted()
|
||||||
|
{
|
||||||
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
|
{
|
||||||
|
desktop.MainWindow = new MainWindow
|
||||||
|
{
|
||||||
|
DataContext = new MainWindowViewModel(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnFrameworkInitializationCompleted();
|
||||||
|
}
|
||||||
|
}
|
BIN
src/ZonyLrcTools.Desktop/Assets/avalonia-logo.ico
Normal file
BIN
src/ZonyLrcTools.Desktop/Assets/avalonia-logo.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 172 KiB |
23
src/ZonyLrcTools.Desktop/Program.cs
Normal file
23
src/ZonyLrcTools.Desktop/Program.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ZonyLrcTools.Desktop;
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||||
|
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||||
|
// yet and stuff might break.
|
||||||
|
[STAThread]
|
||||||
|
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||||
|
.StartWithClassicDesktopLifetime(args);
|
||||||
|
|
||||||
|
// Avalonia configuration, don't remove; also used by visual designer.
|
||||||
|
public static AppBuilder BuildAvaloniaApp()
|
||||||
|
=> AppBuilder.Configure<App>()
|
||||||
|
.UsePlatformDetect()
|
||||||
|
.WithInterFont()
|
||||||
|
.LogToTrace()
|
||||||
|
.UseReactiveUI();
|
||||||
|
}
|
27
src/ZonyLrcTools.Desktop/ViewLocator.cs
Normal file
27
src/ZonyLrcTools.Desktop/ViewLocator.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Templates;
|
||||||
|
using ZonyLrcTools.Desktop.ViewModels;
|
||||||
|
|
||||||
|
namespace ZonyLrcTools.Desktop;
|
||||||
|
|
||||||
|
public class ViewLocator : IDataTemplate
|
||||||
|
{
|
||||||
|
public Control Build(object data)
|
||||||
|
{
|
||||||
|
var name = data.GetType().FullName!.Replace("ViewModel", "View");
|
||||||
|
var type = Type.GetType(name);
|
||||||
|
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
return (Control)Activator.CreateInstance(type)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TextBlock { Text = "Not Found: " + name };
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Match(object data)
|
||||||
|
{
|
||||||
|
return data is ViewModelBase;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
namespace ZonyLrcTools.Desktop.ViewModels;
|
||||||
|
|
||||||
|
public class MainWindowViewModel : ViewModelBase
|
||||||
|
{
|
||||||
|
public string Greeting => "Welcome to Avalonia!";
|
||||||
|
}
|
7
src/ZonyLrcTools.Desktop/ViewModels/ViewModelBase.cs
Normal file
7
src/ZonyLrcTools.Desktop/ViewModels/ViewModelBase.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace ZonyLrcTools.Desktop.ViewModels;
|
||||||
|
|
||||||
|
public class ViewModelBase : ReactiveObject
|
||||||
|
{
|
||||||
|
}
|
20
src/ZonyLrcTools.Desktop/Views/MainWindow.axaml
Normal file
20
src/ZonyLrcTools.Desktop/Views/MainWindow.axaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:vm="using:ZonyLrcTools.Desktop.ViewModels"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="ZonyLrcTools.Desktop.Views.MainWindow"
|
||||||
|
x:DataType="vm:MainWindowViewModel"
|
||||||
|
Icon="/Assets/avalonia-logo.ico"
|
||||||
|
Title="ZonyLrcTools.Desktop">
|
||||||
|
|
||||||
|
<Design.DataContext>
|
||||||
|
<!-- This only sets the DataContext for the previewer in an IDE,
|
||||||
|
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
|
||||||
|
<vm:MainWindowViewModel/>
|
||||||
|
</Design.DataContext>
|
||||||
|
|
||||||
|
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
</Window>
|
11
src/ZonyLrcTools.Desktop/Views/MainWindow.axaml.cs
Normal file
11
src/ZonyLrcTools.Desktop/Views/MainWindow.axaml.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace ZonyLrcTools.Desktop.Views;
|
||||||
|
|
||||||
|
public partial class MainWindow : Window
|
||||||
|
{
|
||||||
|
public MainWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
25
src/ZonyLrcTools.Desktop/ZonyLrcTools.Desktop.csproj
Normal file
25
src/ZonyLrcTools.Desktop/ZonyLrcTools.Desktop.csproj
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||||
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Models\"/>
|
||||||
|
<AvaloniaResource Include="Assets\**"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Avalonia"/>
|
||||||
|
<PackageReference Include="Avalonia.Desktop"/>
|
||||||
|
<PackageReference Include="Avalonia.Themes.Fluent"/>
|
||||||
|
<PackageReference Include="Avalonia.Fonts.Inter"/>
|
||||||
|
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||||
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics"/>
|
||||||
|
<PackageReference Include="Avalonia.ReactiveUI"/>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
18
src/ZonyLrcTools.Desktop/app.manifest
Normal file
18
src/ZonyLrcTools.Desktop/app.manifest
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<!-- This manifest is used on Windows only.
|
||||||
|
Don't remove it as it might cause problems with window transparency and embeded controls.
|
||||||
|
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
|
||||||
|
<assemblyIdentity version="1.0.0.0" name="ZonyLrcTools.Desktop.Desktop"/>
|
||||||
|
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!-- A list of the Windows versions that this application has been tested on
|
||||||
|
and is designed to work with. Uncomment the appropriate elements
|
||||||
|
and Windows will automatically select the most compatible environment. -->
|
||||||
|
|
||||||
|
<!-- Windows 10 -->
|
||||||
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
</assembly>
|
@@ -1,37 +1,36 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
|
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
<PackageReference Include="AutoMapper"/>
|
||||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection"/>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="7.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="7.0.5" />
|
<PackageReference Include="Microsoft.Extensions.Hosting"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
<PackageReference Include="Serilog.Extensions.Hosting"/>
|
||||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
|
<PackageReference Include="Serilog.Sinks.Console"/>
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
<PackageReference Include="Serilog.Sinks.File"/>
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
<PackageReference Include="SuperSocket.WebSocket"/>
|
||||||
<PackageReference Include="SuperSocket.WebSocket" Version="2.0.0-beta.11" />
|
<PackageReference Include="SuperSocket.WebSocket.Server"/>
|
||||||
<PackageReference Include="SuperSocket.WebSocket.Server" Version="2.0.0-beta.11" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="UiStaticResources\**" />
|
<EmbeddedResource Include="UiStaticResources\**"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ZonyLrcTools.Common\ZonyLrcTools.Common.csproj" />
|
<ProjectReference Include="..\ZonyLrcTools.Common\ZonyLrcTools.Common.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- <ItemGroup>-->
|
<!-- <ItemGroup>-->
|
||||||
<!-- <ProjectReference Include="..\ZonyLrcTools.Cli\ZonyLrcTools.Cli.csproj" />-->
|
<!-- <ProjectReference Include="..\ZonyLrcTools.Cli\ZonyLrcTools.Cli.csproj" />-->
|
||||||
<!-- </ItemGroup>-->
|
<!-- </ItemGroup>-->
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
> 1%
|
|
||||||
last 2 versions
|
|
||||||
not dead
|
|
213
src/ui/.gitignore
vendored
213
src/ui/.gitignore
vendored
@@ -1,213 +0,0 @@
|
|||||||
### VisualStudioCode template
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
*.code-workspace
|
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
|
||||||
.history/
|
|
||||||
|
|
||||||
### JetBrains template
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
# *.iml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
||||||
### Node template
|
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
|
||||||
*.lcov
|
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# Snowpack dependency directory (https://snowpack.dev/)
|
|
||||||
web_modules/
|
|
||||||
|
|
||||||
# TypeScript cache
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Microbundle cache
|
|
||||||
.rpt2_cache/
|
|
||||||
.rts2_cache_cjs/
|
|
||||||
.rts2_cache_es/
|
|
||||||
.rts2_cache_umd/
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variables file
|
|
||||||
.env
|
|
||||||
.env.test
|
|
||||||
|
|
||||||
# parcel-bundler cache (https://parceljs.org/)
|
|
||||||
.cache
|
|
||||||
.parcel-cache
|
|
||||||
|
|
||||||
# Next.js build output
|
|
||||||
.next
|
|
||||||
out
|
|
||||||
|
|
||||||
# Nuxt.js build / generate output
|
|
||||||
.nuxt
|
|
||||||
dist
|
|
||||||
|
|
||||||
# Gatsby files
|
|
||||||
.cache/
|
|
||||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
||||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
||||||
# public
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
.serverless/
|
|
||||||
|
|
||||||
# FuseBox cache
|
|
||||||
.fusebox/
|
|
||||||
|
|
||||||
# DynamoDB Local files
|
|
||||||
.dynamodb/
|
|
||||||
|
|
||||||
# TernJS port file
|
|
||||||
.tern-port
|
|
||||||
|
|
||||||
# Stores VSCode versions used for testing VSCode extensions
|
|
||||||
.vscode-test
|
|
||||||
|
|
||||||
# yarn v2
|
|
||||||
.yarn/cache
|
|
||||||
.yarn/unplugged
|
|
||||||
.yarn/build-state.yml
|
|
||||||
.yarn/install-state.gz
|
|
||||||
.pnp.*
|
|
||||||
|
|
||||||
### Vue template
|
|
||||||
# gitignore template for Vue.js projects
|
|
||||||
#
|
|
||||||
# Recommended template: Node.gitignore
|
|
||||||
|
|
||||||
# TODO: where does this rule come from?
|
|
||||||
docs/_book
|
|
||||||
|
|
||||||
# TODO: where does this rule come from?
|
|
||||||
test/
|
|
||||||
|
|
@@ -1,19 +0,0 @@
|
|||||||
# ui
|
|
||||||
|
|
||||||
## Project setup
|
|
||||||
```
|
|
||||||
yarn install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compiles and hot-reloads for development
|
|
||||||
```
|
|
||||||
yarn serve
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compiles and minifies for production
|
|
||||||
```
|
|
||||||
yarn build
|
|
||||||
```
|
|
||||||
|
|
||||||
### Customize configuration
|
|
||||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
|
@@ -1,5 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
presets: [
|
|
||||||
'@vue/cli-plugin-babel/preset'
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es5",
|
|
||||||
"module": "esnext",
|
|
||||||
"baseUrl": "./",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"paths": {
|
|
||||||
"@/*": [
|
|
||||||
"src/*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"lib": [
|
|
||||||
"esnext",
|
|
||||||
"dom",
|
|
||||||
"dom.iterable",
|
|
||||||
"scripthost"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "ui",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"serve": "vue-cli-service serve",
|
|
||||||
"build": "vue-cli-service build"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"axios": "^1.1.3",
|
|
||||||
"core-js": "^3.8.3",
|
|
||||||
"vue": "^2.6.14",
|
|
||||||
"vue-router": "^3.5.1",
|
|
||||||
"vuetify": "^2.6.0",
|
|
||||||
"vuex": "^3.6.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
|
||||||
"@vue/cli-plugin-router": "~5.0.0",
|
|
||||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
|
||||||
"@vue/cli-service": "~5.0.0",
|
|
||||||
"sass": "^1.32.7",
|
|
||||||
"sass-loader": "^12.0.0",
|
|
||||||
"vue-cli-plugin-vuetify": "~2.5.8",
|
|
||||||
"vue-template-compiler": "^2.6.14",
|
|
||||||
"vuetify-loader": "^1.7.0"
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB |
@@ -1,19 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>
|
|
||||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
|
||||||
</noscript>
|
|
||||||
<div id="app"></div>
|
|
||||||
<!-- built files will be auto injected -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@@ -1,80 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-app id="inspire">
|
|
||||||
|
|
||||||
<v-navigation-drawer
|
|
||||||
v-model="drawer"
|
|
||||||
app
|
|
||||||
>
|
|
||||||
<v-sheet
|
|
||||||
color="grey lighten-4"
|
|
||||||
class="pa-4"
|
|
||||||
>
|
|
||||||
<div>ZonyLrcTools-X</div>
|
|
||||||
</v-sheet>
|
|
||||||
|
|
||||||
<v-divider></v-divider>
|
|
||||||
|
|
||||||
<v-list>
|
|
||||||
<v-list-item
|
|
||||||
v-for="[icon, text, to] in links"
|
|
||||||
:key="icon"
|
|
||||||
:to="to"
|
|
||||||
link
|
|
||||||
>
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{ icon }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-list-item-title>{{ text }}</v-list-item-title>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
|
|
||||||
<v-app-bar app>
|
|
||||||
<v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
|
|
||||||
|
|
||||||
<v-toolbar-title>ZonyLrcToolsX</v-toolbar-title>
|
|
||||||
</v-app-bar>
|
|
||||||
|
|
||||||
<v-main>
|
|
||||||
<v-container
|
|
||||||
class="py-8 px-6"
|
|
||||||
fluid
|
|
||||||
>
|
|
||||||
<router-view></router-view>
|
|
||||||
</v-container>
|
|
||||||
</v-main>
|
|
||||||
</v-app>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Socket from "@/communication/socket";
|
|
||||||
import {mapMutations} from "vuex"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data: () => ({
|
|
||||||
drawer: null,
|
|
||||||
links: [
|
|
||||||
['mdi-play-circle', '开始', '/'],
|
|
||||||
['mdi-multiplication-box', '设置', '/setting'],
|
|
||||||
['mdi-information', '关于', '/about'],
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
created() {
|
|
||||||
Socket.$on("message", this.handleGetMessage);
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
Socket.$off("message", this.handleGetMessage);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapMutations({
|
|
||||||
setWsRes: "ws/setWsRes",
|
|
||||||
}),
|
|
||||||
handleGetMessage(msg) {
|
|
||||||
this.setWsRes(JSON.parse(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.7 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>
|
|
Before Width: | Height: | Size: 539 B |
@@ -1,5 +0,0 @@
|
|||||||
import Vue from "vue";
|
|
||||||
|
|
||||||
const eventBus = new Vue();
|
|
||||||
|
|
||||||
export default eventBus;
|
|
@@ -1,31 +0,0 @@
|
|||||||
import Vue from 'vue'
|
|
||||||
import eventBus from "@/communication/eventbus";
|
|
||||||
|
|
||||||
// const wsUrl = process.env.VUE_APP_WS_URL;
|
|
||||||
const wsUrl = "ws://127.0.0.1:50001"
|
|
||||||
|
|
||||||
let socket = new WebSocket(wsUrl);
|
|
||||||
const emitter = new Vue({
|
|
||||||
methods: {
|
|
||||||
send(message) {
|
|
||||||
if (socket.readyState === 1) {
|
|
||||||
socket.send(JSON.stringify(message));
|
|
||||||
}
|
|
||||||
}, connect() {
|
|
||||||
socket = new WebSocket(wsUrl);
|
|
||||||
socket.onmessage = (msg) => {
|
|
||||||
let event = JSON.parse(msg.data);
|
|
||||||
eventBus.$emit(event.action, event);
|
|
||||||
};
|
|
||||||
socket.onerror = (err) => {
|
|
||||||
eventBus.$emit('error', err);
|
|
||||||
};
|
|
||||||
socket.onclose = () => {
|
|
||||||
emitter.connect()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
emitter.connect();
|
|
||||||
export default emitter;
|
|
@@ -1,13 +0,0 @@
|
|||||||
<template>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "setting"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@@ -1,14 +0,0 @@
|
|||||||
import Vue from 'vue'
|
|
||||||
import App from './App.vue'
|
|
||||||
import router from './router'
|
|
||||||
import store from './store'
|
|
||||||
import vuetify from './plugins/vuetify'
|
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
|
||||||
|
|
||||||
new Vue({
|
|
||||||
router,
|
|
||||||
store,
|
|
||||||
vuetify,
|
|
||||||
render: h => h(App)
|
|
||||||
}).$mount('#app')
|
|
@@ -1,21 +0,0 @@
|
|||||||
import Vue from 'vue';
|
|
||||||
import Vuetify from 'vuetify/lib/framework';
|
|
||||||
|
|
||||||
Vue.use(Vuetify);
|
|
||||||
|
|
||||||
export default new Vuetify({
|
|
||||||
theme: {
|
|
||||||
dark: false,
|
|
||||||
themes: {
|
|
||||||
light: {
|
|
||||||
primary: '#03a9f4',
|
|
||||||
secondary: '#8bc34a',
|
|
||||||
accent: '#cddc39',
|
|
||||||
error: '#f44336',
|
|
||||||
warning: '#ffc107',
|
|
||||||
info: '#607d8b',
|
|
||||||
success: '#4caf50'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
@@ -1,33 +0,0 @@
|
|||||||
import Vue from 'vue'
|
|
||||||
import VueRouter from 'vue-router'
|
|
||||||
import HomeView from '../views/HomeView.vue'
|
|
||||||
import AboutView from '../views/AboutView.vue'
|
|
||||||
import SettingView from "@/views/SettingView"
|
|
||||||
|
|
||||||
Vue.use(VueRouter)
|
|
||||||
|
|
||||||
const routes = [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
name: 'home',
|
|
||||||
component: HomeView
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/about',
|
|
||||||
name: 'about',
|
|
||||||
component: AboutView
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/setting',
|
|
||||||
name: 'setting',
|
|
||||||
component: SettingView
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const router = new VueRouter({
|
|
||||||
mode: 'history',
|
|
||||||
base: process.env.BASE_URL,
|
|
||||||
routes
|
|
||||||
})
|
|
||||||
|
|
||||||
export default router
|
|
@@ -1,12 +0,0 @@
|
|||||||
import Vue from 'vue'
|
|
||||||
import Vuex from 'vuex'
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
|
||||||
|
|
||||||
export default new Vuex.Store({
|
|
||||||
state: {},
|
|
||||||
getters: {},
|
|
||||||
mutations: {},
|
|
||||||
actions: {},
|
|
||||||
modules: {}
|
|
||||||
})
|
|
@@ -1,5 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="about">
|
|
||||||
<h1>This is an about page</h1>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@@ -1,90 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
|
|
||||||
<!-- Operation Buttons Group -->
|
|
||||||
<div class="button-group">
|
|
||||||
<v-btn @click="openDir">
|
|
||||||
扫描文件
|
|
||||||
</v-btn>
|
|
||||||
<input type="file" class="d-none">
|
|
||||||
|
|
||||||
<v-btn class="ml-5" disabled>开始下载</v-btn>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="file-list mt-5">
|
|
||||||
<v-data-table
|
|
||||||
:headers="headers"
|
|
||||||
:items="items"
|
|
||||||
class="elevation-1"
|
|
||||||
>
|
|
||||||
<template v-slot:item.status="{ item }">
|
|
||||||
<v-icon v-if="item.status === 'success'" color="success">mdi-check</v-icon>
|
|
||||||
<v-icon v-else-if="item.status === 'error'" color="error">mdi-close</v-icon>
|
|
||||||
<v-icon v-else>mdi-minus</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
|
|
||||||
<div class="output mt-8">
|
|
||||||
<v-textarea disabled outlined label="日志信息" :value='outputText'/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Socket from '@/communication/socket'
|
|
||||||
import eventBus from "@/communication/eventbus";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Home',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
text: '文件名',
|
|
||||||
align: 'start',
|
|
||||||
sortable: false,
|
|
||||||
value: 'name',
|
|
||||||
},
|
|
||||||
{text: '大小', value: 'size'},
|
|
||||||
{text: '状态', value: 'status'},
|
|
||||||
{text: '操作', value: 'action'},
|
|
||||||
],
|
|
||||||
items: [],
|
|
||||||
outputText: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
openDir() {
|
|
||||||
Socket.send({
|
|
||||||
type: 'openDir',
|
|
||||||
data: {},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loadItems() {
|
|
||||||
this.items = []
|
|
||||||
axios.get()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {},
|
|
||||||
mounted() {
|
|
||||||
// eventBus.$on('getFile', (msgData) => {
|
|
||||||
// console.log(msgData);
|
|
||||||
// });
|
|
||||||
// eventBus.$on('getFileInfo', (msgData) => {
|
|
||||||
// this.items = [...this.items, ...msgData.data.map(item => {
|
|
||||||
// return {
|
|
||||||
// name: item.name,
|
|
||||||
// size: item.size,
|
|
||||||
// status: 'success',
|
|
||||||
// action: 4.0,
|
|
||||||
// }
|
|
||||||
// })]
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
eventBus.$on('output', (msgData) => {
|
|
||||||
this.outputText = this.outputText.concat(msgData.data.text).concat('\n');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@@ -1,148 +0,0 @@
|
|||||||
<template>
|
|
||||||
|
|
||||||
<v-form>
|
|
||||||
<v-list subheader flat two-line>
|
|
||||||
<v-subheader>网络代理</v-subheader>
|
|
||||||
|
|
||||||
<v-list-item>
|
|
||||||
<v-switch label="启用代理" @change="proxyEnabledChange" v-model="isProxyEnabled"/>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<v-text-field :disabled="proxyEnabled" v-model="proxyAddress" label="代理地址"
|
|
||||||
placeholder="请输入代理服务器的地址,例如 127.0.0.1:1080。"/>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<v-text-field :disabled="proxyEnabled" v-model="updateAddress" label="更新检查地址"
|
|
||||||
placeholder="请输入更新检查地址,默认情况下无需变更。"/>
|
|
||||||
</v-list-item>
|
|
||||||
|
|
||||||
<v-divider></v-divider>
|
|
||||||
<v-subheader>全局下载设置</v-subheader>
|
|
||||||
<v-list-item>
|
|
||||||
<v-switch label="是否启用翻译歌词"/>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<v-switch label="仅输出翻译歌词"/>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<v-switch label="跳过歌词文件已存在的歌曲"/>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<v-switch label="双语歌词合并展示" v-model="mergeLrc"/>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<!--文件编码-->
|
|
||||||
<v-select v-model="lrcEncoding" :items="lrcEncodings" label="歌词文件编码" placeholder="请选择歌词文件编码"/>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<!--换行符下拉选择-->
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-select label="换行符" v-model="lineBreak" :items="lineBreakOptions" item-text="label"
|
|
||||||
item-value="value"/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-list-item>
|
|
||||||
|
|
||||||
<v-divider></v-divider>
|
|
||||||
<v-list-item>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="6">
|
|
||||||
<v-subheader>歌词下载器设置</v-subheader>
|
|
||||||
<v-list-item>
|
|
||||||
<v-data-table hide-default-footer :headers="lyricDownloaderHeaders" :items="lyricDownloader"
|
|
||||||
class="elevation-1" disable-sort>
|
|
||||||
<template v-slot:item.enabled="{ item }">
|
|
||||||
<v-simple-checkbox v-model="item.enabled" color="primary"/>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
</v-list-item>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
<v-col cols="6">
|
|
||||||
<v-subheader>标签解析器设置</v-subheader>
|
|
||||||
<v-list-item>
|
|
||||||
<v-data-table hide-default-footer :headers="tagParserHeaders" :items="tagParser" class="elevation-1"
|
|
||||||
disable-sort>
|
|
||||||
<template v-slot:item.enabled="{ item }">
|
|
||||||
<v-simple-checkbox v-model="item.enabled" color="primary"></v-simple-checkbox>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
</v-list-item>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-list-item>
|
|
||||||
|
|
||||||
<v-divider class="mt-5"></v-divider>
|
|
||||||
<v-subheader>屏蔽字典</v-subheader>
|
|
||||||
<v-list-item>
|
|
||||||
<v-switch label="启用屏蔽字典" v-model="isBlockDictEnabled" @change="blockDictEnabledChange"/>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item>
|
|
||||||
<v-text-field :disabled="blockDictEnabled" v-model="blockDictPath" label="屏蔽字典路径"
|
|
||||||
placeholder="请选择屏蔽字典的文件路径。"/>
|
|
||||||
<v-btn :disabled="blockDictEnabled" icon @click="openBlockDict">
|
|
||||||
<v-icon>mdi-folder</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-item>
|
|
||||||
|
|
||||||
<v-divider></v-divider>
|
|
||||||
<v-subheader>扫描设置</v-subheader>
|
|
||||||
<v-list-item>
|
|
||||||
<v-text-field v-model="fileSearchSuffix" label="文件搜索后缀"
|
|
||||||
placeholder="请输入文件搜索后缀,多个后缀以英文逗号分隔。"/>
|
|
||||||
</v-list-item>
|
|
||||||
|
|
||||||
</v-list>
|
|
||||||
</v-form>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "Setting",
|
|
||||||
data: () => {
|
|
||||||
return {
|
|
||||||
isProxyEnabled: true,
|
|
||||||
proxyEnabled: false,
|
|
||||||
isBlockDictEnabled: true,
|
|
||||||
blockDictEnabled: false,
|
|
||||||
blockDictPath: "",
|
|
||||||
proxyAddress: "",
|
|
||||||
updateAddress: "",
|
|
||||||
mergeLrc: false,
|
|
||||||
lineBreak: "lf",
|
|
||||||
lineBreakOptions: [
|
|
||||||
{label: "LF", value: "lf"},
|
|
||||||
{label: "CRLF", value: "crlf"},
|
|
||||||
],
|
|
||||||
lrcEncoding: "utf-8",
|
|
||||||
lyricDownloaderHeaders: [
|
|
||||||
{text: "启用", value: "enabled"},
|
|
||||||
{text: "歌词源", value: "name"},
|
|
||||||
{text: "搜索深度", value: "searchDepth"},
|
|
||||||
{text: "优先级", value: "priority"},
|
|
||||||
],
|
|
||||||
lyricDownloader: [
|
|
||||||
{enabled: true, name: "网易云音乐", searchDepth: 10, priority: 1},
|
|
||||||
],
|
|
||||||
tagParserHeaders: [
|
|
||||||
{text: "启用", value: "enabled", sortable: false, width: "10%"},
|
|
||||||
{text: "标签解析器", value: "name", sortable: false, width: "90%"},
|
|
||||||
],
|
|
||||||
tagParser: [
|
|
||||||
{name: '正则表达式解析器', enabled: true},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {},
|
|
||||||
methods: {
|
|
||||||
proxyEnabledChange() {
|
|
||||||
this.proxyEnabled = !this.proxyEnabled;
|
|
||||||
},
|
|
||||||
blockDictEnabledChange() {
|
|
||||||
this.blockDictEnabled = !this.blockDictEnabled;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
@@ -1,6 +0,0 @@
|
|||||||
const { defineConfig } = require('@vue/cli-service')
|
|
||||||
module.exports = defineConfig({
|
|
||||||
transpileDependencies: [
|
|
||||||
'vuetify'
|
|
||||||
]
|
|
||||||
})
|
|
5654
src/ui/yarn.lock
5654
src/ui/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@ public class KuWoLyricsProviderTests : TestBase
|
|||||||
.FirstOrDefault(t => t.DownloaderName == InternalLyricsProviderNames.KuWo);
|
.FirstOrDefault(t => t.DownloaderName == InternalLyricsProviderNames.KuWo);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact(Skip = "Not Working")]
|
||||||
[Trait("LyricsProvider ", "KuGou")]
|
[Trait("LyricsProvider ", "KuGou")]
|
||||||
public async Task DownloadAsync_Test()
|
public async Task DownloadAsync_Test()
|
||||||
{
|
{
|
||||||
@@ -26,7 +26,7 @@ public class KuWoLyricsProviderTests : TestBase
|
|||||||
lyric.IsPruneMusic.ShouldBeFalse();
|
lyric.IsPruneMusic.ShouldBeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact(Skip = "Not Working")]
|
||||||
public async Task DownloadAsync_Source_Null_Test()
|
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",
|
var lyric = await _kuwoLyricsProvider.DownloadAsync("Concerto for Piano and Orchestra No. 12 in A major, K414 - 1. Allegro",
|
||||||
|
@@ -1,20 +1,20 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
|
||||||
<PackageReference Include="Shouldly" Version="4.2.1" />
|
<PackageReference Include="Shouldly"/>
|
||||||
<PackageReference Include="xunit" Version="2.4.2" />
|
<PackageReference Include="xunit"/>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
<PackageReference Include="xunit.runner.visualstudio">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
<PackageReference Include="coverlet.collector">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@@ -1,13 +1,8 @@
|
|||||||
New Features: None
|
New Features: None
|
||||||
Breaking Changes: None
|
Breaking Changes: None
|
||||||
Enhancement: :
|
Enhancement: None
|
||||||
|
|
||||||
- 网易云歌单下载歌词时,支持使用 `;` 传递多个歌单 ID。(`15445646;468435123;4131357`) - [`41cba02`](https://github.com/real-zony/ZonyLrcToolsX/commit/41cba028333d0cf65f7dc3ee466660cc20e558fc)
|
|
||||||
- 优化了结果提示信息,更加明确。- [`1e5c418`](https://github.com/real-zony/ZonyLrcToolsX/commit/1e5c41852f70df4b824d2795f175e57c82a0d104)
|
|
||||||
- 优化了程序的启动时间,不会每次启动都去检测更新了。- [`b240564`](https://github.com/real-zony/ZonyLrcToolsX/commit/b240564cf7ac3432715dd54c280d73f9f985c4fc)
|
|
||||||
|
|
||||||
Fixed Bugs:
|
Fixed Bugs:
|
||||||
|
|
||||||
- 更新了依赖的 NuGet 程序包版本。- [`1f312c7`](https://github.com/real-zony/ZonyLrcToolsX/commit/1f312c749d8e7784e7670ec3821db0b4b430ce2e)
|
- 修复了网易云音歌词下载功能无效的问题。- [243a0e2](https://github.com/real-zony/ZonyLrcToolsX/commit/243a0e2559d3d9925dfcb96d11e2c1b1372363e6)
|
||||||
- 过滤了包含特殊符号的文件路径,避免报错。 - [`62d08df`](https://github.com/real-zony/ZonyLrcToolsX/commit/62d08df7353343711741b23a6ecb9c3908754075)
|
- 修复了日志不正常显示的问题。
|
||||||
- 修复了从网易云歌单下载歌曲时,将专辑名称当作歌手名称进行取值。 - [`98c935e`](https://github.com/real-zony/ZonyLrcToolsX/commit/98c935ed93f9278e8606c056868824ea8335ee5d)
|
|
Reference in New Issue
Block a user