} from 'sequelize-typescript'
import * as Sequelize from 'sequelize'
import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
-import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getSort, throwIfNotValid } from '../utils'
+import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getSort, isOutdated, throwIfNotValid } from '../utils'
import {
isVideoPlaylistDescriptionValid,
isVideoPlaylistNameValid,
} from '../../helpers/custom-validators/video-playlists'
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
import {
- CONFIG,
+ ACTIVITY_PUB,
CONSTRAINTS_FIELDS,
STATIC_PATHS,
THUMBNAILS_SIZE,
VIDEO_PLAYLIST_PRIVACIES,
- VIDEO_PLAYLIST_TYPES
-} from '../../initializers'
+ VIDEO_PLAYLIST_TYPES,
+ WEBSERVER
+} from '../../initializers/constants'
import { VideoPlaylist } from '../../../shared/models/videos/playlist/video-playlist.model'
import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account'
import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel'
import { remove } from 'fs-extra'
import { logger } from '../../helpers/logger'
import { VideoPlaylistType } from '../../../shared/models/videos/playlist/video-playlist-type.model'
+import { CONFIG } from '../../initializers/config'
enum ScopeNames {
AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST',
WITH_VIDEOS_LENGTH = 'WITH_VIDEOS_LENGTH',
WITH_ACCOUNT_AND_CHANNEL_SUMMARY = 'WITH_ACCOUNT_AND_CHANNEL_SUMMARY',
- WITH_ACCOUNT = 'WITH_ACCOUNT'
+ WITH_ACCOUNT = 'WITH_ACCOUNT',
+ WITH_ACCOUNT_AND_CHANNEL = 'WITH_ACCOUNT_AND_CHANNEL'
}
type AvailableForListOptions = {
}
]
},
+ [ ScopeNames.WITH_ACCOUNT_AND_CHANNEL ]: {
+ include: [
+ {
+ model: () => AccountModel,
+ required: true
+ },
+ {
+ model: () => VideoChannelModel,
+ required: false
+ }
+ ]
+ },
[ ScopeNames.AVAILABLE_FOR_LIST ]: (options: AvailableForListOptions) => {
// Only list local playlists OR playlists that are on an instance followed by actorId
const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId)
})
}
- static listUrlsOfForAP (accountId: number, start: number, count: number) {
+ static listPublicUrlsOfForAP (accountId: number, start: number, count: number) {
const query = {
attributes: [ 'url' ],
offset: start,
limit: count,
where: {
- ownerAccountId: accountId
+ ownerAccountId: accountId,
+ privacy: VideoPlaylistPrivacy.PUBLIC
}
}
})
}
+ static listPlaylistIdsOf (accountId: number, videoIds: number[]) {
+ const query = {
+ attributes: [ 'id' ],
+ where: {
+ ownerAccountId: accountId
+ },
+ include: [
+ {
+ attributes: [ 'videoId', 'startTimestamp', 'stopTimestamp' ],
+ model: VideoPlaylistElementModel.unscoped(),
+ where: {
+ videoId: {
+ [Sequelize.Op.any]: videoIds
+ }
+ },
+ required: true
+ }
+ ]
+ }
+
+ return VideoPlaylistModel.findAll(query)
+ }
+
static doesPlaylistExist (url: string) {
const query = {
attributes: [],
.then(e => !!e)
}
- static loadWithAccountAndChannel (id: number | string, transaction: Sequelize.Transaction) {
+ static loadWithAccountAndChannelSummary (id: number | string, transaction: Sequelize.Transaction) {
const where = buildWhereIdOrUUID(id)
const query = {
.findOne(query)
}
+ static loadWithAccountAndChannel (id: number | string, transaction: Sequelize.Transaction) {
+ const where = buildWhereIdOrUUID(id)
+
+ const query = {
+ where,
+ transaction
+ }
+
+ return VideoPlaylistModel
+ .scope([ ScopeNames.WITH_ACCOUNT_AND_CHANNEL, ScopeNames.WITH_VIDEOS_LENGTH ])
+ .findOne(query)
+ }
+
static loadByUrlAndPopulateAccount (url: string) {
const query = {
where: {
}
getThumbnailUrl () {
- return CONFIG.WEBSERVER.URL + STATIC_PATHS.THUMBNAILS + this.getThumbnailName()
+ return WEBSERVER.URL + STATIC_PATHS.THUMBNAILS + this.getThumbnailName()
}
getThumbnailStaticPath () {
.catch(err => logger.warn('Cannot delete thumbnail %s.', thumbnailPath, { err }))
}
+ setAsRefreshed () {
+ this.changed('updatedAt', true)
+
+ return this.save()
+ }
+
isOwned () {
return this.OwnerAccount.isOwned()
}
+ isOutdated () {
+ if (this.isOwned()) return false
+
+ return isOutdated(this, ACTIVITY_PUB.VIDEO_PLAYLIST_REFRESH_INTERVAL)
+ }
+
toFormattedJSON (): VideoPlaylist {
return {
id: this.id,