Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: Publish Image

on:
push:
branches:
- main

env:
REGISTRY: ghcr.io
Expand All @@ -19,7 +17,17 @@ jobs:
- run: bun run tsc
- run: bun test

build-for-branches:
if: github.ref != 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: oven-sh/setup-bun@v1
- run: bun install --frozen-lockfile
- run: bun run build

build-and-push-image:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
5 changes: 1 addition & 4 deletions src/leet/daily-leet/row-utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { getTimeParts, slackTsToDate } from "../../utils/date-utils";
import { getTodaysLeets } from "../../db/queries";

export type LeetStatus = "leetos" | "leet" | "premature" | "late" | "garbage";

export function classifyRow(
row: Awaited<ReturnType<typeof getTodaysLeets>>[number],
): LeetStatus {
export function classifyRow<Row extends { ts: string }>(row: Row): LeetStatus {
const timeParts = getTimeParts(slackTsToDate(row.ts));

if (timeParts.hour !== 13) {
Expand Down
44 changes: 23 additions & 21 deletions src/leet/score-engine/score-day.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as R from "remeda";
import { LeetStatus, classifyRow } from "../daily-leet/row-utils";
import { UserLeetRow } from "../../db/types";
import { slackTsToMs, slackTsToSeconds } from "../../utils/date-utils";

import { ScoredDay, ScoredMessage } from "./index";
import { UserLeetDay } from "./score";

export function scoreDay(leetsForDay: UserLeetRow[]): ScoredDay {
export function scoreDay(leetsForDay: UserLeetDay[]): ScoredDay {
return R.pipe(
leetsForDay,
R.sortBy((row) => row.ts),
R.groupBy(classifyRow),
R.sortBy((row) => row.validLeet.ts),
R.groupBy((it) => classifyRow(it.validLeet)),
(it) =>
R.merge(
{
Expand All @@ -18,7 +18,7 @@ export function scoreDay(leetsForDay: UserLeetRow[]): ScoredDay {
leet: [],
late: [],
garbage: [],
} satisfies Record<LeetStatus, UserLeetRow[]>,
} satisfies Record<LeetStatus, UserLeetDay[]>,
it,
),
scoreLeetos,
Expand All @@ -29,70 +29,72 @@ export function scoreDay(leetsForDay: UserLeetRow[]): ScoredDay {
}

function scoreLeetos(
day: Record<LeetStatus, UserLeetRow[]>,
): Record<LeetStatus, (UserLeetRow | ScoredMessage)[]> {
day: Record<LeetStatus, UserLeetDay[]>,
): Record<LeetStatus, (UserLeetDay | ScoredMessage)[]> {
return {
...day,
leetos: day.leetos.map((leet): ScoredMessage => {
const ms = slackTsToMs(leet.ts);
const ms = slackTsToMs(leet.validLeet.ts);

const omegaLeet = ms === 0;
if (omegaLeet) {
return {
points: 13337,
message: leet,
message: leet.validLeet,
};
}

const firstBonus = leet.ts === day.leetos[0].ts ? 500 : 0;
const firstBonus =
leet.validLeet.ts === day.leetos[0].validLeet.ts ? 500 : 0;
const points = firstBonus + 1000 + (1000 - ms);

return {
points,
message: leet,
message: leet.validLeet,
};
}),
};
}

function scorePrematures(
day: Record<LeetStatus, UserLeetRow[]>,
): Record<LeetStatus, (UserLeetRow | ScoredMessage)[]> {
day: Record<LeetStatus, UserLeetDay[]>,
): Record<LeetStatus, (UserLeetDay | ScoredMessage)[]> {
return {
...day,
premature: day.premature.map((it): ScoredMessage => {
return {
points: -5000,
message: it,
message: it.validLeet,
};
}),
};
}

function scoreLeets(
day: Record<LeetStatus, UserLeetRow[]>,
): Record<LeetStatus, (UserLeetRow | ScoredMessage)[]> {
day: Record<LeetStatus, UserLeetDay[]>,
): Record<LeetStatus, (UserLeetDay | ScoredMessage)[]> {
return {
...day,
leet: day.leet.map((it): ScoredMessage => {
const firstBonus = day.leetos.length === 0 ? 500 : 0;
const within3SecondsPoints = slackTsToSeconds(it.ts) <= 3 ? 250 : 27;
const within3SecondsPoints =
slackTsToSeconds(it.validLeet.ts) <= 3 ? 250 : 27;

return {
points: firstBonus + within3SecondsPoints,
message: it,
message: it.validLeet,
};
}),
};
}

function zeroTheRest(
day: Record<LeetStatus, UserLeetRow[]>,
day: Record<LeetStatus, UserLeetDay[]>,
): Record<LeetStatus, ScoredMessage[]> {
const zeroMessage = (it: UserLeetRow): ScoredMessage => {
const zeroMessage = (it: UserLeetDay): ScoredMessage => {
return {
points: 0,
message: it,
message: it.validLeet,
};
};

Expand Down
24 changes: 23 additions & 1 deletion src/leet/score-engine/score.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe("score engine", () => {
});
});

describe.skip("score engine - multiple leets", () => {
describe("score engine - multiple leets", () => {
test("only the leetoo should count", async () => {
const [userA] = await scoreLeets([
createLeet("user", "1337", createLeetooDate(123)),
Expand Down Expand Up @@ -85,6 +85,24 @@ describe.skip("score engine - multiple leets", () => {

expect(userA.scoreSum).toBe(500 + 250);
});

test("garbage before should be discounted", async () => {
const [userA] = await scoreLeets([
createLeet("user", "1337", createGarbage(32)),
createLeet("user", "1337", createLeetDate(1.5)),
]);

expect(userA.scoreSum).toBe(750);
});

test("garbage after should be discounted", async () => {
const [userA] = await scoreLeets([
createLeet("user", "1337", createLeetDate(1.5)),
createLeet("user", "1337", createGarbage(39)),
]);

expect(userA.scoreSum).toBe(750);
});
});

function createLeet(user: string, text: string, ts: Date): UserLeetRow {
Expand All @@ -98,6 +116,10 @@ function createLeet(user: string, text: string, ts: Date): UserLeetRow {
} as UserLeetRow;
}

function createGarbage(minutes: number): Date {
return new Date(2023, 5, 6, 13 - 2, minutes, 15, 169);
}

function createPrematureDate(ms: number): Date {
return new Date(2023, 5, 6, 13 - 2, 36, 59, 1000 - ms);
}
Expand Down
21 changes: 21 additions & 0 deletions src/leet/score-engine/score.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export async function scoreLeets(leets: UserLeetRow[]): Promise<ScoredUser[]> {
return R.pipe(
leets,
R.groupBy((row) => slackTsToDay(row.ts)),
R.mapValues(dayGroupToUserDay),
R.mapValues(scoreDay),
R.values,
R.flatMap(R.values),
Expand All @@ -35,6 +36,26 @@ export async function scoreLeets(leets: UserLeetRow[]): Promise<ScoredUser[]> {
);
}

export type UserLeetDay = {
user: string;
validLeet: UserLeetRow;
otherLeets: UserLeetRow[];
};

const dayGroupToUserDay = (leetsForDay: UserLeetRow[]): UserLeetDay[] => {
const users = R.groupBy(leetsForDay, (it) => it.message.user);

return R.values(users).map((it) => {
// TODO: actually deduce the valid leet instead of taking the first one

return {
user: it[0].message.user,
validLeet: it[0],
otherLeets: it.slice(1),
};
});
};

const toTotalUserScore = (it: ScoredMessageSmol[]): ScoredUser => ({
user: it[0].user,
scoreSum: R.sumBy(it, (it) => it.score),
Expand Down