Podcast episodes play; servers with NodeInfo2 only are described

Castopod announces an episode with a Note that only links to the episode's page, which serves a PodcastEpisode. PrivaPub
reads PodcastEpisode (its words in description, its sound in audio, its cover in image), and a Note that is only a link
to its author's own episode takes the episode's sound, title, cover and words, so the post plays. A server that
publishes no NodeInfo is described from NodeInfo2 (/.well-known/x-nodeinfo2), as Castopod publishes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-06 11:12:05 +02:00
1 parent 3df3c333bf
commit 69ab8e50eb
7 files changed
+163 -3

No files matched your search

@@ -72,6 +72,33 @@ namespace PrivaPub.Federation.Objects
Languages(metadata, "languages") ?? Languages(metadata, "langs"));
}
// NodeInfo2 (`/.well-known/x-nodeinfo2`), which Castopod publishes in place of NodeInfo: the server, its software
// and its usage in one document
public static NodeInfoFacts NodeInfo2(JsonElement root)
{
var server = Section(root, "server");
var usage = Section(root, "usage");
var users = Section(usage, "users");
if (Text(server, "software", 200) is not { } software)
return default;
return new NodeInfoFacts(
"nodeinfo2-" + (Text(root, "version", 20) ?? "1.0"),
software.ToLowerInvariant(),
Text(server, "version", 200),
Text(server, "name", 200),
default,
Strings(root, "protocols", 16, value => value.Length <= 40),
root.ValueKind == JsonValueKind.Object && root.TryGetProperty("openRegistrations", out var open) && open.ValueKind is JsonValueKind.True or JsonValueKind.False
? open.GetBoolean()
: (bool?)null,
Count(users, "total"),
Count(users, "activeMonth"),
Count(users, "activeHalfyear"),
Count(usage, "localPosts"),
Count(usage, "localComments"),
default);
}
public static InstanceApiFacts InstanceApi(JsonElement root)
{
var registrations = root.ValueKind == JsonValueKind.Object && root.TryGetProperty("registrations", out var r) ? r : default;