Clean up what's hot (#1002)
* changes to clean up whats hot * fix test * add quote posts back in & use underwear label instead of no-promote * tidy
This commit is contained in:
parent
41793b7ff9
commit
c8e6adbbf5
packages
bsky/src/services/label
pds
@ -3,14 +3,9 @@ import Database from '../../db'
|
||||
import { Label } from '../../lexicon/types/com/atproto/label/defs'
|
||||
import { ids } from '../../lexicon/lexicons'
|
||||
import { sql } from 'kysely'
|
||||
import { NotEmptyArray } from '@atproto/common'
|
||||
|
||||
export type Labels = Record<string, Label[]>
|
||||
|
||||
// @TODO forward these labels to client
|
||||
// these are labels are currently only used server side & not sent to client since it does not handle them correctly
|
||||
const SERVER_SIDE_LABELS: NotEmptyArray<string> = ['!no-promote']
|
||||
|
||||
export class LabelService {
|
||||
constructor(public db: Database) {}
|
||||
|
||||
@ -73,7 +68,6 @@ export class LabelService {
|
||||
const res = await this.db.db
|
||||
.selectFrom('label')
|
||||
.where('label.uri', 'in', subjects)
|
||||
.where('label.val', 'not in', SERVER_SIDE_LABELS)
|
||||
.if(!includeNeg, (qb) => qb.where('neg', '=', false))
|
||||
.selectAll()
|
||||
.execute()
|
||||
|
@ -5,6 +5,7 @@ import AppContext from '../../../../context'
|
||||
import { FeedRow } from '../../../services/feed'
|
||||
import { FeedViewPost } 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',
|
||||
@ -12,7 +13,7 @@ const NO_WHATS_HOT_LABELS: NotEmptyArray<string> = [
|
||||
'self-harm',
|
||||
]
|
||||
|
||||
const NSFW_LABELS = ['porn', 'sexual']
|
||||
const NSFW_LABELS = ['porn', 'sexual', 'nudity', 'underwear']
|
||||
|
||||
// THIS IS A TEMPORARY UNSPECCED ROUTE
|
||||
export default function (server: Server, ctx: AppContext) {
|
||||
@ -36,6 +37,7 @@ export default function (server: Server, ctx: AppContext) {
|
||||
.selectPostQb()
|
||||
.leftJoin('post_agg', 'post_agg.uri', 'post.uri')
|
||||
.where('post_agg.likeCount', '>=', 12)
|
||||
.where('post.replyParent', 'is', null)
|
||||
.whereNotExists((qb) =>
|
||||
qb
|
||||
.selectFrom('label')
|
||||
@ -70,7 +72,18 @@ export default function (server: Server, ctx: AppContext) {
|
||||
requester,
|
||||
)
|
||||
|
||||
const noRecordEmbeds = feed.map((post) => {
|
||||
// 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) {
|
||||
delete post.reply.parent.record['embed']
|
||||
|
@ -3,14 +3,9 @@ import Database from '../../../db'
|
||||
import { Label } from '../../../lexicon/types/com/atproto/label/defs'
|
||||
import { ids } from '../../../lexicon/lexicons'
|
||||
import { sql } from 'kysely'
|
||||
import { NotEmptyArray } from '@atproto/common'
|
||||
|
||||
export type Labels = Record<string, Label[]>
|
||||
|
||||
// @TODO forward these labels to client
|
||||
// these are labels are currently only used server side & not sent to client since it does not handle them correctly
|
||||
const SERVER_SIDE_LABELS: NotEmptyArray<string> = ['!no-promote']
|
||||
|
||||
export class LabelService {
|
||||
constructor(public db: Database) {}
|
||||
|
||||
@ -73,7 +68,6 @@ export class LabelService {
|
||||
const res = await this.db.db
|
||||
.selectFrom('label')
|
||||
.where('label.uri', 'in', subjects)
|
||||
.where('label.val', 'not in', SERVER_SIDE_LABELS)
|
||||
.if(!includeNeg, (qb) => qb.where('neg', '=', 0))
|
||||
.selectAll()
|
||||
.execute()
|
||||
|
@ -129,6 +129,14 @@ export const sexualLabels = (classes: HiveRespClass[]): string[] => {
|
||||
return ['nudity']
|
||||
}
|
||||
}
|
||||
|
||||
// as a stop gap, we label underwear posts as !no-promote to keep them out of what's hot
|
||||
for (const nudityClass of ['yes_male_underwear', 'yes_female_underwear']) {
|
||||
if (scores[nudityClass] >= 0.9) {
|
||||
return ['underwear']
|
||||
}
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ describe('popular views', () => {
|
||||
{ headers: sc.getHeaders(alice) },
|
||||
)
|
||||
const feedUris = res.data.feed.map((i) => i.post.uri).sort()
|
||||
const expected = [one.ref.uriStr, two.ref.uriStr, three.ref.uriStr].sort()
|
||||
const expected = [one.ref.uriStr, two.ref.uriStr].sort()
|
||||
expect(feedUris).toEqual(expected)
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user