unoffical wafrn mirror
wafrn.net
atproto
social-network
activitypub
1import { Op } from 'sequelize'
2import { PostAncestor, sequelize, SilencedPost } from '../../models/index.js'
3import { redisCache } from '../redis.js'
4import { logger } from '../logger.js'
5
6async function getMutedPosts(userId: string, superMute = false): Promise<Array<string>> {
7 let res: string[] = []
8 const cacheResult = await redisCache.get((superMute ? 'superMutedPosts:' : 'mutedPosts:') + userId)
9 if (cacheResult) {
10 res = JSON.parse(cacheResult)
11 } else {
12 const mutedPostsQuery = await SilencedPost.findAll({
13 where: {
14 userId: userId,
15 superMuted: superMute
16 ? true
17 : {
18 [Op.in]: [true, false, null, undefined] as any // yeah ok this is a bit dirty haha but its only one code path
19 }
20 },
21 attributes: ['postId']
22 })
23 res = mutedPostsQuery.map((elem: any) => elem.postId)
24 if (superMute && res.length) {
25 const muted = res.map((elem) => "'" + (elem ? elem : '00000000-0000-0000-0000-000000000000') + "'")
26 const mutedPosts = (await sequelize.query(
27 `SELECT "postsId" FROM "postsancestors" where "ancestorId" IN (${muted})`
28 )) as PostAncestor[][]
29 res = mutedPosts[0].map((elem) => elem.postsId)
30 }
31 await redisCache.set((superMute ? 'superMutedPosts:' : 'mutedPosts:') + userId, JSON.stringify(res), 'EX', 600)
32 }
33 return res
34}
35
36async function getMutedPostsMultiple(userIds: string[], superMute = false) {
37 let cacheResults: (string | null)[] = []
38 try {
39 cacheResults = await redisCache.mget(
40 userIds.map((userId) => (superMute ? 'superMutedPosts:' : 'mutedPosts:') + userId)
41 )
42 } catch (error) {
43 logger.error({
44 message: `Error getMutedPostsMultiple`,
45 userIds,
46 superMute,
47 error
48 })
49 }
50
51 if (cacheResults.every((result) => !!result)) {
52 const ids = cacheResults.map((result) => JSON.parse(result!) as string[])
53 return new Map(userIds.map((userId, index) => [userId, ids[index]]))
54 }
55
56 const where = {
57 userId: {
58 [Op.in]: userIds
59 }
60 } as { userId: Record<any, any>; superMuted?: true }
61
62 if (superMute) {
63 where.superMuted = true
64 }
65
66 const mutedFirstIds = await SilencedPost.findAll({
67 where,
68 attributes: ['postId', 'userId']
69 })
70
71 const postIds = new Map<string, string[]>()
72 for (const result of cacheResults) {
73 const index = cacheResults.indexOf(result)
74 const userId = userIds[index]
75
76 if (result) {
77 postIds.set(userId, JSON.parse(result) as string[])
78 } else {
79 let mutedIds = mutedFirstIds.filter((elem) => elem.userId === userId).map((elem) => elem.postId)
80
81 if (superMute && mutedIds.length) {
82 const formattedIds = mutedIds.map((elem) => "'" + elem + "'").join(',')
83 const mutedPosts = (await sequelize.query(
84 `SELECT "postsId" FROM "postsancestors" where "ancestorId" IN (${formattedIds})`
85 )) as [PostAncestor[], unknown]
86 mutedIds = mutedPosts[0].map((elem) => elem.postsId)
87 }
88
89 await redisCache.set(
90 (superMute ? 'superMutedPosts:' : 'mutedPosts:') + userIds[index],
91 JSON.stringify(mutedIds),
92 'EX',
93 600
94 )
95 postIds.set(userId, mutedIds)
96 }
97 }
98
99 return postIds
100}
101
102export { getMutedPosts, getMutedPostsMultiple }