81 lines
3.5 KiB
C#
81 lines
3.5 KiB
C#
using System.Net.Http.Json;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace LMEMappeCatastaliApp.Services;
|
|
|
|
public sealed class AppUpdateService
|
|
{
|
|
private const string ReleasesUrl = "https://gitea.lmcloud.it/api/v1/repos/livio/LMEMappeCatastaliProApp/releases?limit=50";
|
|
private static readonly Regex ProTagPattern = new(
|
|
@"^v?(?<version>\d+\.\d+\.\d+)-pro(?:[-.].*)?$",
|
|
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
|
private readonly HttpClient _httpClient = new() { Timeout = TimeSpan.FromSeconds(20) };
|
|
|
|
public static string CurrentVersion =>
|
|
typeof(AppUpdateService).Assembly
|
|
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
|
|
.InformationalVersion.Split('+')[0]
|
|
?? AppInfo.Current.VersionString;
|
|
|
|
public async Task<AppUpdateResult> CheckAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
var releases = await _httpClient.GetFromJsonAsync<GiteaRelease[]>(ReleasesUrl, cancellationToken)
|
|
?? throw new InvalidDataException("Risposta aggiornamenti non valida.");
|
|
GiteaRelease? selectedRelease = null;
|
|
GiteaAsset? selectedApk = null;
|
|
Version? selectedVersion = null;
|
|
foreach (var release in releases.Where(item => !item.Draft))
|
|
{
|
|
var match = ProTagPattern.Match(release.TagName ?? string.Empty);
|
|
var apk = release.Assets?.FirstOrDefault(item => IsProApk(item.Name));
|
|
if (!match.Success || apk is null || !Version.TryParse(match.Groups["version"].Value, out var version))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (selectedVersion is null || version > selectedVersion)
|
|
{
|
|
selectedRelease = release;
|
|
selectedApk = apk;
|
|
selectedVersion = version;
|
|
}
|
|
}
|
|
|
|
if (selectedRelease is null || selectedApk is null || selectedVersion is null)
|
|
{
|
|
throw new InvalidDataException("Nessuna release compatibile con LME Mappe Catastali Pro trovata.");
|
|
}
|
|
|
|
_ = Version.TryParse(CurrentVersion, out var current);
|
|
return new(
|
|
current is not null && selectedVersion > current,
|
|
selectedVersion.ToString(3),
|
|
selectedRelease.HtmlUrl ?? string.Empty,
|
|
selectedApk.BrowserDownloadUrl ?? selectedRelease.HtmlUrl ?? string.Empty,
|
|
selectedRelease.Body ?? string.Empty);
|
|
}
|
|
|
|
private static bool IsProApk(string? name) =>
|
|
name?.StartsWith("LME-Mappe-Catastali-Pro-", StringComparison.OrdinalIgnoreCase) == true
|
|
&& name.EndsWith(".apk", StringComparison.OrdinalIgnoreCase);
|
|
|
|
private sealed class GiteaRelease
|
|
{
|
|
[JsonPropertyName("tag_name")] public string? TagName { get; set; }
|
|
[JsonPropertyName("html_url")] public string? HtmlUrl { get; set; }
|
|
[JsonPropertyName("assets")] public GiteaAsset[]? Assets { get; set; }
|
|
[JsonPropertyName("body")] public string? Body { get; set; }
|
|
[JsonPropertyName("draft")] public bool Draft { get; set; }
|
|
}
|
|
|
|
private sealed class GiteaAsset
|
|
{
|
|
[JsonPropertyName("name")] public string? Name { get; set; }
|
|
[JsonPropertyName("browser_download_url")] public string? BrowserDownloadUrl { get; set; }
|
|
}
|
|
}
|
|
|
|
public sealed record AppUpdateResult(bool IsAvailable, string Version, string ReleaseUrl, string DownloadUrl, string ReleaseNotes);
|