Skip to content

Commit

Permalink
Merge pull request #30 from real-zony/aot
Browse files Browse the repository at this point in the history
Replace McMaster with System.CommandLine.
  • Loading branch information
real-zony authored Dec 13, 2023
2 parents 06185b2 + 8283062 commit 969a965
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 107 deletions.
32 changes: 16 additions & 16 deletions AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ public ApiRequestParameters()
{
SortedDictionary = new SortedDictionary<string, string>(StringComparer.Ordinal)
{
{"Format", "json"},
{"AccessKeyId", ConfigurationHelper.Configuration.AccessId},
{"SignatureMethod", "HMAC-SHA1"},
{"SignatureNonce", Guid.NewGuid().ToString()},
{"Version", "2015-01-09"},
{"SignatureVersion", "1.0"},
{"Timestamp", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")}
{ "Format", "json" },
{ "AccessKeyId", ConfigurationHelper.Configuration.AccessId },
{ "SignatureMethod", "HMAC-SHA1" },
{ "SignatureNonce", Guid.NewGuid().ToString() },
{ "Version", "2015-01-09" },
{ "SignatureVersion", "1.0" },
{ "Timestamp", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ") }
};
}

Expand All @@ -43,13 +43,13 @@ public void GenerateSignature()
{
var queryString = GenerateSortedQueryString();
var signBuilder = new StringBuilder();

signBuilder.Append(HttpMethod.Get)
.Append("&")
.Append('&')
.Append(SpecialUrlEncode("/"))
.Append("&")
.Append('&')
.Append(SpecialUrlEncode(queryString));

var hmac = new HMACSHA1(Encoding.UTF8.GetBytes($"{ConfigurationHelper.Configuration.AccessKey}&"));
var signStr = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(signBuilder.ToString())));
SortedDictionary.Add("Signature", signStr);
Expand All @@ -66,7 +66,7 @@ public virtual string GenerateSortedQueryString()
.Append(SpecialUrlEncode(kv.Value));
}

return sb.ToString().Substring(1);
return sb.ToString()[1..];
}

protected virtual string SpecialUrlEncode(string srcStr)
Expand All @@ -76,16 +76,16 @@ protected virtual string SpecialUrlEncode(string srcStr)
var bytes = Encoding.UTF8.GetBytes(srcStr);
foreach (var @byte in bytes)
{
var @char = (char) @byte;
var @char = (char)@byte;
// 如果值是 text 集合内的数据,则使用默认的值。
if (text.IndexOf(@char) >= 0)
if (text.Contains(@char))
{
stringBuilder.Append(@char);
}
else
{
stringBuilder.Append("%")
.Append(string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int) @char));
stringBuilder.Append('%')
.Append(string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)@char));
}
}

