From d99449ea5d2e0f199b3d05726c52c8fd1c03537b Mon Sep 17 00:00:00 2001 From: real-zony Date: Wed, 13 Dec 2023 22:54:48 +0800 Subject: [PATCH 1/2] refactor: Adjusted the syntax related to Alibaba Cloud requests. --- .../ApiRequest/ApiRequestParameters.cs | 32 +++++++++---------- .../AliCloud/ApiRequest/ApiRequestTool.cs | 7 +--- .../AliCloud/Models/AliCloudRecordModel.cs | 24 ++------------ 3 files changed, 19 insertions(+), 44 deletions(-) diff --git a/AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestParameters.cs b/AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestParameters.cs index 6a999d9..85f6fcb 100644 --- a/AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestParameters.cs +++ b/AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestParameters.cs @@ -14,13 +14,13 @@ public ApiRequestParameters() { SortedDictionary = new SortedDictionary(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") } }; } @@ -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); @@ -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) @@ -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)); } } diff --git a/AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestTool.cs b/AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestTool.cs index 098b464..ca59a80 100644 --- a/AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestTool.cs +++ b/AliCloudDynamicDNS/AliCloud/ApiRequest/ApiRequestTool.cs @@ -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 GetRecordsWithMainDomainAsync(string mainDomainName) { diff --git a/AliCloudDynamicDNS/AliCloud/Models/AliCloudRecordModel.cs b/AliCloudDynamicDNS/AliCloud/Models/AliCloudRecordModel.cs index ed6d046..303873f 100644 --- a/AliCloudDynamicDNS/AliCloud/Models/AliCloudRecordModel.cs +++ b/AliCloudDynamicDNS/AliCloud/Models/AliCloudRecordModel.cs @@ -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() - { - - } - } -} \ No newline at end of file +public record AliCloudRecordModel(string SubName, string RecordId, string Value); \ No newline at end of file From 8283062a14a8a015369f7e3a0d25332ea88d6438 Mon Sep 17 00:00:00 2001 From: real-zony Date: Wed, 13 Dec 2023 23:16:42 +0800 Subject: [PATCH 2/2] refactor: Replaced the McMaster package with System.CommandLine. --- AliCloudDynamicDNS/AliCloudDynamicDNS.csproj | 6 +- AliCloudDynamicDNS/Commands/BaseCommand.cs | 14 --- AliCloudDynamicDNS/Program.cs | 121 +++++++++++-------- 3 files changed, 78 insertions(+), 63 deletions(-) delete mode 100644 AliCloudDynamicDNS/Commands/BaseCommand.cs diff --git a/AliCloudDynamicDNS/AliCloudDynamicDNS.csproj b/AliCloudDynamicDNS/AliCloudDynamicDNS.csproj index 740af6a..025e76e 100644 --- a/AliCloudDynamicDNS/AliCloudDynamicDNS.csproj +++ b/AliCloudDynamicDNS/AliCloudDynamicDNS.csproj @@ -7,9 +7,13 @@ - + + + + + diff --git a/AliCloudDynamicDNS/Commands/BaseCommand.cs b/AliCloudDynamicDNS/Commands/BaseCommand.cs deleted file mode 100644 index 6f7144f..0000000 --- a/AliCloudDynamicDNS/Commands/BaseCommand.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Threading.Tasks; -using McMaster.Extensions.CommandLineUtils; - -namespace AliCloudDynamicDNS.Commands -{ - [HelpOption("-?|-h|--help", Description = "欢迎使用 AliDDNSNet 工具。")] - public abstract class BaseCommand - { - protected virtual Task OnExecuteAsync(CommandLineApplication app) - { - return Task.FromResult(0); - } - } -} \ No newline at end of file diff --git a/AliCloudDynamicDNS/Program.cs b/AliCloudDynamicDNS/Program.cs index 1411dae..652e6cf 100644 --- a/AliCloudDynamicDNS/Program.cs +++ b/AliCloudDynamicDNS/Program.cs @@ -1,4 +1,6 @@ using System; +using System.CommandLine; +using System.CommandLine.NamingConventionBinder; using System.IO; using System.Linq; using System.Text; @@ -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 ", "指定自定义的配置文件,请传入配置文件的路径。", CommandOptionType.SingleValue)] - public string FilePath { get; set; } + public static string FilePath { get; set; } + public static uint Interval { get; set; } - [Option("-i|--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(""); @@ -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": @@ -76,7 +65,7 @@ private async Task ConsoleAwaitExitAsync() } } - private async Task ConsoleWriteIpInfo() + private static async Task ConsoleWriteIpInfo() { ConsoleHelper.WriteInfo($"正在获取当前公网IP,请稍等..."); var currentPubicIp = (await NetworkHelper.GetPublicNetworkIp()).Replace("\n", ""); @@ -84,10 +73,10 @@ private async Task ConsoleWriteIpInfo() 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}"); @@ -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)) @@ -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, @@ -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(), - SubName = x.SelectToken("$.RR")?.Value(), - Value = x.SelectToken("$.Value")?.Value() - }) + .Select(x => new AliCloudRecordModel(x.SelectToken("$.RR")?.Value(), + x.SelectToken("$.RecordId")?.Value(), x.SelectToken("$.Value")?.Value())) .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)) { @@ -168,7 +158,8 @@ 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; } @@ -176,21 +167,26 @@ private async Task UpdateRecord(bool isWriteNoUpdateInfo = false) { 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(); + var result = + (await ApiRequestTool.UpdateRecordAsync(record.RecordId, currentPubicIp, subDomain)) + .SelectToken("$.RecordId").Value(); 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}"); } } } @@ -205,6 +201,35 @@ private async Task UpdateRecord(bool isWriteNoUpdateInfo = false) } } - public static Task Main(string[] args) => CommandLineApplication.ExecuteAsync(args); + public static Task Main(string[] args) + { + var rootCommand = new RootCommand(); + + var fileOption = new Option( + new[] { "-f", "--file" }, + "指定自定义的配置文件,请传入配置文件的路径。" + ); + + var intervalOption = new Option( + new[] { "-i", "--interval" }, + "指定程序的自动检测周期,单位是秒。" + ); + + rootCommand.AddOption(fileOption); + rootCommand.AddOption(intervalOption); + rootCommand.Handler = CommandHandler.Create(async (file, interval) => + { + Interval = interval; + FilePath = file; + + await InitializeConfigurationAsync(); + InitializeStrongTimer(); + await ConsoleAwaitExitAsync(); + + return 0; + }); + + return rootCommand.InvokeAsync(args); + } } } \ No newline at end of file