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 _mscCache = new(); private static Dictionary _mscCacheExpiry = new(); private static long RatelimitRemaining = 60; private static DateTime RatelimitReset = DateTime.UtcNow; public async Task 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(); 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 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($"{Title} by {Author} ({State})
"); foreach (var label in Labels) { sb.Append($"" + $"{label.Name}" + $" \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"; } } }