网站首页 网站源码
using System.Collections.Specialized;
using System.Net.Http;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Dpz.Core.Service;
public interface IBingWallpaper
{
/// <summary>
/// 随机获取一张壁纸
/// </summary>
/// <returns></returns>
Task<Wallpaper> GetRandomWallpaperAsync();
/// <summary>
/// 获取今日的所有壁纸
/// </summary>
/// <returns></returns>
Task<List<Wallpaper>> GetTodayWallpapersAsync();
/// <summary>
/// 清除缓存
/// </summary>
/// <returns></returns>
Task ClearCacheAsync();
}
public class Wallpaper
{
private const string Host = "https://cn.bing.com";
private string _url = "";
[JsonProperty("url")]
public string Url
{
get => _url.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? _url : Host + _url;
set => _url = value;
}
[JsonProperty("copyright")]
public string? CopyRight { get; set; }
[JsonProperty("copyrightlink")]
public string? CopyRightLink { get; set; }
}
public class BingWallpaper(
ILogger<BingWallpaper> logger,
IHttpClientFactory httpClientFactory,
IFusionCache fusionCache
) : AbstractCacheService(fusionCache), IBingWallpaper
{
private const string BingWallpaperKey = "bing-wallpaper-8";
private const string BingWallpaperRandomKey = "bing-wallpaper-random:first";
private readonly Wallpaper _defaultWallpaper =
new()
{
Url =
"/th?id=OHR.RedAlley_ZH-CN2795378972_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp",
CopyRight = "武侯祠内红墙和竹林掩映下的小巷,中国成都 (© Eastimages/Getty Images)",
CopyRightLink =
"https://www.bing.com/search?q=%E6%AD%A6%E4%BE%AF%E7%A5%A0&form=hpcapt&mkt=zh-cn",
};
private async Task<List<Wallpaper>> FetchWallpaperAsync(
CancellationToken cancellationToken = default
)
{
try
{
//var request = new RestRequest("/HPImageArchive.aspx", Method.GET);
var parameters = new NameValueCollection
{
{ "format", "js" },
//请求图片截止天数 0 今天 -1 截止中明天 (预准备的) 1 截止至昨天,类推(目前最多获取到7天前的图片)
{ "idx", "0" },
//1-8 返回请求数量,目前最多一次获取8张
{ "n", "8" },
//地区
{ "mkt", "zh-CN" },
};
var httpClient = httpClientFactory.CreateClient("edge");
var request = new HttpRequestMessage(
HttpMethod.Get,
$"https://cn.bing.com/HPImageArchive.aspx?{parameters.ToQueryString()}"
);
var response = await httpClient.SendAsync(request, cancellationToken);
var content = await response.Content.ReadAsStringAsync(cancellationToken);
var result = JObject.Parse(content)["images"]?.ToObject<List<Wallpaper>>() ?? [];
return result;
}
catch (Exception e)
{
logger.LogError(e, "获取bing壁纸失败");
var result = new List<Wallpaper> { _defaultWallpaper };
return result;
}
}
private async Task<List<Wallpaper>> GetWallpaperAsync()
{
return await GetOrSetCacheAsync<List<Wallpaper>>(
nameof(GetWallpaperAsync),
(_, cancellationToken) => FetchWallpaperAsync(cancellationToken)
);
}
public async Task<Wallpaper> GetRandomWallpaperAsync()
{
return await GetOrSetCacheAsync<Wallpaper>(
nameof(GetRandomWallpaperAsync),
async (_, _) =>
{
var list = await GetWallpaperAsync();
var result = list.OrderBy(_ => Guid.NewGuid()).FirstOrDefault();
return result ?? _defaultWallpaper;
}
);
}
public async Task<List<Wallpaper>> GetTodayWallpapersAsync()
{
return await GetWallpaperAsync();
}
public async Task ClearCacheAsync()
{
await RemoveByPrefixAsync();
}
protected override string CachePrefixKey => "Dpz.Core.Service.BingWallpaper";
protected override TimeSpan CacheDefaultExpiration => TimeSpan.FromDays(1);
}
上述代码定义了一个用于获取必应(Bing)壁纸的服务,主要功能包括获取随机壁纸、获取今日壁纸以及清除缓存。以下是代码的详细解释:
IBingWallpaper
该接口定义了三个异步方法:
GetRandomWallpaperAsync()
: 随机获取一张壁纸。GetTodayWallpapersAsync()
: 获取今日的所有壁纸。ClearCacheAsync()
: 清除缓存。Wallpaper
该类表示一张壁纸,包含以下属性:
Url
: 壁纸的URL,确保返回的URL是完整的(以http
开头),如果不是,则自动添加必应的主机名。CopyRight
: 壁纸的版权信息。CopyRightLink
: 版权信息的链接。BingWallpaper
该类实现了 IBingWallpaper
接口,提供了具体的壁纸获取逻辑。构造函数接受三个参数:
ILogger<BingWallpaper>
: 用于记录日志。IHttpClientFactory
: 用于创建HTTP客户端。IHybridCachingProvider
: 用于缓存管理。FetchWallpaperAsync()
该方法用于从必应的API获取壁纸数据:
Wallpaper
对象列表。cachingProvider
中,并移除随机壁纸的缓存。GetRandomWallpaperAsync()
该方法用于获取一张随机壁纸:
FetchWallpaperAsync()
获取壁纸。GetTodayWallpapersAsync()
该方法用于获取今日的所有壁纸:
FetchWallpaperAsync()
获取并缓存。ClearCacheAsync()
该方法用于清除缓存,实际上是调用 FetchWallpaperAsync()
方法来重新获取壁纸并更新缓存。
整体上,这段代码实现了一个壁纸服务,能够从必应获取壁纸并提供缓存机制,以提高性能和减少API调用。它还处理了错误情况,确保在获取壁纸失败时返回一个默认的壁纸。