me-web? 0.6.0: provider notes from shared checks, and the internet seen from eight places
- Notes on providers in any country: findings people choose to share are counted on the publisher's server, one vote per network. A total appears on the provider card only after a person has reviewed it, and only when at least five different networks of that provider agree four times in five; the card says how many agree. Notes researched by hand still come first, and on mobile data the totals for the mobile network replace the notes about home lines. - "Connected to the internet through" now comes from eight RouteViews collectors (Oregon, Ashburn, London, Sao Paulo, Johannesburg, Dubai, Singapore, Sydney) instead of one in Oregon, each counting the same, so networks far from the United States are described from nearby. A network that only exchanges traffic with a collector's neighbour is no longer listed as one of its upstreams. - Ready for measuring servers outside Europe: once the publisher adds one, the app times each server and runs the speed test and the test from outside against the closest. None exists yet, so nothing changes today. - When me-web? has no notes on a provider, it says that findings shared at the end of a check help write them. - The privacy page states the rule for publishing totals. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
This commit is contained in:
1 parent
c72a6be433
commit
d18caed157
139 files changed
+1403
-287
No files matched your search
@@ -0,0 +1,87 @@
|
||||
#: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)");
|
||||
}
|
||||
Reference in new issue
Block a user