Skip to content

Commit

Permalink
Merge pull request #5 from dr1rrb/dev/dr/net9
Browse files Browse the repository at this point in the history
Udpate dotnet
  • Loading branch information
dr1rrb authored Dec 23, 2024
2 parents 4879257 + 55bc453 commit ace4ce1
Show file tree
Hide file tree
Showing 17 changed files with 345 additions and 439 deletions.
90 changes: 34 additions & 56 deletions Crawler/DuplicatiCrawler/Client/AzureDevOps/AzureDevOpsApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,76 +2,54 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Crawler.Extensions;
using Newtonsoft.Json;

namespace Crawler.Client.AzureDevOps
namespace Crawler.Client.AzureDevOps;

internal sealed class AzureDevOpsApi(string auth) : IDisposable
{
public class AzureDevOpsApi : IDisposable
private readonly HttpClient _client = new()
{
private readonly HttpClient _client;

public AzureDevOpsApi(string auth)
BaseAddress = new Uri("https://dev.azure.com/dr1rrb/docker-duplicati-win/_apis/"),
DefaultRequestHeaders =
{
_client = new HttpClient
{
BaseAddress = new Uri("https://dev.azure.com/dr1rrb/docker-duplicati-win/_apis/"),
DefaultRequestHeaders =
{
{ "Authorization", auth}
}
};
{ "Authorization", auth}
}
};

public async Task<Dictionary<string, VariableGroup>> GetBuildVariables(CancellationToken ct)
{
using (var response = await _client.GetAsync("distributedtask/variablegroups?api-version=5.0-preview.1", ct))
{
var raw = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();
var groups = JsonConvert.DeserializeObject<GetVariableGroupsResponse>(raw).Groups;

return groups.ToDictionary(g => g.Name.TrimStart("duplicati-", StringComparison.OrdinalIgnoreCase));
}
}
public async Task<Dictionary<string, VariableGroup>> GetBuildVariables(CancellationToken ct)
{
var response = await _client.GetFromJsonAsync<GetVariableGroupsResponse>("distributedtask/variablegroups?api-version=5.0-preview.1", ct)
?? throw new InvalidOperationException("Failed to get build variables.");

public async Task UpdateBuildVariables(VariableGroup group, CancellationToken ct)
{
var body = new StringContent(JsonConvert.SerializeObject(group, Formatting.None), Encoding.UTF8, "application/json");
return response.Groups.ToDictionary(g => g.Name.TrimStart("duplicati-", StringComparison.OrdinalIgnoreCase));
}

using (var response = await _client.PutAsync($"distributedtask/variablegroups/{@group.Id}?api-version=5.0-preview.1", body, ct))
{
response.EnsureSuccessStatusCode();
}
}
public async Task UpdateBuildVariables(VariableGroup group, CancellationToken ct)
{
using var body = JsonContent.Create(group);
using var response = await _client.PutAsync($"distributedtask/variablegroups/{group.Id}?api-version=5.0-preview.1", body, ct);
response.EnsureSuccessStatusCode();
}

public async Task QueueBuild(string channel, CancellationToken ct)
public async Task QueueBuild(string channel, CancellationToken ct)
{
var parameters = new Dictionary<string, string>
{
var parameters = new Dictionary<string, string>
{
{ "duplicati.channel", channel }
};
var request = new QueueBuildRequest
{
Definition = new BuildDefinition
{
Id = 1
},
Parameters = JsonConvert.SerializeObject(parameters, Formatting.None)
};
var body = new StringContent(JsonConvert.SerializeObject(request, Formatting.None), Encoding.UTF8, "application/json");
{ "duplicati.channel", channel }
};

using (var response = await _client.PostAsync("build/builds?api-version=5.0", body, ct))
{
response.EnsureSuccessStatusCode();
}
}
using var body = JsonContent.Create(new QueueBuildRequest(new BuildDefinition(1), JsonSerializer.Serialize(parameters)));
using var response = await _client.PostAsync("build/builds?api-version=5.0", body, ct);
response.EnsureSuccessStatusCode();
}

/// <inheritdoc />
public void Dispose()
=> _client.Dispose();
/// <inheritdoc />
public void Dispose()
=> _client.Dispose();

}
}
15 changes: 4 additions & 11 deletions Crawler/DuplicatiCrawler/Client/AzureDevOps/BuildDefinition.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace Crawler.Client.AzureDevOps
{
public class BuildDefinition
{
[JsonProperty("id")]
public int Id { get; set; }
}
}
namespace Crawler.Client.AzureDevOps;

internal sealed record BuildDefinition([property: JsonPropertyName("id")] int Id);
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace Crawler.Client.AzureDevOps
{
internal class GetVariableGroupsResponse
{
[JsonProperty("value")]
public VariableGroup[] Groups { get; set; }
}
}
namespace Crawler.Client.AzureDevOps;

internal sealed record GetVariableGroupsResponse([property: JsonPropertyName("value")] VariableGroup[] Groups);
18 changes: 5 additions & 13 deletions Crawler/DuplicatiCrawler/Client/AzureDevOps/QueueBuildRequest.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace Crawler.Client.AzureDevOps
{
public class QueueBuildRequest
{
[JsonProperty("definition")]
public BuildDefinition Definition { get; set; }
namespace Crawler.Client.AzureDevOps;

[JsonProperty("parameters")]
public string Parameters { get; set; }
}
}
internal sealed record QueueBuildRequest(
[property: JsonPropertyName("definition")] BuildDefinition Definition,
[property: JsonPropertyName("parameters")] string Parameters);
15 changes: 4 additions & 11 deletions Crawler/DuplicatiCrawler/Client/AzureDevOps/Variable.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace Crawler.Client.AzureDevOps
{
public class Variable
{
[JsonProperty("value")]
public string Value { get; set; }
}
}
namespace Crawler.Client.AzureDevOps;

