add: WeatherModule

This commit is contained in:
jackfiled 2023-11-01 22:33:41 +08:00
parent 014fb2a44d
commit e477c015af
4 changed files with 145 additions and 0 deletions

View File

@ -0,0 +1,26 @@
using Katheryne.Modules;
using Xunit.Abstractions;
namespace Katheryne.Tests.Modules;
public class WeatherModuleTests
{
private readonly ITestOutputHelper _output;
public WeatherModuleTests(ITestOutputHelper output)
{
_output = output;
}
[Fact]
public void WeatherModuleTest()
{
var weather = new WeatherModule();
Assert.True(weather.ContainsParam("text"));
Assert.True(weather.ContainsParam("temp"));
_output.WriteLine(weather["text"]);
_output.WriteLine(weather["temp"]);
}
}

View File

@ -0,0 +1,22 @@
namespace Katheryne.Exceptions;
/// <summary>
/// 调用模块中发生的异常
/// </summary>
public class ModuleException : Exception
{
public ModuleException() : base()
{
}
public ModuleException(string message) : base(message)
{
}
public ModuleException(string message, Exception innerException) : base(message, innerException)
{
}
}

View File

@ -0,0 +1,30 @@
using System.Text.Json;
using Katheryne.Abstractions;
namespace Katheryne.Modules;
public abstract class ModuleBase : IParamsModule
{
protected readonly Dictionary<string, Func<string>> Functions = new();
protected readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true
};
public abstract string ModuleName { get; }
public string this[string param]
{
get
{
Func<string> func = Functions[param];
return func();
}
}
public bool ContainsParam(string param)
{
return Functions.ContainsKey(param);
}
}

View File

@ -0,0 +1,67 @@
using System.Net.Http.Json;
using System.Text.Json.Serialization;
using Katheryne.Exceptions;
namespace Katheryne.Modules;
public class WeatherModule : ModuleBase
{
private static readonly HttpClient s_httpClient = new();
private const string WeatherApi =
"https://api.seniverse.com/v3/weather/now.json?key=S7s93MkxJ1q7mgHoj&location=beijing&language=zh-Hans&unit=c";
private WeatherDto? _weatherDto;
public override string ModuleName => "weather";
public WeatherModule()
{
Functions.Add("text", () => FetchWeatherDate().Now.Text);
Functions.Add("temp", () => FetchWeatherDate().Now.Temperature);
}
private WeatherDto FetchWeatherDate()
{
if (_weatherDto is not null)
{
if (DateTime.Now - _weatherDto.LastUpdate < TimeSpan.FromMinutes(5))
{
return _weatherDto;
}
}
try
{
Task<Dictionary<string, List<WeatherDto>>?> task = s_httpClient.GetFromJsonAsync<Dictionary<string, List<WeatherDto>>>(
WeatherApi, JsonOptions);
task.Wait();
Dictionary<string, List<WeatherDto>>? response = task.Result;
WeatherDto? weather = response?["results"][0];
_weatherDto = weather ?? throw new ModuleException("Failed to fetch weather data.");
return _weatherDto;
}
catch (HttpRequestException e)
{
throw new ModuleException("Failed to fetch weather data.", e);
}
}
private class WeatherNowDto
{
public required string Text { get; set; }
public required string Code { get; set; }
public required string Temperature { get; set; }
}
private class WeatherDto
{
public required WeatherNowDto Now { get; set; }
[JsonPropertyName("last_update")]
public DateTime LastUpdate { get; set; }
}
}