Files
ReleaseUpdater/ReleaseUpdater/ReleaseProvider.cs

85 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Net.Http.Headers;
using System.Text.Json;
namespace ReleaseUpdater;
/// <summary>
/// Провайдер для получения информации о релизах из Github / Gitea API.
/// </summary>
public sealed class ReleaseProvider
{
private static readonly JsonSerializerOptions JsonOpts = new(JsonSerializerDefaults.Web);
/// <summary>
/// Получает список всех релизов из указанного API.
/// </summary>
/// <param name="apiUrl">URL API Gitea для релизов.</param>
/// <param name="token">Токен авторизации (если требуется).</param>
/// <returns>Список релизов.</returns>
public async Task<IReadOnlyList<ReleaseInfo>> GetReleasesAsync(string apiUrl, string? token = null)
{
using var client = CreateClient(token);
using var resp = await client.GetAsync(apiUrl);
resp.EnsureSuccessStatusCode();
var stream = await resp.Content.ReadAsStreamAsync();
var releases = await JsonSerializer.DeserializeAsync<List<GiteaReleaseDto>>(stream, JsonOpts)
?? new List<GiteaReleaseDto>();
return releases.Select(Map).ToList();
}
/// <summary>
/// Находит релиз по версии или возвращает последний релиз.
/// </summary>
/// <param name="apiUrl">URL API Gitea для релизов.</param>
/// <param name="versionOrLatest">Версия (например, "3.5.2") или "latest".</param>
/// <param name="token">Токен авторизации (если требуется).</param>
/// <returns>Информация о релизе или null.</returns>
public async Task<ReleaseInfo?> FindReleaseAsync(string apiUrl, string? versionOrLatest, string? token = null)
{
var all = await GetReleasesAsync(apiUrl, token);
if (string.IsNullOrWhiteSpace(versionOrLatest) || versionOrLatest.Equals("latest", StringComparison.OrdinalIgnoreCase))
return all.FirstOrDefault();
var tag = versionOrLatest.StartsWith('v') ? versionOrLatest : $"v{versionOrLatest}";
return all.FirstOrDefault(r => string.Equals(r.TagName, tag, StringComparison.OrdinalIgnoreCase));
}
private static HttpClient CreateClient(string? token)
{
var client = new HttpClient();
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("ReleaseUpdater", "1.0"));
if (!string.IsNullOrWhiteSpace(token))
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("token", token);
return client;
}
private static ReleaseInfo Map(GiteaReleaseDto dto) =>
new()
{
TagName = dto.tag_name,
Name = dto.name,
Assets = dto.assets?.Select(a => new AssetInfo
{
Name = a.name,
DownloadUrl = new Uri(a.browser_download_url)
}).ToList() ?? new List<AssetInfo>()
};
// DTOs для десериализации JSON
private sealed class GiteaReleaseDto
{
public string tag_name { get; set; } = "";
public string? name { get; set; }
public List<GiteaAssetDto>? assets { get; set; }
}
private sealed class GiteaAssetDto
{
public string name { get; set; } = "";
public string browser_download_url { get; set; } = "";
}
}