internal sealed record Variable([property: JsonPropertyName("value")] string Value);
48 changes: 17 additions & 31 deletions Crawler/DuplicatiCrawler/Client/AzureDevOps/VariableGroup.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using System.Collections.Immutable;
using System.Text.Json.Serialization;

namespace Crawler.Client.AzureDevOps
{
public class VariableGroup
{
[JsonProperty("id")]
public uint Id { get; set; }

[JsonProperty("name")]
public string Name { get; set; }
namespace Crawler.Client.AzureDevOps;

[JsonProperty("variables")]
public Dictionary<string, Variable> Variables { get; set; }

// Yes its ugly ... it a mutable entity
[JsonIgnore]
public string this[string key] => Variables[Name.Replace('-', '.') + '.' + key].Value;
internal sealed record VariableGroup(
[property: JsonPropertyName("id")] uint Id,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("variables")] ImmutableDictionary<string, Variable> Variables)
{
[JsonIgnore]
public string this[string key] => Variables[Name.Replace('-', '.') + '.' + key].Value;

public bool TryUpdate(string key, string value)
{
var variable = Variables[Name.Replace('-', '.') + '.' + key];
public VariableGroup With(string key, string value)
{
var variableName = Name.Replace('-', '.') + '.' + key;

if (variable.Value.Equals(value, StringComparison.OrdinalIgnoreCase))
{
return false;
}
else
{
variable.Value = value;
return true;
}
}
return Variables.TryGetValue(variableName, out var current)
&& current.Value.Equals(value, StringComparison.Ordinal)
? this
: this with { Variables = Variables.SetItem(variableName, new(value)) };
}
}
15 changes: 4 additions & 11 deletions Crawler/DuplicatiCrawler/Client/GitHub/Asset.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace Crawler.Client.GitHub
{
public class Asset
{
[JsonProperty("browser_download_url")]
public string Url { get; set; }
}
}
namespace Crawler.Client.GitHub;

internal sealed record Asset([property: JsonPropertyName("browser_download_url")] string Url);
75 changes: 33 additions & 42 deletions Crawler/DuplicatiCrawler/Client/GitHub/GitHubApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,49 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Crawler.Client.GitHub
{
public class GitHubApi : IDisposable
{
private static readonly Regex _releaseVersion = new Regex(@"[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+_(?<channel>[a-zA-Z]+)_[0-9]{4}-[0-9]{2}-[0-9]{2}");
namespace Crawler.Client.GitHub;

private readonly HttpClient _client;
internal sealed class GitHubApi : IDisposable
{
private static readonly Regex _releaseVersion = new(@"[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+_(?<channel>[a-zA-Z]+)_[0-9]{4}-[0-9]{2}-[0-9]{2}");

public GitHubApi()
private readonly HttpClient _client = new()
{
DefaultRequestHeaders =
{
_client = new HttpClient
{
DefaultRequestHeaders =
{
{ "User-Agent", "DuplicatiReleaseCrawler"}
}
};
{ "User-Agent", "DuplicatiReleaseCrawler"}
}
};

public async Task<Dictionary<string, (string version, Release data)>> GetDuplicatiReleases(CancellationToken ct)
{
using (var response = await _client.GetAsync(new Uri("https://api.github.com/repos/duplicati/duplicati/releases"), ct))
public async Task<Dictionary<string, (string version, Release data)>> GetDuplicatiReleases(CancellationToken ct)
{
var releases = await _client.GetFromJsonAsync<Release[]>(new Uri("https://api.github.com/repos/duplicati/duplicati/releases"), ct);

return (releases ?? [])
.Select(r => new
{
var raw = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();
return JsonConvert
.DeserializeObject<Release[]>(raw)
.Select(r => new
{
release = r,
version = _releaseVersion.Match(r.Version)
})
.Where(x => x.version.Success)
.GroupBy(x => x.version.Groups["channel"].Value)
.ToDictionary(
g => g.Key,
g =>
{
var last = g.OrderBy(x => x.release.PublicationDate).Last();
var version = last.version.Value;

return (version, last.release);
});
}
}
release = r,
version = _releaseVersion.Match(r.Version)
})
.Where(x => x.version.Success)
.GroupBy(x => x.version.Groups["channel"].Value)
.ToDictionary(
g => g.Key,
g =>
{
var last = g.OrderBy(x => x.release.PublicationDate).Last();
var version = last.version.Value;

/// <inheritdoc />
public void Dispose()
=> _client.Dispose();
return (version, last.release);
});
}

/// <inheritdoc />
public void Dispose()
=> _client.Dispose();
}
28 changes: 8 additions & 20 deletions Crawler/DuplicatiCrawler/Client/GitHub/Release.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace Crawler.Client.GitHub
{
public class Release
{
[JsonProperty("html_url")]
public string Url { get; set; }
namespace Crawler.Client.GitHub;

[JsonProperty("name")]
public string Version { get; set; }

[JsonProperty("body")]
public string Notes { get; set; }

public Asset[] Assets { get; set; }

[JsonProperty("published_at")]
public DateTimeOffset PublicationDate { get; set; }
}
}
internal sealed record Release(
[property: JsonPropertyName("html_url")] string Url,
[property: JsonPropertyName("name")] string Version,
[property: JsonPropertyName("body")] string Notes,
[property: JsonPropertyName("assets")] Asset[] Assets,
[property: JsonPropertyName("published_at")] DateTimeOffset PublicationDate);
Loading

0 comments on commit ace4ce1

Please sign in to comment.