Pins across servers, both ways
An account elsewhere that pins or unpins one of its posts (Add or Remove on its `featured`) now shows those pins on its profile here (`pinned=true`), in its order and its public posts only; a community's announce of a moderator's Add does the same for the community. The `featured` collection itself is read with the account's counts, at most once a day, so pins made before PrivaPub ever saw an account show too. Any other target (Smithereen's wall, a community's moderators) is dropped. A persona's pin and unpin go to the post's audience as Add and Remove on /trophies, as Mastodon sends them. Checked live against Mastodon (scenarios/pins.sh, 8 checks). The town's checker learnt three peer rules from the village: Misskey and Sharkey keep a forwarded reply only with its author's LD signature (only Mastodon signs), they count no renote by a bot, and Mastodon never sees a Lemmy vote on a post in a community. The village of 2026-10-05 checks clean, 2454 of 2454. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
5f150b7a59
commit
1c7d1ece9c
23 files changed
+510
-19
No files matched your search
@@ -37,10 +37,17 @@ NEEDS_PICTURE = {"pixelfed"}
|
||||
# others there (nobody relays a followers-only reply), nor anything under it
|
||||
THREAD_BOUND = {"friendica"}
|
||||
# Mastodon takes an activity another server passes on only with its author's LD signature (or a FEP-8b32 proof) and
|
||||
# drops it otherwise (ActivityPub::ProcessActivityService); of the platforms here only Mastodon and Misskey and its forks
|
||||
# sign their Creates that way, so another's reply PrivaPub passes on never lands there
|
||||
NEEDS_LD_SIGNATURE = {"mastodon"}
|
||||
LD_SIGNS = {"mastodon", "misskey", "sharkey"}
|
||||
# drops it otherwise (ActivityPub::ProcessActivityService); Misskey and Sharkey skip it the same way ("http-signature
|
||||
# verification failed and no LD-Signature"). Of the platforms here only Mastodon signs its Creates that way: Misskey
|
||||
# 2026.10's carry no signature (seen in the village of 2026-10-05), so another's reply PrivaPub passes on lands there
|
||||
# only when Mastodon wrote it
|
||||
NEEDS_LD_SIGNATURE = {"mastodon", "misskey", "sharkey"}
|
||||
LD_SIGNS = {"mastodon"}
|
||||
# Misskey and Sharkey count no renote by a bot (NoteCreateService: `!user.isBot` before incRenoteCount)
|
||||
BOT_RENOTES_UNCOUNTED = {"misskey", "sharkey"}
|
||||
# a Lemmy account's vote goes to the community alone, which announces it; Mastodon takes no Announce of a Like, so a
|
||||
# Lemmy vote on a Mastodon post in a community never counts there
|
||||
GROUP_VOTES_UNSEEN = {"mastodon"}
|
||||
|
||||
|
||||
class World:
|
||||
@@ -256,6 +263,7 @@ class Sweep:
|
||||
# -- counts on the object's own server, and PrivaPub's exact counts
|
||||
def counts(self, stored):
|
||||
likes, reacts, boosts, votes = defaultdict(int), defaultdict(lambda: defaultdict(int)), defaultdict(int), defaultdict(lambda: defaultdict(int))
|
||||
bot_boosts = defaultdict(int)
|
||||
for f in self.w.interactions:
|
||||
ref = f["ref"]
|
||||
if f["verb"] == "like":
|
||||
@@ -269,6 +277,8 @@ class Sweep:
|
||||
reacts[ref]["❤️" if f["emoji"] in HEARTS else f["emoji"]] += 1
|
||||
elif f["verb"] == "boost":
|
||||
boosts[ref] += 1
|
||||
if self.w.planner.accounts[f["actor"]]["bot"]:
|
||||
bot_boosts[ref] += 1
|
||||
elif f["verb"] == "vote":
|
||||
for c in f["choices"]:
|
||||
votes[ref][c] += 1
|
||||
@@ -293,12 +303,14 @@ class Sweep:
|
||||
self.add(f"count.vote.{v}", "privapub", "privapub", row.votes == want, ref, want, row.votes)
|
||||
elif origin != "lemmy":
|
||||
# elsewhere: at least the plain likes that every platform sends as Like
|
||||
plain = sum(1 for f in self.w.interactions if f["ref"] == ref and f["verb"] == "like")
|
||||
plain = sum(1 for f in self.w.interactions if f["ref"] == ref and f["verb"] == "like"
|
||||
and not (origin in GROUP_VOTES_UNSEEN and o.get("group") and self.w.platform(f["actor"]) == "lemmy"))
|
||||
if plain:
|
||||
total = (row.likes or 0)
|
||||
self.add(f"count.like.{v}", "*", origin, total >= plain, ref, f">={plain}", total)
|
||||
if boosts[ref]:
|
||||
self.add(f"count.boost.{v}", "*", origin, (row.boosts or 0) >= boosts[ref], ref, f">={boosts[ref]}", row.boosts)
|
||||
counted = boosts[ref] - (bot_boosts[ref] if origin in BOT_RENOTES_UNCOUNTED else 0)
|
||||
if counted:
|
||||
self.add(f"count.boost.{v}", "*", origin, (row.boosts or 0) >= counted, ref, f">={counted}", row.boosts)
|
||||
if votes[ref]:
|
||||
want = sum(votes[ref].values())
|
||||
got = sum(row.votes or [])
|
||||
|
||||
Reference in new issue
Block a user