Filter host for channels and playlists search

This commit is contained in:
Chocobozzz
2021-07-28 10:32:40 +02:00
parent f68d1cb6ac
commit fa47956ecf
18 changed files with 237 additions and 80 deletions

View File

@@ -1,4 +1,4 @@
import { FindOptions, Includeable, literal, Op, QueryTypes, ScopeOptions, Transaction } from 'sequelize'
import { FindOptions, Includeable, literal, Op, QueryTypes, ScopeOptions, Transaction, WhereOptions } from 'sequelize'
import {
AllowNull,
BeforeDestroy,
@@ -17,7 +17,6 @@ import {
Table,
UpdatedAt
} from 'sequelize-typescript'
import { setAsUpdated } from '@server/helpers/database-utils'
import { MAccountActor } from '@server/types/models'
import { AttributesOnly } from '@shared/core-utils'
import { ActivityPubActor } from '../../../shared/models/activitypub'
@@ -41,6 +40,7 @@ import { ActorModel, unusedActorAttributesForAPI } from '../actor/actor'
import { ActorFollowModel } from '../actor/actor-follow'
import { ActorImageModel } from '../actor/actor-image'
import { ServerModel } from '../server/server'
import { setAsUpdated } from '../shared'
import { buildServerIdsFollowedBy, buildTrigramSearchIndex, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils'
import { VideoModel } from './video'
import { VideoPlaylistModel } from './video-playlist'
@@ -58,6 +58,7 @@ export enum ScopeNames {
type AvailableForListOptions = {
actorId: number
search?: string
host?: string
}
type AvailableWithStatsOptions = {
@@ -83,6 +84,33 @@ export type SummaryOptions = {
// Only list local channels OR channels that are on an instance followed by actorId
const inQueryInstanceFollow = buildServerIdsFollowedBy(options.actorId)
const whereActor = {
[Op.or]: [
{
serverId: null
},
{
serverId: {
[Op.in]: Sequelize.literal(inQueryInstanceFollow)
}
}
]
}
let serverRequired = false
let whereServer: WhereOptions
if (options.host && options.host !== WEBSERVER.HOST) {
serverRequired = true
whereServer = { host: options.host }
}
if (options.host === WEBSERVER.HOST) {
Object.assign(whereActor, {
[Op.and]: [ { serverId: null } ]
})
}
return {
include: [
{
@@ -90,19 +118,18 @@ export type SummaryOptions = {
exclude: unusedActorAttributesForAPI
},
model: ActorModel,
where: {
[Op.or]: [
{
serverId: null
},
{
serverId: {
[Op.in]: Sequelize.literal(inQueryInstanceFollow)
}
}
]
},
where: whereActor,
include: [
{
model: ServerModel,
required: serverRequired,
where: whereServer
},
{
model: ActorImageModel,
as: 'Avatar',
required: false
},
{
model: ActorImageModel,
as: 'Banner',
@@ -431,6 +458,8 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`
start: number
count: number
sort: string
host?: string
}) {
const attributesInclude = []
const escapedSearch = VideoChannelModel.sequelize.escape(options.search)
@@ -458,7 +487,7 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`
return VideoChannelModel
.scope({
method: [ ScopeNames.FOR_API, { actorId: options.actorId } as AvailableForListOptions ]
method: [ ScopeNames.FOR_API, { actorId: options.actorId, host: options.host } as AvailableForListOptions ]
})
.findAndCountAll(query)
.then(({ rows, count }) => {

View File

@@ -21,7 +21,6 @@ import {
import { Where } from 'sequelize/types/lib/utils'
import validator from 'validator'
import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub'
import { doesExist } from '@server/helpers/database-utils'
import { logger } from '@server/helpers/logger'
import { extractVideo } from '@server/helpers/video'
import { getTorrentFilePath } from '@server/lib/video-paths'
@@ -45,6 +44,7 @@ import {
} from '../../initializers/constants'
import { MVideoFile, MVideoFileStreamingPlaylistVideo, MVideoFileVideo } from '../../types/models/video/video-file'
import { VideoRedundancyModel } from '../redundancy/video-redundancy'
import { doesExist } from '../shared'
import { parseAggregateResult, throwIfNotValid } from '../utils'
import { VideoModel } from './video'
import { VideoStreamingPlaylistModel } from './video-streaming-playlist'

View File

@@ -17,7 +17,6 @@ import {
Table,
UpdatedAt
} from 'sequelize-typescript'
import { setAsUpdated } from '@server/helpers/database-utils'
import { buildUUID, uuidToShort } from '@server/helpers/uuid'
import { MAccountId, MChannelId } from '@server/types/models'
import { AttributesOnly, buildPlaylistEmbedPath, buildPlaylistWatchPath } from '@shared/core-utils'
@@ -53,6 +52,7 @@ import {
} from '../../types/models/video/video-playlist'
import { AccountModel, ScopeNames as AccountScopeNames, SummaryOptions } from '../account/account'
import { ActorModel } from '../actor/actor'
import { setAsUpdated } from '../shared'
import {
buildServerIdsFollowedBy,
buildTrigramSearchIndex,
@@ -82,6 +82,7 @@ type AvailableForListOptions = {
videoChannelId?: number
listMyPlaylists?: boolean
search?: string
host?: string
withVideos?: boolean
}
@@ -141,9 +142,19 @@ function getVideoLengthSelect () {
]
},
[ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => {
const whereAnd: WhereOptions[] = []
const whereServer = options.host && options.host !== WEBSERVER.HOST
? { host: options.host }
: undefined
let whereActor: WhereOptions = {}
const whereAnd: WhereOptions[] = []
if (options.host === WEBSERVER.HOST) {
whereActor = {
[Op.and]: [ { serverId: null } ]
}
}
if (options.listMyPlaylists !== true) {
whereAnd.push({
@@ -168,9 +179,7 @@ function getVideoLengthSelect () {
})
}
whereActor = {
[Op.or]: whereActorOr
}
Object.assign(whereActor, { [Op.or]: whereActorOr })
}
if (options.accountId) {
@@ -228,7 +237,7 @@ function getVideoLengthSelect () {
include: [
{
model: AccountModel.scope({
method: [ AccountScopeNames.SUMMARY, { whereActor } as SummaryOptions ]
method: [ AccountScopeNames.SUMMARY, { whereActor, whereServer } as SummaryOptions ]
}),
required: true
},
@@ -349,6 +358,7 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
videoChannelId?: number
listMyPlaylists?: boolean
search?: string
host?: string
withVideos?: boolean // false by default
}) {
const query = {
@@ -368,6 +378,7 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
videoChannelId: options.videoChannelId,
listMyPlaylists: options.listMyPlaylists,
search: options.search,
host: options.host,
withVideos: options.withVideos || false
} as AvailableForListOptions
]
@@ -390,6 +401,7 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
count: number
sort: string
search?: string
host?: string
}) {
return VideoPlaylistModel.listForApi({
...options,

View File

@@ -2,7 +2,6 @@ import * as memoizee from 'memoizee'
import { join } from 'path'
import { Op } from 'sequelize'
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
import { doesExist } from '@server/helpers/database-utils'
import { VideoFileModel } from '@server/models/video/video-file'
import { MStreamingPlaylist, MVideo } from '@server/types/models'
import { AttributesOnly } from '@shared/core-utils'
@@ -20,6 +19,7 @@ import {
WEBSERVER
} from '../../initializers/constants'
import { VideoRedundancyModel } from '../redundancy/video-redundancy'
import { doesExist } from '../shared'
import { throwIfNotValid } from '../utils'
import { VideoModel } from './video'

View File

@@ -24,7 +24,6 @@ import {
Table,
UpdatedAt
} from 'sequelize-typescript'
import { setAsUpdated } from '@server/helpers/database-utils'
import { buildNSFWFilter } from '@server/helpers/express-utils'
import { uuidToShort } from '@server/helpers/uuid'
import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video'
@@ -92,6 +91,7 @@ import { VideoRedundancyModel } from '../redundancy/video-redundancy'
import { ServerModel } from '../server/server'
import { TrackerModel } from '../server/tracker'
import { VideoTrackerModel } from '../server/video-tracker'
import { setAsUpdated } from '../shared'
import { UserModel } from '../user/user'
import { UserVideoHistoryModel } from '../user/user-video-history'
import { buildTrigramSearchIndex, buildWhereIdOrUUID, getVideoSort, isOutdated, throwIfNotValid } from '../utils'