Expand Down
7 changes: 1 addition & 6 deletions AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ namespace AliCloudDynamicDNS.AliCloud.ApiRequest
{
public class ApiRequestTool
{
private readonly HttpClient _httpClient;

public ApiRequestTool()
{
_httpClient = new HttpClient();
}
private readonly HttpClient _httpClient = new();

public async Task<JObject> GetRecordsWithMainDomainAsync(string mainDomainName)
{
Expand Down
24 changes: 2 additions & 22 deletions AliCloudDynamicDNS/AliCloud/Models/AliCloudRecordModel.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
namespace AliCloudDynamicDNS.AliCloud.Models
{
public class AliCloudRecordModel
{
public string SubName { get; set; }
namespace AliCloudDynamicDNS.AliCloud.Models;

public string RecordId { get; set; }

public string Value { get; set; }

public AliCloudRecordModel(string subName, string recordId, string value)
{
SubName = subName;
RecordId = recordId;
Value = value;
}

public AliCloudRecordModel()
{

}
}
}
public record AliCloudRecordModel(string SubName, string RecordId, string Value);
6 changes: 5 additions & 1 deletion AliCloudDynamicDNS/AliCloudDynamicDNS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Nito.AsyncEx.Context" Version="5.1.2" />
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
<PackageReference Include="Nito.Disposables" Version="2.5.0" />
<PackageReference Include="System.Collections.Immutable" Version="8.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="System.CommandLine.Hosting" Version="0.4.0-alpha.22272.1" />
</ItemGroup>

<ItemGroup>
Expand Down
14 changes: 0 additions & 14 deletions AliCloudDynamicDNS/Commands/BaseCommand.cs

This file was deleted.

121 changes: 73 additions & 48 deletions AliCloudDynamicDNS/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.CommandLine;
using System.CommandLine.NamingConventionBinder;
using System.IO;
using System.Linq;
using System.Text;
Expand All @@ -8,33 +10,20 @@
using AliCloudDynamicDNS.Configuration;
using AliCloudDynamicDNS.Threading;
using AliCloudDynamicDNS.Utility;
using McMaster.Extensions.CommandLineUtils;
using Newtonsoft.Json.Linq;
using Nito.AsyncEx;

namespace AliCloudDynamicDNS
{
[HelpOption("-?|-h|--help")]
public class Program
{
[Option("-f|--file <FILE>", "指定自定义的配置文件,请传入配置文件的路径。", CommandOptionType.SingleValue)]
public string FilePath { get; set; }
public static string FilePath { get; set; }
public static uint Interval { get; set; }

[Option("-i|--interval <INTERVAL>", "指定程序的自动检测周期,单位是秒。", CommandOptionType.SingleValue)]
public uint Interval { get; set; }
private static StrongTimer _strongTimer;
private static readonly ApiRequestTool ApiRequestTool = new();

private StrongTimer _strongTimer;
private readonly ApiRequestTool _apiRequestTool = new ApiRequestTool();

public async Task OnExecuteAsync()
{
await InitializeConfigurationAsync();
InitializeStrongTimer();

await ConsoleAwaitExitAsync();
}

private async Task ConsoleAwaitExitAsync()
private static async Task ConsoleAwaitExitAsync()
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("");
Expand All @@ -48,8 +37,8 @@ private async Task ConsoleAwaitExitAsync()
Console.WriteLine("请输入:");
Console.ForegroundColor = ConsoleColor.Gray;

string command = Console.ReadLine().ToLower();
Console.WriteLine("");
var command = Console.ReadLine()?.ToLower();
Console.WriteLine(string.Empty);
switch (command)
{
case "exit":
Expand All @@ -76,18 +65,18 @@ private async Task ConsoleAwaitExitAsync()
}
}

private async Task ConsoleWriteIpInfo()
private static async Task ConsoleWriteIpInfo()
{
ConsoleHelper.WriteInfo($"正在获取当前公网IP,请稍等...");
var currentPubicIp = (await NetworkHelper.GetPublicNetworkIp()).Replace("\n", "");
ConsoleHelper.WriteInfo($"当前的公网IP:{currentPubicIp}");
await ConsoleAwaitExitAsync();
}

private void ConsoleWriteConfigInfo()
private static void ConsoleWriteConfigInfo()
{
var intervalSec = (int) TimeSpan.FromSeconds(Interval).TotalSeconds;
StringBuilder iniConfMsg = new StringBuilder();
var intervalSec = (int)TimeSpan.FromSeconds(Interval).TotalSeconds;
var iniConfMsg = new StringBuilder();
iniConfMsg.AppendLine($"\t当前配置内容如下:");
iniConfMsg.AppendLine($"\t监听的时间周期:{intervalSec} 秒");
iniConfMsg.AppendLine($"\tAccessId:{ConfigurationHelper.Configuration.AccessId}");
Expand All @@ -97,13 +86,14 @@ private void ConsoleWriteConfigInfo()
foreach (var subDomain in ConfigurationHelper.Configuration.SubDomains)
{
subDomainSerialNumber++;
iniConfMsg.AppendLine($"\t\t子域名地址{subDomainSerialNumber}{subDomain.SubDomain}.{ConfigurationHelper.Configuration.MainDomain} - 记录类型:{subDomain.Type}");
iniConfMsg.AppendLine(
$"\t\t子域名地址{subDomainSerialNumber}{subDomain.SubDomain}.{ConfigurationHelper.Configuration.MainDomain} - 记录类型:{subDomain.Type}");
}

ConsoleHelper.WriteInfo(iniConfMsg.ToString());
}

private async Task InitializeConfigurationAsync()
private static async Task InitializeConfigurationAsync()
{
var filePath = FilePath ?? Path.Combine(Environment.CurrentDirectory, "settings.json");
if (!File.Exists(filePath))
Expand All @@ -116,16 +106,16 @@ private async Task InitializeConfigurationAsync()
ConsoleWriteConfigInfo();
}

private void InitializeStrongTimer()
private static void InitializeStrongTimer()
{
int minInterval = 30;
const int minInterval = 30;
if (Interval < minInterval && Interval != 0)
{
ConsoleHelper.WriteError($"指定的时间周期必须大于或等于 {minInterval} 秒,用户指定的值:{Interval}");
Environment.Exit(-1);
}

var intervalSec = (int) TimeSpan.FromSeconds(Interval).TotalMilliseconds;
var intervalSec = (int)TimeSpan.FromSeconds(Interval).TotalMilliseconds;
_strongTimer = new StrongTimer
{
Period = intervalSec == 0 ? 5000 : intervalSec,
Expand All @@ -137,28 +127,28 @@ private void InitializeStrongTimer()
_strongTimer.Start();
ConsoleHelper.WriteMessage("程序已经开始运行...");

if (Interval == 0)
if (Interval != 0)
{
_strongTimer.Stop();
ConsoleHelper.WriteMessage("程序执行完成...");
Environment.Exit(0);
return;
}

_strongTimer.Stop();
ConsoleHelper.WriteMessage("程序执行完成...");
Environment.Exit(0);
}

private async Task UpdateRecord(bool isWriteNoUpdateInfo = false)
private static async Task UpdateRecord(bool isWriteNoUpdateInfo = false)
{
try
{
var records = (await _apiRequestTool.GetRecordsWithMainDomainAsync(ConfigurationHelper.Configuration.MainDomain))
var records =
(await ApiRequestTool.GetRecordsWithMainDomainAsync(ConfigurationHelper.Configuration.MainDomain))
.SelectTokens($"$.DomainRecords.Record[*]")
.Select(x => new AliCloudRecordModel
{
RecordId = x.SelectToken("$.RecordId")?.Value<string>(),
SubName = x.SelectToken("$.RR")?.Value<string>(),
Value = x.SelectToken("$.Value")?.Value<string>()
})
.Select(x => new AliCloudRecordModel(x.SelectToken("$.RR")?.Value<string>(),
x.SelectToken("$.RecordId")?.Value<string>(), x.SelectToken("$.Value")?.Value<string>()))
.ToList();
ConsoleHelper.WriteInfo($"远程API获取的域名[{ConfigurationHelper.Configuration.MainDomain}]的解析记录有:{records.Count}条");
ConsoleHelper.WriteInfo(
$"远程API获取的域名[{ConfigurationHelper.Configuration.MainDomain}]的解析记录有:{records.Count}条");
var currentPubicIp = (await NetworkHelper.GetPublicNetworkIp()).Replace("\n", "");
if (!string.IsNullOrEmpty(currentPubicIp))
{
Expand All @@ -168,29 +158,35 @@ private async Task UpdateRecord(bool isWriteNoUpdateInfo = false)
var record = records.FirstOrDefault(x => x.SubName == subDomain.SubDomain);
if (record == null)
{
ConsoleHelper.WriteError($" {record.SubName}.{ConfigurationHelper.Configuration.MainDomain} 在远程API获取的域名中未找到,无法进行更新IP操作...");
ConsoleHelper.WriteError(
$" {record.SubName}.{ConfigurationHelper.Configuration.MainDomain} 在远程API获取的域名中未找到,无法进行更新IP操作...");
continue;
}

if (record.Value == currentPubicIp)
{
if (isWriteNoUpdateInfo)
{
ConsoleHelper.WriteInfo($"{record.SubName}.{ConfigurationHelper.Configuration.MainDomain} 记录的IP与当前获取的公网IP一致,无需更新");
ConsoleHelper.WriteInfo(
$"{record.SubName}.{ConfigurationHelper.Configuration.MainDomain} 记录的IP与当前获取的公网IP一致,无需更新");
}

continue;
}

// 更新指定的子域名 IP。
var result = (await _apiRequestTool.UpdateRecordAsync(record.RecordId, currentPubicIp, subDomain)).SelectToken("$.RecordId").Value<string>();
var result =
(await ApiRequestTool.UpdateRecordAsync(record.RecordId, currentPubicIp, subDomain))
.SelectToken("$.RecordId").Value<string>();
if (result == null || result != record.RecordId)
{
ConsoleHelper.WriteError($" {record.SubName}.{ConfigurationHelper.Configuration.MainDomain} 更新失败...");
ConsoleHelper.WriteError(
$" {record.SubName}.{ConfigurationHelper.Configuration.MainDomain} 更新失败...");
}
else
{
ConsoleHelper.WriteInfo($" {record.SubName}.{ConfigurationHelper.Configuration.MainDomain} 更新成功,IP:{record.Value} => {currentPubicIp}");
ConsoleHelper.WriteInfo(
$" {record.SubName}.{ConfigurationHelper.Configuration.MainDomain} 更新成功,IP:{record.Value} => {currentPubicIp}");
}
}
}
Expand All @@ -205,6 +201,35 @@ private async Task UpdateRecord(bool isWriteNoUpdateInfo = false)
}
}

public static Task<int> Main(string[] args) => CommandLineApplication.ExecuteAsync<Program>(args);
public static Task<int> Main(string[] args)
{
var rootCommand = new RootCommand();

var fileOption = new Option<string>(
new[] { "-f", "--file" },
"指定自定义的配置文件,请传入配置文件的路径。"
);

var intervalOption = new Option<uint>(
new[] { "-i", "--interval" },
"指定程序的自动检测周期,单位是秒。"
);

rootCommand.AddOption(fileOption);
rootCommand.AddOption(intervalOption);
rootCommand.Handler = CommandHandler.Create<string, uint>(async (file, interval) =>
{
Interval = interval;
FilePath = file;

await InitializeConfigurationAsync();
InitializeStrongTimer();
await ConsoleAwaitExitAsync();

return 0;
});

return rootCommand.InvokeAsync(args);
}
}
}

0 comments on commit 969a965

Please sign in to comment.