Files

87 lines
3.4 KiB
C#
Raw Permalink Normal View History

#:project ../src/MeWeb.Core/MeWeb.Core.csproj
using System.Text.Json;
using System.Text.Json.Serialization;
using MeWeb.Core.Knowledge;
var json = new KnowledgeJsonContext(new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
});
var root = FindRoot();
var reviewed = Path.Combine(root, "data", "observed.json");
if (args.Length < 2 || args[0] is not ("show" or "accept"))
{
Console.Error.WriteLine("""
usage: dotnet run tools/observed.cs -- show <candidates.json>
dotnet run tools/observed.cs -- accept <candidates.json> AS<number>/<home|mobile> ...
<candidates.json> is the server's count of shared findings (/var/lib/meweb/observed.json on the box).
show prints every provider line and which notes are ready (at least 5 networks, 4 in 5 agreeing);
accept copies the ready notes of the named lines into data/observed.json, which every release embeds.
""");
return 2;
}
var candidates = Load(args[1]);
if (args[0] == "show")
{
foreach (var line in candidates)
{
Console.WriteLine($"{line.Key,-16} {line.Name} - {line.Networks} network(s), {line.From} to {line.To}");
foreach (var (label, fact) in new[] { ("ipv4", line.Ipv4), ("ipv6", line.Ipv6), ("port25", line.Port25) })
if (fact is not null) Console.WriteLine($" {label,-7} {fact.Value,-8} {fact.Agree} of {fact.Of}{(fact.Ready ? " ready" : "")}");
}
Console.WriteLine($"{candidates.Count} provider line(s), {candidates.Count(c => Ready(c) is not null)} with a ready note");
return 0;
}
var wanted = args.Skip(2).ToHashSet(StringComparer.OrdinalIgnoreCase);
var current = File.Exists(reviewed) ? Load(reviewed) : [];
foreach (var key in wanted)
{
var line = candidates.FirstOrDefault(c => string.Equals(c.Key, key, StringComparison.OrdinalIgnoreCase));
var ready = line is null ? null : Ready(line);
if (ready is null)
{
Console.Error.WriteLine($"{key}: no ready note in {args[1]}");
return 1;
}
current.RemoveAll(c => c.Key == ready.Key);
current.Add(ready);
Console.WriteLine($"{ready.Key}: accepted ({string.Join(", ", new[] { ready.Ipv4, ready.Ipv6, ready.Port25 }.Where(f => f is not null).Select(f => $"{f.Value} {f.Agree}/{f.Of}"))})");
}
File.WriteAllText(reviewed, JsonSerializer.Serialize(current.OrderBy(c => c.Asn).ThenBy(c => c.Line, StringComparer.Ordinal).ToList(), json.ListObservedNetwork) + "\n");
return 0;
List<ObservedNetwork> Load(string path)
{
using var stream = File.OpenRead(path);
return JsonSerializer.Deserialize(stream, json.ListObservedNetwork) ?? [];
}
static ObservedNetwork Ready(ObservedNetwork line)
{
var copy = new ObservedNetwork
{
Asn = line.Asn,
Line = line.Line,
Name = line.Name,
Networks = line.Networks,
From = line.From,
To = line.To,
Ipv4 = line.Ipv4 is { Ready: true } ? line.Ipv4 : null,
Ipv6 = line.Ipv6 is { Ready: true } ? line.Ipv6 : null,
Port25 = line.Port25 is { Ready: true } ? line.Port25 : null,
};
return copy.Ipv4 is null && copy.Ipv6 is null && copy.Port25 is null ? null : copy;
}
static string FindRoot()
{
var dir = new DirectoryInfo(Directory.GetCurrentDirectory());
while (dir is not null && !File.Exists(Path.Combine(dir.FullName, "MeWeb.slnx"))) dir = dir.Parent;
return dir?.FullName ?? throw new InvalidOperationException("run from inside the repository (MeWeb.slnx not found)");
}