fedicrawl/application/src/Fediverse/Providers/Mastodon/retrieveLocalPublicUsersPag...

103 wiersze
2.9 KiB
TypeScript
Czysty Zwykły widok Historia

2021-12-23 14:14:06 +00:00
import { assertSuccessJsonResponse } from '../../assertSuccessJsonResponse'
2022-01-03 12:26:17 +00:00
import { z } from 'zod'
2022-11-29 13:11:27 +00:00
import getTimeoutMilliseconds from '../../getTimeoutMilliseconds.js'
import { FeedProviderMethod } from '../FeedProviderMethod'
import { NoMoreFeedsError } from '../NoMoreFeedsError'
2022-09-18 11:32:25 +00:00
import { FeedData } from '../FeedData'
2021-12-23 14:14:06 +00:00
2022-11-22 09:57:34 +00:00
const limit = 40
2021-12-23 14:14:06 +00:00
const emojiSchema = z.object({
shortcode: z.string(),
url: z.string()
})
const schema = z.array(
z.object({
id: z.string(),
username: z.string(),
display_name: z.string(),
locked: z.boolean(),
bot: z.boolean(),
created_at: z.string(),
note: z.string(),
url: z.string(),
avatar: z.string(),
followers_count: z.number(),
following_count: z.number(),
statuses_count: z.number(),
last_status_at: z.nullable(z.string()),
emojis: z.array(emojiSchema),
fields: z.array(
z.object({
name: z.string(),
value: z.string(),
verified_at: z.nullable(z.string())
})
2022-11-22 16:01:25 +00:00
),
noindex: z.boolean().optional().nullable()
2021-12-23 14:14:06 +00:00
})
)
type Emoji = z.infer<typeof emojiSchema>
const replaceEmojis = (text: string, emojis: Emoji[]): string => {
2022-09-18 11:32:25 +00:00
emojis.forEach((emoji) => {
2021-12-23 14:14:06 +00:00
text = text.replace(
RegExp(`:${emoji.shortcode}:`, 'gi'),
2022-09-18 11:32:25 +00:00
`<img draggable="false" class="emoji" title="${emoji.shortcode}" alt="${emoji.shortcode}" src="${emoji.url}" />`
2021-12-23 14:14:06 +00:00
)
})
return text
}
2022-09-18 11:32:25 +00:00
export const retrieveLocalPublicUsersPage: FeedProviderMethod = async (
domain,
2022-11-22 15:37:11 +00:00
page,
robotsTxt
2022-09-18 11:32:25 +00:00
): Promise<FeedData[]> => {
2022-11-29 13:11:27 +00:00
const response = await robotsTxt.getIfAllowed(new URL(`https://${domain}/api/v1/directory`), {
params: {
2022-09-18 11:32:25 +00:00
limit,
offset: page * limit,
local: true
},
2022-11-29 13:11:27 +00:00
timeout: getTimeoutMilliseconds(domain)
})
assertSuccessJsonResponse(response)
const responseData = schema.parse(response.data)
if (responseData.length === 0) {
throw new NoMoreFeedsError('user')
2021-12-23 14:14:06 +00:00
}
2022-09-18 11:32:25 +00:00
return responseData.map((item) => {
return {
name: item.username,
displayName: replaceEmojis(item.display_name, item.emojis),
description: replaceEmojis(item.note, item.emojis),
followersCount: item.followers_count,
followingCount: item.following_count,
statusesCount: item.statuses_count,
bot: item.bot,
url: item.url,
avatar: item.avatar,
locked: item.locked,
lastStatusAt:
item.last_status_at !== null
? new Date(item.last_status_at)
: undefined,
createdAt: new Date(item.created_at),
fields: item.fields.map((field) => {
return {
name: replaceEmojis(field.name, item.emojis),
value: replaceEmojis(field.value, item.emojis),
verifiedAt:
field.verified_at !== null ? new Date(field.verified_at) : undefined
}
}),
type: 'account',
2022-11-22 16:01:25 +00:00
parentFeed: undefined,
indexable: !(item.noindex ?? false)
}
2022-09-18 11:32:25 +00:00
})
2021-12-23 14:14:06 +00:00
}