From c7c75a714757ac6b15e9167ab337ea06b996795f Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sun, 2 Jun 2024 19:40:42 -0500 Subject: [PATCH] Get rid if trending-events.ts, do everything with tag values (brave) --- src/cron.ts | 50 +++++-------------------------- src/trends/trending-events.ts | 47 ----------------------------- src/trends/trending-tag-values.ts | 4 +-- 3 files changed, 10 insertions(+), 91 deletions(-) delete mode 100644 src/trends/trending-events.ts diff --git a/src/cron.ts b/src/cron.ts index 0313e7d1..f450e8de 100644 --- a/src/cron.ts +++ b/src/cron.ts @@ -4,49 +4,12 @@ import { Conf } from '@/config.ts'; import { DittoDB } from '@/db/DittoDB.ts'; import { handleEvent } from '@/pipeline.ts'; import { AdminSigner } from '@/signers/AdminSigner.ts'; -import { getTrendingEvents } from '@/trends/trending-events.ts'; import { getTrendingTagValues } from '@/trends/trending-tag-values.ts'; import { Time } from '@/utils/time.ts'; const console = new Stickynotes('ditto:trends'); -async function updateTrendingNotes() { - console.info('Updating trending notes...'); - const kysely = await DittoDB.getInstance(); - const signal = AbortSignal.timeout(1000); - - 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: 40, - }); - - if (!events.length) { - return; - } - - const signer = new AdminSigner(); - - const label = await signer.signEvent({ - kind: 1985, - content: '', - tags: [ - ['L', 'pub.ditto.trends'], - ['l', '#e', 'pub.ditto.trends'], - ...events.map(({ id }) => ['e', id, Conf.relay]), - ], - created_at: Math.floor(Date.now() / 1000), - }); - - await handleEvent(label, signal); - console.info('Trending notes updated.'); -} - -async function updateTrendingTags(tagName: string, limit: number, extra = '') { +async function updateTrendingTags(tagName: string, kinds: number[], limit: number, extra = '', aliases?: string[]) { console.info(`Updating trending #${tagName}...`); const kysely = await DittoDB.getInstance(); const signal = AbortSignal.timeout(1000); @@ -54,7 +17,10 @@ async function updateTrendingTags(tagName: string, limit: number, extra = '') { const yesterday = Math.floor((Date.now() - Time.days(1)) / 1000); const now = Math.floor(Date.now() / 1000); - const trends = await getTrendingTagValues(kysely, tagName, { + const tagNames = aliases ? [tagName, ...aliases] : [tagName]; + + const trends = await getTrendingTagValues(kysely, tagNames, { + kinds, since: yesterday, until: now, limit, @@ -83,7 +49,7 @@ async function updateTrendingTags(tagName: string, limit: number, extra = '') { /** Start cron jobs for the application. */ export function cron() { - Deno.cron('update trending notes', '15 * * * *', updateTrendingNotes); - Deno.cron('update trending hashtags', '30 * * * *', () => updateTrendingTags('t', 20)); - Deno.cron('update trending links', '45 * * * *', () => updateTrendingTags('r', 20)); + Deno.cron('update trending notes', '15 * * * *', () => updateTrendingTags('e', [1, 6, 7], 40, Conf.relay, ['q'])); + Deno.cron('update trending hashtags', '30 * * * *', () => updateTrendingTags('t', [1], 20)); + Deno.cron('update trending links', '45 * * * *', () => updateTrendingTags('r', [1], 20)); } diff --git a/src/trends/trending-events.ts b/src/trends/trending-events.ts deleted file mode 100644 index 3f0e8ef7..00000000 --- a/src/trends/trending-events.ts +++ /dev/null @@ -1,47 +0,0 @@ -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-tag-values.ts b/src/trends/trending-tag-values.ts index aec0ddf0..17ec53d2 100644 --- a/src/trends/trending-tag-values.ts +++ b/src/trends/trending-tag-values.ts @@ -8,7 +8,7 @@ export async function getTrendingTagValues( /** Kysely instance to execute queries on. */ kysely: Kysely, /** Tag name to filter by, eg `t` or `r`. */ - tagName: string, + tagNames: string[], /** Filter of eligible events. */ filter: NostrFilter, ): Promise<{ value: string; authors: number; uses: number }[]> { @@ -20,7 +20,7 @@ export async function getTrendingTagValues( fn.agg('count', ['nostr_events.pubkey']).distinct().as('authors'), fn.countAll().as('uses'), ]) - .where('nostr_tags.name', '=', tagName) + .where('nostr_tags.name', 'in', tagNames) .groupBy('nostr_tags.value') .orderBy((c) => c.fn.agg('count', ['nostr_events.pubkey']).distinct(), 'desc');