Add trends controller... and it kind of works!

This commit is contained in:
Alex Gleason 2023-07-25 17:07:09 -05:00
parent 11f21e3922
commit 1d67181e52
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
6 changed files with 51 additions and 13 deletions

View File

@ -2,7 +2,7 @@
"$schema": "https://deno.land/x/deno@v1.32.3/cli/schemas/config-file.v1.json",
"lock": false,
"tasks": {
"dev": "deno run --allow-read --allow-env --allow-net --allow-ffi --unstable --watch src/server.ts",
"dev": "deno run --allow-read --allow-write --allow-env --allow-net --allow-ffi --unstable --watch src/server.ts",
"test": "deno test -A --unstable src"
},
"imports": {

View File

@ -27,6 +27,7 @@ import {
statusController,
} from './controllers/api/statuses.ts';
import { streamingController } from './controllers/api/streaming.ts';
import { trendingTagsController } from './controllers/api/trends.ts';
import { indexController } from './controllers/site.ts';
import { hostMetaController } from './controllers/well-known/host-meta.ts';
import { nodeInfoController, nodeInfoSchemaController } from './controllers/well-known/nodeinfo.ts';
@ -101,6 +102,9 @@ app.get('/api/v2/search', searchController);
app.get('/api/pleroma/frontend_configurations', frontendConfigController);
app.get('/api/v1/trends/tags', trendingTagsController);
app.get('/api/v1/trends', trendingTagsController);
// Not (yet) implemented.
app.get('/api/v1/notifications', emptyArrayController);
app.get('/api/v1/bookmarks', emptyArrayController);

View File

@ -0,0 +1,23 @@
import { type AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { trends } from '@/trends.ts';
import { Time } from '@/utils.ts';
const trendingTagsController: AppController = (c) => {
const yesterday = new Date(new Date().getTime() - Time.days(1));
const now = new Date();
const tags = trends.getTrendingTags(yesterday, now);
return c.json(tags.map(({ name, accounts }) => ({
name,
url: Conf.local(`/tags/${name}`),
history: [{
day: String(Math.floor(yesterday.getTime() / 1000)),
uses: String(accounts), // Not actually true - we don't collect this
accounts: String(accounts),
}],
})));
};
export { trendingTagsController };

View File

@ -1,17 +1,15 @@
import { Conf } from '@/config.ts';
import { relayInit, Sqlite } from '@/deps.ts';
import { TrendsDB } from '@/trends.ts';
const db = new Sqlite('data/trends.sqlite3');
const trends = new TrendsDB(db);
import { relayInit } from '@/deps.ts';
import { trends } from '@/trends.ts';
import { nostrNow } from '@/utils.ts';
const relay = relayInit(Conf.relay);
await relay.connect();
const sub = relay.sub([{ kinds: [1] }]);
const sub = relay.sub([{ kinds: [1], since: nostrNow() }]);
sub.on('eose', sub.unsub);
sub.on('event', (event) => {
console.info('loopback event:', event.id);
const tags = event.tags
.filter((tag) => tag[0] === 't')
.map((tag) => tag[1]);

View File

@ -18,7 +18,13 @@ Deno.test('getTrendingTags', () => {
new Date('2999-01-01T00:00:00'),
);
assertEquals(result, ['ditto', 'hello', 'yolo']);
const expected = [
{ name: 'ditto', accounts: 3 },
{ name: 'hello', accounts: 2 },
{ name: 'yolo', accounts: 1 },
];
assertEquals(result, expected);
trends.cleanupTagUsages(new Date('2999-01-01T00:00:00'));
});

View File

@ -18,7 +18,7 @@ class TrendsDB {
`);
}
getTrendingTags(since: Date, until: Date): string[] {
getTrendingTags(since: Date, until: Date) {
return this.#db.query<string[]>(
`
SELECT tag, COUNT(DISTINCT pubkey8)
@ -29,12 +29,15 @@ class TrendsDB {
DESC LIMIT 10;
`,
[since, until],
).map((row) => row[0]);
).map((row) => ({
name: row[0],
accounts: Number(row[1]),
}));
}
addTagUsages(pubkey: string, hashtags: string[]): void {
const pubkey8 = hexIdSchema.parse(pubkey).substring(0, 8);
const tags = hashtagSchema.array().parse(hashtags);
const tags = hashtagSchema.array().min(1).parse(hashtags);
const now = new Date();
this.#db.query(
@ -51,4 +54,8 @@ class TrendsDB {
}
}
export { TrendsDB };
const trends = new TrendsDB(
new Sqlite('data/trends.sqlite3'),
);
export { trends, TrendsDB };