about summary refs log tree commit diff
path: root/MiniUtils/Utilities
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2025-05-13 08:17:26 +0200
committerRory& <root@rory.gay>2025-05-13 08:17:26 +0200
commitddb5a61b0fd234b436c0406ab57e38d67429c6b8 (patch)
treebd2bc4c20aab27135ebaa55e1f9193f22e7d73cc /MiniUtils/Utilities
downloadMiniUtils-ddb5a61b0fd234b436c0406ab57e38d67429c6b8.tar.xz
Initial commit
Diffstat (limited to 'MiniUtils/Utilities')
-rw-r--r--MiniUtils/Utilities/MscInfoProvider.cs91
1 files changed, 91 insertions, 0 deletions
diff --git a/MiniUtils/Utilities/MscInfoProvider.cs b/MiniUtils/Utilities/MscInfoProvider.cs
new file mode 100644

index 0000000..74788dc --- /dev/null +++ b/MiniUtils/Utilities/MscInfoProvider.cs
@@ -0,0 +1,91 @@ +using System.Globalization; +using System.Net.Http.Json; +using System.Text; +using System.Text.Json.Nodes; +using LibMatrix.Extensions; + +namespace MiniUtils.Utilities; + +public class MscInfoProvider(MiniUtilsConfiguration config) { + private static Dictionary<int, MscInfo> _mscCache = new(); + private static Dictionary<int, DateTime> _mscCacheExpiry = new(); + private static long RatelimitRemaining = 60; + private static DateTime RatelimitReset = DateTime.UtcNow; + public async Task<MscInfo?> GetMscInfo(int id) { + var hc = new MatrixHttpClient() { + DefaultRequestHeaders = { + { "User-Agent", "SynapseDataMiner" } + } + }; + + if(!string.IsNullOrWhiteSpace(config.GithubToken)) + hc.DefaultRequestHeaders.Add("Authorization", $"Bearer {config.GithubToken}"); + + var response = await hc.GetAsync($"https://api.github.com/repos/matrix-org/matrix-spec-proposals/pulls/{id}"); + if(response.Headers.Contains("X-RateLimit-Remaining")) { + RatelimitRemaining = long.Parse(response.Headers.GetValues("X-RateLimit-Remaining").First()); + } + + if (response.Headers.Contains("X-RateLimit-Reset")) { + var reset = long.Parse(response.Headers.GetValues("X-RateLimit-Reset").First()); + RatelimitReset = DateTimeOffset.FromUnixTimeSeconds(reset).UtcDateTime; + } + + if (!response.IsSuccessStatusCode) { + return _mscCache.GetValueOrDefault(id); + } + + var data = await response.Content.ReadFromJsonAsync<JsonObject>(); + var info = new MscInfo() { + Id = id, + Author = data?["user"]?["login"]?.ToString(), + Title = data?["title"]?.ToString(), + Url = data?["html_url"]?.ToString(), + State = data?["state"]?.ToString(), + Labels = data?["labels"]?.AsArray().Select(x => new MscInfo.LabelInfo() { + Name = x["name"]?.ToString(), + Color = x["color"]?.ToString() + }).ToList() ?? [] + }; + _mscCache[id] = info; + _mscCacheExpiry[id] = DateTime.UtcNow.AddMinutes(60); + return info; + } + + public class MscInfo { + public int Id { get; set; } + public string Title { get; set; } + public string State { get; set; } + public string Author { get; set; } + public string Url { get; set; } + public List<LabelInfo> Labels { get; set; } + + public class LabelInfo { + public string Name { get; set; } + public string Color { get; set; } + } + + public string ToHtml() { + var sb = new StringBuilder(); + sb.Append($"<a href=\"{Url}\">{Title}</a> by {Author} ({State})<br/>"); + + foreach (var label in Labels) { + sb.Append($"<font color=\"#{label.Color}\">" + + $"<span data-mx-bg-color=\"#{label.Color}\" data-mx-color=\"{GetContrastingForegroundColor(label.Color)}\">{label.Name}</span>" + + $"</font> \n"); + } + + return sb + "\n"; + } + + private static string GetContrastingForegroundColor(string backgroundColor) { + var color = backgroundColor.Replace("#", ""); + var r = int.Parse(color.Substring(0, 2), NumberStyles.HexNumber); + var g = int.Parse(color.Substring(2, 2), NumberStyles.HexNumber); + var b = int.Parse(color.Substring(4, 2), NumberStyles.HexNumber); + // var brightness = Math.Sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b); + var brightness = Math.Sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b); + return brightness < 130 ? "#ffffff" : "#000000"; + } + } +} \ No newline at end of file