//! bufo of the month — ported from the retired rust backend.
//!
//! GET /api/bufo-of-the-month → json; GET /bufo-of-the-month → html page.
//! the winner comes from the bot's public stats: last month's top match from
//! monthly.json, else a deterministic rotation over the cumulative top-24,
//! with published winners pinned so history never rewrites itself.
const std = @import("std");
const http = std.http;
const json = std.json;
const mem = std.mem;
const Allocator = mem.Allocator;
const Io = std.Io;
const ROTATION_POOL_SIZE: usize = 24;
const Pinned = struct { month: []const u8, name: []const u8 };
const PINNED_MONTHLY_BUFOS = [_]Pinned{.{ .month = "2026-06", .name = "bufo-on-the-ceiling" }};
pub const BotBufo = struct {
name: []const u8,
url: []const u8,
matches: u64,
rank: usize,
};
pub const Winner = struct {
month: []const u8,
name: []const u8,
url: []const u8,
bot_matches: u64,
bot_rank: usize,
basis_month: ?[]const u8,
source: []const u8,
};
const YearMonth = struct { year: i32, month: u32 };
const PreviousWinner = struct { bufo: BotBufo, basis_month: []const u8 };
pub fn currentMonth(io: Io) YearMonth {
const secs: i64 = @intCast(@divFloor(Io.Timestamp.now(io, .real).nanoseconds, std.time.ns_per_s));
return civilFromDays(@divFloor(secs, 86_400));
}
fn civilFromDays(days_since_epoch: i64) YearMonth {
const z = days_since_epoch + 719_468;
const era = @divFloor(if (z >= 0) z else z - 146_096, 146_097);
const doe = z - era * 146_097;
const yoe = @divFloor(doe - @divFloor(doe, 1460) + @divFloor(doe, 36_524) - @divFloor(doe, 146_096), 365);
const y = yoe + era * 400;
const doy = doe - (365 * yoe + @divFloor(yoe, 4) - @divFloor(yoe, 100));
const mp = @divFloor(5 * doy + 2, 153);
const month: i64 = mp + (if (mp < 10) @as(i64, 3) else @as(i64, -9));
const year = y + (if (month <= 2) @as(i64, 1) else @as(i64, 0));
return .{ .year = @intCast(year), .month = @intCast(month) };
}
const month_names = [_][]const u8{
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December",
};
fn monthName(alloc: Allocator, ym: YearMonth) ![]const u8 {
const name = if (ym.month >= 1 and ym.month <= 12) month_names[ym.month - 1] else "Unknown";
return std.fmt.allocPrint(alloc, "{s} {d}", .{ name, ym.year });
}
fn monthKey(alloc: Allocator, ym: YearMonth) ![]const u8 {
return std.fmt.allocPrint(alloc, "{d:0>4}-{d:0>2}", .{ @as(u32, @intCast(ym.year)), ym.month });
}
pub fn previousMonth(ym: YearMonth) YearMonth {
return if (ym.month == 1) .{ .year = ym.year - 1, .month = 12 } else .{ .year = ym.year, .month = ym.month - 1 };
}
/// parse the bot stats page: each card is
/// `
\s*

