MVideoPlaylistElementVideoUrlPlaylistPrivacy,
MVideoPlaylistVideoThumbnail
} from '@server/types/models/video/video-playlist-element'
+import { forceNumber } from '@shared/core-utils'
+import { AttributesOnly } from '@shared/typescript-utils'
import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object'
import { VideoPrivacy } from '../../../shared/models/videos'
import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model'
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
import { AccountModel } from '../account/account'
-import { getSort, throwIfNotValid } from '../utils'
+import { getSort, throwIfNotValid } from '../shared'
import { ForAPIOptions, ScopeNames as VideoScopeNames, VideoModel } from './video'
import { VideoPlaylistModel } from './video-playlist'
-import { AttributesOnly } from '@shared/typescript-utils'
@Table({
tableName: 'videoPlaylistElement',
playlistId: number | string,
playlistElementId: number
): Promise<MVideoPlaylistElementVideoUrlPlaylistPrivacy> {
- const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId }
+ const playlistWhere = validator.isUUID('' + playlistId)
+ ? { uuid: playlistId }
+ : { id: playlistId }
const query = {
include: [
}
static listUrlsOfForAP (videoPlaylistId: number, start: number, count: number, t?: Transaction) {
- const query = {
- attributes: [ 'url' ],
- offset: start,
- limit: count,
- order: getSort('position'),
- where: {
- videoPlaylistId
- },
- transaction: t
+ const getQuery = (forCount: boolean) => {
+ return {
+ attributes: forCount
+ ? []
+ : [ 'url' ],
+ offset: start,
+ limit: count,
+ order: getSort('position'),
+ where: {
+ videoPlaylistId
+ },
+ transaction: t
+ }
}
- return VideoPlaylistElementModel
- .findAndCountAll(query)
- .then(({ rows, count }) => {
- return { total: count, data: rows.map(e => e.url) }
- })
+ return Promise.all([
+ VideoPlaylistElementModel.count(getQuery(true)),
+ VideoPlaylistElementModel.findAll(getQuery(false))
+ ]).then(([ total, rows ]) => ({
+ total,
+ data: rows.map(e => e.url)
+ }))
}
static loadFirstElementWithVideoThumbnail (videoPlaylistId: number): Promise<MVideoPlaylistVideoThumbnail> {
.then(position => position ? position + 1 : 1)
}
- static reassignPositionOf (
- videoPlaylistId: number,
- firstPosition: number,
- endPosition: number,
- newPosition: number,
+ static reassignPositionOf (options: {
+ videoPlaylistId: number
+ firstPosition: number
+ endPosition: number
+ newPosition: number
transaction?: Transaction
- ) {
+ }) {
+ const { videoPlaylistId, firstPosition, endPosition, newPosition, transaction } = options
+
const query = {
where: {
videoPlaylistId,
validate: false // We use a literal to update the position
}
- const positionQuery = Sequelize.literal(`${newPosition} + "position" - ${firstPosition}`)
+ const positionQuery = Sequelize.literal(`${forceNumber(newPosition)} + "position" - ${forceNumber(firstPosition)}`)
return VideoPlaylistElementModel.update({ position: positionQuery }, query)
}
return VideoPlaylistElementModel.increment({ position: by }, query)
}
- getType (this: MVideoPlaylistElementFormattable, displayNSFW?: boolean, accountId?: number) {
+ toFormattedJSON (
+ this: MVideoPlaylistElementFormattable,
+ options: { accountId?: number } = {}
+ ): VideoPlaylistElement {
+ return {
+ id: this.id,
+ position: this.position,
+ startTimestamp: this.startTimestamp,
+ stopTimestamp: this.stopTimestamp,
+
+ type: this.getType(options.accountId),
+
+ video: this.getVideoElement(options.accountId)
+ }
+ }
+
+ getType (this: MVideoPlaylistElementFormattable, accountId?: number) {
const video = this.Video
if (!video) return VideoPlaylistElementType.DELETED
if (video.privacy === VideoPrivacy.PRIVATE || video.privacy === VideoPrivacy.INTERNAL) return VideoPlaylistElementType.PRIVATE
if (video.isBlacklisted() || video.isBlocked()) return VideoPlaylistElementType.UNAVAILABLE
- if (video.nsfw === true && displayNSFW === false) return VideoPlaylistElementType.UNAVAILABLE
return VideoPlaylistElementType.REGULAR
}
- getVideoElement (this: MVideoPlaylistElementFormattable, displayNSFW?: boolean, accountId?: number) {
+ getVideoElement (this: MVideoPlaylistElementFormattable, accountId?: number) {
if (!this.Video) return null
- if (this.getType(displayNSFW, accountId) !== VideoPlaylistElementType.REGULAR) return null
+ if (this.getType(accountId) !== VideoPlaylistElementType.REGULAR) return null
return this.Video.toFormattedJSON()
}
- toFormattedJSON (
- this: MVideoPlaylistElementFormattable,
- options: { displayNSFW?: boolean, accountId?: number } = {}
- ): VideoPlaylistElement {
- return {
- id: this.id,
- position: this.position,
- startTimestamp: this.startTimestamp,
- stopTimestamp: this.stopTimestamp,
-
- type: this.getType(options.displayNSFW, options.accountId),
-
- video: this.getVideoElement(options.displayNSFW, options.accountId)
- }
- }
-
toActivityPubObject (this: MVideoPlaylistElementAP): PlaylistElementObject {
const base: PlaylistElementObject = {
id: this.url,
type: 'PlaylistElement',
- url: this.Video.url,
+ url: this.Video?.url || null,
position: this.position
}