From b5545ddb601fc3fc17f24aa4a7f24e945b8f750a Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sun, 2 Jun 2024 16:07:25 -0500 Subject: [PATCH] getTrendingNotes -> getTrendingEvents --- src/cron.ts | 14 ++++++++--- src/trends/trending-events.ts | 47 +++++++++++++++++++++++++++++++++++ src/trends/trending-notes.ts | 37 --------------------------- 3 files changed, 58 insertions(+), 40 deletions(-) create mode 100644 src/trends/trending-events.ts delete mode 100644 src/trends/trending-notes.ts diff --git a/src/cron.ts b/src/cron.ts index 7f8f46a..53714e8 100644 --- a/src/cron.ts +++ b/src/cron.ts @@ -1,7 +1,7 @@ import { Stickynotes } from '@soapbox/stickynotes'; import { DittoDB } from '@/db/DittoDB.ts'; -import { getTrendingNotes } from '@/trends/trending-notes.ts'; +import { getTrendingEvents } from '@/trends/trending-events.ts'; import { Time } from '@/utils/time.ts'; import { AdminSigner } from '@/signers/AdminSigner.ts'; import { handleEvent } from '@/pipeline.ts'; @@ -12,10 +12,18 @@ const console = new Stickynotes('ditto:trends'); async function updateTrendingNotesCache() { console.info('Updating trending notes cache...'); const kysely = await DittoDB.getInstance(); - const yesterday = Math.floor((Date.now() - Time.days(1)) / 1000); const signal = AbortSignal.timeout(1000); - const events = await getTrendingNotes(kysely, yesterday, 20); + const yesterday = Math.floor((Date.now() - Time.days(1)) / 1000); + const now = Math.floor(Date.now() / 1000); + + const events = await getTrendingEvents(kysely, { + kinds: [1], + since: yesterday, + until: now, + limit: 20, + }); + const signer = new AdminSigner(); const label = await signer.signEvent({ diff --git a/src/trends/trending-events.ts b/src/trends/trending-events.ts new file mode 100644 index 0000000..3f0e8ef --- /dev/null +++ b/src/trends/trending-events.ts @@ -0,0 +1,47 @@ +import { NostrEvent, NostrFilter } from '@nostrify/nostrify'; +import { Kysely, sql } from 'kysely'; + +import { DittoTables } from '@/db/DittoTables.ts'; + +/** + * Make a direct query to the database to get trending events within the specified timeframe. + * Trending events are determined by the number of reposts, replies, and reactions. + * + * This query makes use of cached stats (in the `event_stats` table). + * The query is SLOW so it needs to be run on a schedule and cached. + */ +export async function getTrendingEvents( + /** Kysely instance to execute queries on. */ + kysely: Kysely, + /** Filter of eligible events. */ + filter: NostrFilter, +): Promise { + let query = kysely + .selectFrom('nostr_events') + .selectAll('nostr_events') + .innerJoin('event_stats', 'event_stats.event_id', 'nostr_events.id') + .orderBy( + sql`(event_stats.reposts_count * 2) + (event_stats.replies_count) + (event_stats.reactions_count)`, + 'desc', + ); + + if (filter.kinds) { + query = query.where('nostr_events.kind', 'in', filter.kinds); + } + if (typeof filter.since === 'number') { + query = query.where('nostr_events.created_at', '>=', filter.since); + } + if (typeof filter.until === 'number') { + query = query.where('nostr_events.created_at', '<=', filter.until); + } + if (typeof filter.limit === 'number') { + query = query.limit(filter.limit); + } + + const rows = await query.execute(); + + return rows.map((row) => ({ + ...row, + tags: JSON.parse(row.tags), + })); +} diff --git a/src/trends/trending-notes.ts b/src/trends/trending-notes.ts deleted file mode 100644 index a469aa9..0000000 --- a/src/trends/trending-notes.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { NostrEvent } from '@nostrify/nostrify'; -import { Kysely, sql } from 'kysely'; - -import { DittoTables } from '@/db/DittoTables.ts'; - -/** - * Make a direct query to the database to get trending kind 1 notes within the specified timeframe. - * - * This query makes use of cached stats (in the `event_stats` table). - * The query is SLOW so it needs to be run on a schedule and cached. - */ -export async function getTrendingNotes( - /** Kysely instance to execute queries on. */ - kysely: Kysely, - /** Unix timestamp in _seconds_ for the starting point of this query. */ - since: number, - /** Maximum number of trending notes to return. */ - limit: number, -): Promise { - const rows = await kysely - .selectFrom('nostr_events') - .selectAll('nostr_events') - .innerJoin('event_stats', 'event_stats.event_id', 'nostr_events.id') - .where('nostr_events.kind', '=', 1) - .where('nostr_events.created_at', '>', since) - .orderBy( - sql`(event_stats.reposts_count * 2) + (event_stats.replies_count) + (event_stats.reactions_count)`, - 'desc', - ) - .limit(limit) - .execute(); - - return rows.map((row) => ({ - ...row, - tags: JSON.parse(row.tags), - })); -}