') orelse break;
const tag = html[card..tag_end];
const title_start = (mem.indexOf(u8, tag, "title=\"") orelse continue) + "title=\"".len;
const title_end = mem.indexOfScalarPos(u8, tag, title_start, '"') orelse continue;
const title = tag[title_start..title_end];
const paren = mem.lastIndexOf(u8, title, " (") orelse continue;
if (!mem.endsWith(u8, title, " matches)")) continue;
const name = title[0..paren];
const count_str = title[paren + 2 .. title.len - " matches)".len];
const matches = std.fmt.parseInt(u64, count_str, 10) catch continue;
const img = mem.indexOfPos(u8, html, tag_end, "
)
next) continue;
}
try out.append(alloc, .{
.name = name,
.url = html[url_start..url_end],
.matches = matches,
.rank = out.items.len + 1,
});
}
return out.items;
}
fn byName(_: void, a: BotBufo, b: BotBufo) bool {
return mem.lessThan(u8, a.name, b.name);
}
pub fn pickMonthlyBufo(alloc: Allocator, bufos: []const BotBufo, ym: YearMonth) !?BotBufo {
const key = try monthKey(alloc, ym);
for (PINNED_MONTHLY_BUFOS) |pin| {
if (mem.eql(u8, pin.month, key)) {
for (bufos) |b| if (mem.eql(u8, b.name, pin.name)) return b;
}
}
const pool_len = @min(bufos.len, ROTATION_POOL_SIZE);
if (pool_len == 0) return null;
const pool = try alloc.dupe(BotBufo, bufos[0..pool_len]);
mem.sort(BotBufo, pool, {}, byName);
const basis = previousMonth(ym);
const month_index: i64 = @as(i64, basis.year) * 12 + (@as(i64, basis.month) - 1);
const idx: usize = @intCast(@mod(month_index, @as(i64, @intCast(pool_len))));
return pool[idx];
}
fn byMatchesDesc(_: void, a: BotBufo, b: BotBufo) bool {
if (a.matches != b.matches) return a.matches > b.matches;
return mem.lessThan(u8, a.name, b.name);
}
/// monthly.json: {"monthly_bufo_matches": {"YYYY-MM\tname": {"count": N, "url": "..."}}}
pub fn pickPreviousMonthWinner(alloc: Allocator, monthly: json.ObjectMap, ym: YearMonth) !?PreviousWinner {
const basis = previousMonth(ym);
const basis_key = try monthKey(alloc, basis);
var candidates: std.ArrayList(BotBufo) = .empty;
var it = monthly.iterator();
while (it.next()) |entry| {
const key = entry.key_ptr.*;
const tab = mem.indexOfScalar(u8, key, '\t') orelse continue;
if (!mem.eql(u8, key[0..tab], basis_key)) continue;
if (entry.value_ptr.* != .object) continue;
const stats = entry.value_ptr.object;
const count = switch (stats.get("count") orelse continue) {
.integer => |n| @as(u64, @intCast(@max(n, 0))),
else => continue,
};
const url = switch (stats.get("url") orelse continue) {
.string => |s| s,
else => continue,
};
try candidates.append(alloc, .{ .name = key[tab + 1 ..], .url = url, .matches = count, .rank = 0 });
}
if (candidates.items.len == 0) return null;
mem.sort(BotBufo, candidates.items, {}, byMatchesDesc);
var winner = candidates.items[0];
winner.rank = 1;
return .{ .bufo = winner, .basis_month = try monthName(alloc, basis) };
}
pub const Source = struct {
io: Io,
http: *http.Client,
bot_stats_url: []const u8,
public_url: []const u8,
fn get(self: Source, alloc: Allocator, url: []const u8) ![]const u8 {
var body: Io.Writer.Allocating = .init(alloc);
const res = self.http.fetch(.{ .location = .{ .url = url }, .method = .GET, .response_writer = &body.writer }) catch
return error.Upstream;
if (res.status != .ok) return error.Upstream;
return body.written();
}
pub fn winner(self: Source, alloc: Allocator) !Winner {
const stats_url = mem.trimEnd(u8, self.bot_stats_url, "/");
const html = try self.get(alloc, stats_url);
const bufos = try parseBotStats(alloc, html);
const ym = currentMonth(self.io);
const current_key = try monthKey(alloc, ym);
var pinned = false;
for (PINNED_MONTHLY_BUFOS) |pin| if (mem.eql(u8, pin.month, current_key)) {
pinned = true;
};
var chosen: BotBufo = undefined;
var basis_month: ?[]const u8 = null;
var source: []const u8 = undefined;
if (pinned) {
chosen = (try pickMonthlyBufo(alloc, bufos, ym)) orelse return error.NotFound;
source = "published monthly winner";
} else if (try self.previousMonthWinner(alloc, stats_url, ym)) |prev| {
chosen = prev.bufo;
basis_month = prev.basis_month;
source = "previous month bot match stats";
} else {
chosen = (try pickMonthlyBufo(alloc, bufos, ym)) orelse return error.NotFound;
source = "deterministic cumulative bot match stats fallback";
}
return .{
.month = try monthName(alloc, ym),
.name = chosen.name,
.url = chosen.url,
.bot_matches = chosen.matches,
.bot_rank = chosen.rank,
.basis_month = basis_month,
.source = source,
};
}
fn previousMonthWinner(self: Source, alloc: Allocator, stats_url: []const u8, ym: YearMonth) !?PreviousWinner {
const url = try std.fmt.allocPrint(alloc, "{s}/monthly.json", .{stats_url});
const body = self.get(alloc, url) catch return null;
const parsed = json.parseFromSliceLeaky(json.Value, alloc, body, .{}) catch return null;
if (parsed != .object) return null;
const monthly = parsed.object.get("monthly_bufo_matches") orelse return null;
if (monthly != .object) return null;
return try pickPreviousMonthWinner(alloc, monthly.object, ym);
}
pub fn writeJson(self: Source, alloc: Allocator, w: Winner) ![]const u8 {
return json.Stringify.valueAlloc(alloc, .{
.month = w.month,
.name = w.name,
.url = w.url,
.bot_matches = w.bot_matches,
.bot_rank = w.bot_rank,
.bot_stats_url = self.bot_stats_url,
.basis_month = w.basis_month,
.source = w.source,
}, .{});
}
pub fn writePage(self: Source, alloc: Allocator, w: Winner) ![]const u8 {
const public_url = mem.trimEnd(u8, self.public_url, "/");
const page_url = try std.fmt.allocPrint(alloc, "{s}/bufo-of-the-month", .{public_url});
const title = try std.fmt.allocPrint(alloc, "{s} Bufo of the Month: {s}", .{ w.month, w.name });
const stats_phrase = if (w.basis_month) |bm|
try std.fmt.allocPrint(alloc, "{d} {s} bot matches and rank #{d} for that month", .{ w.bot_matches, bm, w.bot_rank })
else
try std.fmt.allocPrint(alloc, "{d} bot matches and current public rank #{d}", .{ w.bot_matches, w.bot_rank });
const description = try std.fmt.allocPrint(alloc, "{s} is the {s} Bufo of the Month with {s}.", .{ w.name, w.month, stats_phrase });
const e = struct {
fn f(a: Allocator, s: []const u8) ![]const u8 {
return escapeHtml(a, s);
}
}.f;
return std.fmt.allocPrint(alloc, page_template, .{
.title = try e(alloc, title),
.page_url = try e(alloc, page_url),
.description = try e(alloc, description),
.image = try e(alloc, w.url),
.alt = try e(alloc, w.name),
.name = try e(alloc, w.name),
.month = try e(alloc, w.month),
.stats_phrase = try e(alloc, stats_phrase),
.stats_url = try e(alloc, self.bot_stats_url),
});
}
};
pub fn escapeHtml(alloc: Allocator, s: []const u8) ![]const u8 {
var out: std.ArrayList(u8) = .empty;
for (s) |c| switch (c) {
'&' => try out.appendSlice(alloc, "&"),
'<' => try out.appendSlice(alloc, "<"),
'>' => try out.appendSlice(alloc, ">"),
'"' => try out.appendSlice(alloc, """),
else => try out.append(alloc, c),
};
return out.items;
}
const page_template =
\\
\\
\\
\\
\\
\\
{[title]s}
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\
\\ {[title]s}
\\
\\
![{[alt]s}]({[image]s})
\\
\\ {[name]s} is the {[month]s} Bufo of the Month with {[stats_phrase]s} in the public bot stats.
\\ find more bufos
\\
\\
\\
;
// --- tests: the rust suite, ported ---
const t = std.testing;
fn bufo(name: []const u8, matches: u64, rank: usize) BotBufo {
return .{ .name = name, .url = "https://all-the.bufo.zone/x.png", .matches = matches, .rank = rank };
}
test "pins published june 2026 winner" {
var arena = std.heap.ArenaAllocator.init(t.allocator);
defer arena.deinit();
const bufos = [_]BotBufo{ bufo("bufo-take-my-money", 1874, 6), bufo("bufo-on-the-ceiling", 1866, 7) };
const w = (try pickMonthlyBufo(arena.allocator(), &bufos, .{ .year = 2026, .month = 6 })).?;
try t.expectEqualStrings("bufo-on-the-ceiling", w.name);
try t.expectEqual(@as(usize, 7), w.rank);
}
test "stable pool does not depend on live rank order" {
var arena = std.heap.ArenaAllocator.init(t.allocator);
defer arena.deinit();
const ranked = [_]BotBufo{ bufo("bufo-z", 30, 1), bufo("bufo-a", 20, 2), bufo("bufo-m", 10, 3) };
const reranked = [_]BotBufo{ bufo("bufo-a", 21, 1), bufo("bufo-m", 19, 2), bufo("bufo-z", 18, 3) };
const ym: YearMonth = .{ .year = 2026, .month = 7 };
const first = (try pickMonthlyBufo(arena.allocator(), &ranked, ym)).?;
const second = (try pickMonthlyBufo(arena.allocator(), &reranked, ym)).?;
try t.expectEqualStrings(first.name, second.name);
}
test "january uses previous december as basis" {
try t.expectEqual(YearMonth{ .year = 2026, .month = 12 }, previousMonth(.{ .year = 2027, .month = 1 }));
try t.expectEqual(YearMonth{ .year = 2027, .month = 1 }, previousMonth(.{ .year = 2027, .month = 2 }));
}
test "civil date from epoch days" {
try t.expectEqual(YearMonth{ .year = 1970, .month = 1 }, civilFromDays(0));
try t.expectEqual(YearMonth{ .year = 2026, .month = 8 }, civilFromDays(20693)); // 2026-08-28
try t.expectEqual(YearMonth{ .year = 2000, .month = 3 }, civilFromDays(11017)); // 2000-03-01
}
test "picks previous month winner from monthly stats" {
var arena = std.heap.ArenaAllocator.init(t.allocator);
defer arena.deinit();
const a = arena.allocator();
const parsed = try json.parseFromSliceLeaky(json.Value, a,
\\{"2026-06\tbufo-second":{"count":4,"url":"u2"},"2026-06\tbufo-first":{"count":8,"url":"u1"},"2026-07\tbufo-too-new":{"count":99,"url":"u3"}}
, .{});
const r = (try pickPreviousMonthWinner(a, parsed.object, .{ .year = 2026, .month = 7 })).?;
try t.expectEqualStrings("bufo-first", r.bufo.name);
try t.expectEqual(@as(u64, 8), r.bufo.matches);
try t.expectEqual(@as(usize, 1), r.bufo.rank);
try t.expectEqualStrings("June 2026", r.basis_month);
}
test "parses bot stats cards" {
var arena = std.heap.ArenaAllocator.init(t.allocator);
defer arena.deinit();
const html =
\\
\\

\\
;
const bufos = try parseBotStats(arena.allocator(), html);
try t.expectEqual(@as(usize, 2), bufos.len);
try t.expectEqualStrings("bufo-a", bufos[0].name);
try t.expectEqual(@as(u64, 12), bufos[0].matches);
try t.expectEqualStrings("https://all-the.bufo.zone/bufo-a.png", bufos[0].url);
try t.expectEqual(@as(usize, 2), bufos[1].rank);
}
test "escapes html" {
var arena = std.heap.ArenaAllocator.init(t.allocator);
defer arena.deinit();
try t.expectEqualStrings("a&b<c>"", try escapeHtml(arena.allocator(), "a&b
\""));
}