-
Notifications
You must be signed in to change notification settings - Fork 554
/
unspecced.ts
99 lines (87 loc) · 3.34 KB
/
unspecced.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { Server } from '../../../../lexicon'
import { FeedKeyset } from './util/feed'
import { paginate } from '../../../../db/pagination'
import AppContext from '../../../../context'
import { FeedRow } from '../../../services/feed'
import { isPostView } from '../../../../lexicon/types/app/bsky/feed/defs'
import { NotEmptyArray } from '@atproto/common'
import { isViewRecord } from '../../../../lexicon/types/app/bsky/embed/record'
const NO_WHATS_HOT_LABELS: NotEmptyArray<string> = [
'!no-promote',
'corpse',
'self-harm',
]
const NSFW_LABELS = ['porn', 'sexual', 'nudity', 'underwear']
// THIS IS A TEMPORARY UNSPECCED ROUTE
export default function (server: Server, ctx: AppContext) {
server.app.bsky.unspecced.getPopular({
auth: ctx.accessVerifier,
handler: async ({ params, auth }) => {
const { limit, cursor, includeNsfw } = params
const requester = auth.credentials.did
const db = ctx.db.db
const { ref } = db.dynamic
const accountService = ctx.services.account(ctx.db)
const feedService = ctx.services.appView.feed(ctx.db)
const graphService = ctx.services.appView.graph(ctx.db)
const labelsToFilter = includeNsfw
? NO_WHATS_HOT_LABELS
: [...NO_WHATS_HOT_LABELS, ...NSFW_LABELS]
const postsQb = feedService
.selectPostQb()
.leftJoin('post_agg', 'post_agg.uri', 'post.uri')
.where('post_agg.likeCount', '>=', 12)
.where('post.replyParent', 'is', null)
.whereNotExists((qb) =>
qb
.selectFrom('label')
.selectAll()
.where('val', 'in', labelsToFilter)
.where('neg', '=', 0)
.where((clause) =>
clause
.whereRef('label.uri', '=', ref('post.creator'))
.orWhereRef('label.uri', '=', ref('post.uri')),
),
)
.whereNotExists(
accountService.mutedQb(requester, [ref('post.creator')]),
)
.whereNotExists(graphService.blockQb(requester, [ref('post.creator')]))
const keyset = new FeedKeyset(ref('sortAt'), ref('cid'))
let feedQb = ctx.db.db.selectFrom(postsQb.as('feed_items')).selectAll()
feedQb = paginate(feedQb, { limit, cursor, keyset })
const feedItems: FeedRow[] = await feedQb.execute()
const feed = await feedService.hydrateFeed(feedItems, requester)
// filter out any quote post where the internal post has a filtered label
const noLabeledQuotePosts = feed.filter((post) => {
const quoteView = post.post.embed?.record
if (!quoteView || !isViewRecord(quoteView)) return true
for (const label of quoteView.labels || []) {
if (labelsToFilter.includes(label.val)) return false
}
return true
})
// remove record embeds in our response
const noRecordEmbeds = noLabeledQuotePosts.map((post) => {
delete post.post.record['embed']
if (post.reply) {
if (isPostView(post.reply.parent)) {
delete post.reply.parent.record['embed']
}
if (isPostView(post.reply.root)) {
delete post.reply.root.record['embed']
}
}
return post
})
return {
encoding: 'application/json',
body: {
feed: noRecordEmbeds,
cursor: keyset.packFromResult(feedItems),
},
}
},
})
}