Crunch the tag history in the controller

This commit is contained in:
Alex Gleason 2024-06-02 17:47:36 -05:00
parent b46bcc559e
commit 76c882d836
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
2 changed files with 54 additions and 38 deletions

View File

@ -5,12 +5,8 @@ import { type AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
import { Storages } from '@/storages.ts';
import { Time } from '@/utils.ts';
import { stripTime } from '@/utils/time.ts';
import { generateDateRange, Time } from '@/utils/time.ts';
import { renderStatus } from '@/views/mastodon/statuses.ts';
import { TrendsWorker } from '@/workers/trends.ts';
await TrendsWorker.open('data/trends.sqlite3');
let trendingHashtagsCache = getTrendingHashtags();
@ -31,42 +27,62 @@ const trendingTagsController: AppController = async (c) => {
};
async function getTrendingHashtags() {
const store = await Storages.db();
const [label] = await store.query([{
kinds: [1985],
'#L': ['pub.ditto.trends'],
'#l': ['#t'],
authors: [Conf.pubkey],
limit: 1,
}]);
if (!label) {
return [];
}
const tags = label.tags.filter(([name]) => name === 't');
const now = new Date();
const yesterday = new Date(now.getTime() - Time.days(1));
const lastWeek = new Date(now.getTime() - Time.days(7));
const dates = generateDateRange(lastWeek, now);
/** Most used hashtags within the past 24h. */
const tags = await TrendsWorker.getTrendingTags({
since: yesterday,
until: now,
limit: 20,
});
return Promise.all(tags.map(async ([_, hashtag]) => {
const filters = dates.map((date) => ({
kinds: [1985],
'#L': ['pub.ditto.trends'],
'#l': ['#t'],
'#t': [hashtag],
authors: [Conf.pubkey],
since: Math.floor(date.getTime() / 1000),
until: Math.floor((date.getTime() + Time.days(1)) / 1000),
limit: 1,
}));
return Promise.all(tags.map(async ({ tag, uses, accounts }) => ({
name: tag,
url: Conf.local(`/tags/${tag}`),
history: [
// Use the full 24h query for the current day. Then use `offset: 1` to adjust for this below.
// This result is more accurate than what Mastodon returns.
{
day: String(Math.floor(stripTime(now).getTime() / 1000)),
accounts: String(accounts),
uses: String(uses),
},
...(await TrendsWorker.getTagHistory({
tag,
since: lastWeek,
until: now,
limit: 6,
offset: 1,
})).map((history) => ({
// For some reason, Mastodon wants these to be strings... oh well.
day: String(Math.floor(history.day.getTime() / 1000)),
accounts: String(history.accounts),
uses: String(history.uses),
})),
],
})));
const labels = await store.query(filters);
const history = dates.map((date) => {
const label = labels.find((label) => {
const since = Math.floor(date.getTime() / 1000);
const until = Math.floor((date.getTime() + Time.days(1)) / 1000);
return label.created_at >= since && label.created_at < until;
});
const [, , accounts, uses] = label?.tags.find(([name, value]) => name === 't' && value === hashtag) ?? [];
return {
day: String(date.getTime() / 1000),
accounts: accounts || '0',
uses: uses || '0',
};
});
return {
name: hashtag,
url: Conf.local(`/tags/${hashtag}`),
history,
};
}));
}
const trendingStatusesQuerySchema = z.object({

View File

@ -36,7 +36,7 @@ class EventsDB implements NStore {
'p': ({ event, count, value }) => (count < 15 || event.kind === 3) && isNostrId(value),
'proxy': ({ count, value }) => count === 0 && isURL(value),
'q': ({ event, count, value }) => count === 0 && event.kind === 1 && isNostrId(value),
't': ({ count, value }) => count < 5 && value.length < 50,
't': ({ event, count, value }) => (event.kind === 1985 ? count < 20 : count < 5) && value.length < 50,
'name': ({ event, count }) => event.kind === 30361 && count === 0,
'role': ({ event, count }) => event.kind === 30361 && count === 0,
};