diff --git a/deno.json b/deno.json index 7501c3f6..562aab51 100644 --- a/deno.json +++ b/deno.json @@ -23,6 +23,7 @@ "clean:deps": "deno cache --reload src/app.ts", "db:populate-search": "deno run -A --env-file --deny-read=.env scripts/db-populate-search.ts", "db:populate-extensions": "deno run -A --env-file --deny-read=.env scripts/db-populate-extensions.ts", + "db:streak:recompute": "deno run -A --env-file --deny-read=.env scripts/db-streak-recompute.ts", "vapid": "deno run scripts/vapid.ts" }, "unstable": [ diff --git a/scripts/db-streak-recompute.ts b/scripts/db-streak-recompute.ts new file mode 100644 index 00000000..262f0427 --- /dev/null +++ b/scripts/db-streak-recompute.ts @@ -0,0 +1,48 @@ +import { Storages } from '@/storages.ts'; + +const kysely = await Storages.kysely(); +const statsQuery = kysely.selectFrom('author_stats').select('pubkey'); + +for await (const { pubkey } of statsQuery.stream(10)) { + const eventsQuery = kysely + .selectFrom('nostr_events') + .select('created_at') + .where('pubkey', '=', pubkey) + .where('kind', 'in', [1, 20, 1111, 30023]) + .orderBy('nostr_events.created_at', 'desc') + .orderBy('nostr_events.id', 'asc'); + + let end: number | null = null; + let start: number | null = null; + + for await (const { created_at } of eventsQuery.stream(20)) { + const createdAt = Number(created_at); + + if (!end) { + const now = Math.floor(Date.now() / 1000); + + if (now - createdAt > 86400) { + break; // streak broken + } + + end = createdAt; + } + + if (start && (start - createdAt > 86400)) { + break; // streak broken + } + + start = createdAt; + } + + await kysely + .updateTable('author_stats') + .set({ + streak_end: end, + streak_start: start, + }) + .where('pubkey', '=', pubkey) + .execute(); +} + +Deno.exit(); diff --git a/src/utils/stats.ts b/src/utils/stats.ts index 341174c5..64e7986d 100644 --- a/src/utils/stats.ts +++ b/src/utils/stats.ts @@ -20,6 +20,7 @@ export async function updateStats({ event, kysely, store, x = 1 }: UpdateStatsOp case 1: case 20: case 1111: + case 30023: return handleEvent1(kysely, event, x); case 3: return handleEvent3(kysely, event, x, store);