From b27b84e3fb4350fca7b1ee92558d97e2ebb80b9e Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 29 Aug 2023 18:08:00 -0500 Subject: [PATCH] Add favourited_by and reblogged_by controllers --- src/app.ts | 4 +++ src/controllers/api/instance.ts | 9 +++++++ src/controllers/api/statuses.ts | 46 ++++++++++++++++++++++++++++++--- src/utils/web.ts | 2 +- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/app.ts b/src/app.ts index 346831f..73fcb2d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -35,6 +35,8 @@ import { contextController, createStatusController, favouriteController, + favouritedByController, + rebloggedByController, statusController, } from './controllers/api/statuses.ts'; import { streamingController } from './controllers/api/streaming.ts'; @@ -106,6 +108,8 @@ app.post('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/follow', followController); app.get('/api/v1/accounts/:pubkey{[0-9a-f]{64}}/statuses', accountStatusesController); app.get('/api/v1/accounts/:pubkey{[0-9a-f]{64}}', accountController); +app.get('/api/v1/statuses/:id{[0-9a-f]{64}}/favourited_by', favouritedByController); +app.get('/api/v1/statuses/:id{[0-9a-f]{64}}/reblogged_by', rebloggedByController); app.get('/api/v1/statuses/:id{[0-9a-f]{64}}/context', contextController); app.get('/api/v1/statuses/:id{[0-9a-f]{64}}', statusController); app.post('/api/v1/statuses/:id{[0-9a-f]{64}}/favourite', favouriteController); diff --git a/src/controllers/api/instance.ts b/src/controllers/api/instance.ts index c28e03b..b30c753 100644 --- a/src/controllers/api/instance.ts +++ b/src/controllers/api/instance.ts @@ -30,6 +30,15 @@ const instanceController: AppController = (c) => { max_media_attachments: 20, }, }, + pleroma: { + metadata: { + features: [ + 'mastodon_api', + 'mastodon_api_streaming', + 'exposable_reactions', + ], + }, + }, languages: ['en'], stats: { domain_count: 0, diff --git a/src/controllers/api/statuses.ts b/src/controllers/api/statuses.ts index c7ad80c..9efc4e4 100644 --- a/src/controllers/api/statuses.ts +++ b/src/controllers/api/statuses.ts @@ -1,8 +1,9 @@ import { type AppController } from '@/app.ts'; import { type Event, ISO6391, z } from '@/deps.ts'; -import { getAncestors, getDescendants, getEvent } from '@/queries.ts'; -import { toStatus } from '@/transformers/nostr-to-mastoapi.ts'; -import { createEvent, parseBody } from '@/utils/web.ts'; +import * as mixer from '@/mixer.ts'; +import { getAncestors, getAuthor, getDescendants, getEvent } from '@/queries.ts'; +import { toAccount, toStatus } from '@/transformers/nostr-to-mastoapi.ts'; +import { createEvent, paginated, parseBody } from '@/utils/web.ts'; const createStatusSchema = z.object({ in_reply_to_id: z.string().regex(/[0-9a-f]{64}/).nullish(), @@ -128,4 +129,41 @@ const favouriteController: AppController = async (c) => { } }; -export { contextController, createStatusController, favouriteController, statusController }; +const favouritedByController: AppController = async (c) => { + const id = c.req.param('id'); + + const events = await mixer.getFilters([{ kinds: [7], '#e': [id] }]); + + const accounts = await Promise.all(events.map(async ({ pubkey }) => { + const author = await getAuthor(pubkey); + if (author) { + return toAccount(author); + } + })); + + return paginated(c, events, accounts); +}; + +const rebloggedByController: AppController = async (c) => { + const id = c.req.param('id'); + + const events = await mixer.getFilters([{ kinds: [6], '#e': [id] }]); + + const accounts = await Promise.all(events.map(async ({ pubkey }) => { + const author = await getAuthor(pubkey); + if (author) { + return toAccount(author); + } + })); + + return paginated(c, events, accounts); +}; + +export { + contextController, + createStatusController, + favouriteController, + favouritedByController, + rebloggedByController, + statusController, +}; diff --git a/src/utils/web.ts b/src/utils/web.ts index 6d89523..5bae5c9 100644 --- a/src/utils/web.ts +++ b/src/utils/web.ts @@ -75,7 +75,7 @@ type PaginationParams = z.infer; /** Build HTTP Link header for Mastodon API pagination. */ function buildLinkHeader(url: string, events: Event[]): string | undefined { - if (!events.length) return; + if (events.length <= 1) return; const firstEvent = events[0]; const lastEvent = events[events.length - 1];