feat: support trendings by language

This commit is contained in:
P. Reis 2024-09-30 14:02:12 -03:00
parent b33a6cdfe0
commit 61bc57c778

View file

@ -1,3 +1,4 @@
import ISO6391, { LanguageCode } from 'iso-639-1';
import { NostrFilter } from '@nostrify/nostrify'; import { NostrFilter } from '@nostrify/nostrify';
import { Stickynotes } from '@soapbox/stickynotes'; import { Stickynotes } from '@soapbox/stickynotes';
import { Kysely, sql } from 'kysely'; import { Kysely, sql } from 'kysely';
@ -19,8 +20,11 @@ export async function getTrendingTagValues(
tagNames: string[], tagNames: string[],
/** Filter of eligible events. */ /** Filter of eligible events. */
filter: NostrFilter, filter: NostrFilter,
/** Only return trending events of 'language' */
language?: LanguageCode,
): Promise<{ value: string; authors: number; uses: number }[]> { ): Promise<{ value: string; authors: number; uses: number }[]> {
let query = kysely let query = kysely.with('trends', (db) => {
let query = db
.selectFrom([ .selectFrom([
'nostr_events', 'nostr_events',
sql<{ key: string; value: string }>`jsonb_each_text(nostr_events.tags_index)`.as('kv'), sql<{ key: string; value: string }>`jsonb_each_text(nostr_events.tags_index)`.as('kv'),
@ -47,6 +51,18 @@ export async function getTrendingTagValues(
if (typeof filter.until === 'number') { if (typeof filter.until === 'number') {
query = query.where('nostr_events.created_at', '<=', filter.until); query = query.where('nostr_events.created_at', '<=', filter.until);
} }
return query;
})
.selectFrom(['trends'])
.innerJoin('nostr_events', 'trends.value', 'nostr_events.id')
.select(['value', 'authors', 'uses']);
if (language) {
query = query.where('nostr_events.language', '=', language);
}
query = query.orderBy('authors desc');
if (typeof filter.limit === 'number') { if (typeof filter.limit === 'number') {
query = query.limit(filter.limit); query = query.limit(filter.limit);
} }
@ -68,6 +84,7 @@ export async function updateTrendingTags(
limit: number, limit: number,
extra = '', extra = '',
aliases?: string[], aliases?: string[],
language?: LanguageCode,
) { ) {
console.info(`Updating trending ${l}...`); console.info(`Updating trending ${l}...`);
const kysely = await Storages.kysely(); const kysely = await Storages.kysely();
@ -84,7 +101,7 @@ export async function updateTrendingTags(
since: yesterday, since: yesterday,
until: now, until: now,
limit, limit,
}); }, language);
if (!trends.length) { if (!trends.length) {
console.info(`No trending ${l} found. Skipping.`); console.info(`No trending ${l} found. Skipping.`);
@ -93,14 +110,19 @@ export async function updateTrendingTags(
const signer = new AdminSigner(); const signer = new AdminSigner();
const label = await signer.signEvent({ const tags = [
kind: 1985,
content: '',
tags: [
['L', 'pub.ditto.trends'], ['L', 'pub.ditto.trends'],
['l', l, 'pub.ditto.trends'], ['l', l, 'pub.ditto.trends'],
...trends.map(({ value, authors, uses }) => [tagName, value, extra, authors.toString(), uses.toString()]), ...trends.map(({ value, authors, uses }) => [tagName, value, extra, authors.toString(), uses.toString()]),
], ];
if (language) {
tags.push(['lang', language]);
}
const label = await signer.signEvent({
kind: 1985,
content: '',
tags,
created_at: Math.floor(Date.now() / 1000), created_at: Math.floor(Date.now() / 1000),
}); });
@ -122,8 +144,17 @@ export function updateTrendingZappedEvents(): Promise<void> {
} }
/** Update trending events. */ /** Update trending events. */
export function updateTrendingEvents(): Promise<void> { export async function updateTrendingEvents(): Promise<void> {
return updateTrendingTags('#e', 'e', [1, 6, 7, 9735], 40, Conf.relay, ['q']); const languages = Conf.trendLanguages;
if (!languages) return updateTrendingTags('#e', 'e', [1, 6, 7, 9735], 40, Conf.relay, ['q']);
const promise: Promise<void>[] = [];
for (const language of languages) {
promise.push(updateTrendingTags('#e', 'e', [1, 6, 7, 9735], 40, Conf.relay, ['q'], language));
}
await Promise.allSettled(promise);
} }
/** Update trending hashtags. */ /** Update trending hashtags. */