bsky feeds about music music-atmosphere-feed.plyr.fm/
bsky feed zig
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

exclude bots from dashboard top posters list

Uses the same BOT_THRESHOLD/24h detection as the organic feed filter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+23 -5
+22 -4
src/server/dashboard.zig
··· 2 2 const Io = std.Io; 3 3 const stats = @import("stats.zig"); 4 4 const posts = @import("../store/posts.zig"); 5 + const http = @import("http.zig"); 5 6 6 7 var io: Io = undefined; 7 8 ··· 290 291 \\<div class="subsection">top posters</div> 291 292 ); 292 293 293 - // get top 5 posters 294 - const top = s.getTopPosters(5); 294 + // get top posters, excluding bots 295 + const bot_threshold = http.getBotThreshold(); 296 + const exclude_dids = posts.getHighVolumePosters(alloc, bot_threshold, 24) catch null; 297 + defer if (exclude_dids) |e| posts.freeDidList(alloc, e); 298 + const top = s.getTopPosters(20); 295 299 const unique_count = s.getUniquePosterCount(); 296 300 const concentration = s.getTopConcentration(5); 297 301 const posters_since = s.getPostersSince(); ··· 326 330 }); 327 331 } 328 332 329 - // find max count for relative sizing 333 + // find max count for relative sizing (skip bots) 330 334 var max_count: u32 = 1; 331 335 for (top) |entry| { 336 + if (entry.count == 0) continue; 337 + if (isExcluded(entry.getDid(), exclude_dids)) continue; 332 338 if (entry.count > max_count) max_count = entry.count; 333 339 } 334 340 ··· 336 342 \\<div class="poster-cards"> 337 343 ); 338 344 339 - // render avatar cards with relative sizing 345 + // render avatar cards with relative sizing, skip bots, cap at 5 346 + var shown: usize = 0; 340 347 for (top) |entry| { 341 348 if (entry.count == 0) continue; 342 349 const did = entry.getDid(); 350 + if (isExcluded(did, exclude_dids)) continue; 351 + if (shown >= 5) break; 352 + shown += 1; 343 353 // size: 20-36px based on relative post count 344 354 const ratio: f64 = @as(f64, @floatFromInt(entry.count)) / @as(f64, @floatFromInt(max_count)); 345 355 const size: u32 = 20 + @as(u32, @intFromFloat(ratio * 16)); ··· 441 451 442 452 return buf.toOwnedSlice(alloc); 443 453 } 454 + 455 + fn isExcluded(did: []const u8, exclude_dids: ?[][]const u8) bool { 456 + const dids = exclude_dids orelse return false; 457 + for (dids) |excluded| { 458 + if (std.mem.eql(u8, did, excluded)) return true; 459 + } 460 + return false; 461 + }
+1 -1
src/server/http.zig
··· 261 261 try sendJson(request, .ok, result); 262 262 } 263 263 264 - fn getBotThreshold() usize { 264 + pub fn getBotThreshold() usize { 265 265 const val = if (std.c.getenv("BOT_THRESHOLD")) |p| std.mem.span(p) else return 100; 266 266 return std.fmt.parseInt(usize, val, 10) catch 100; 267 267 }