async function run () {
await initDatabaseModels(true)
- const video = await VideoModel.loadByUUID(program['video'])
+ const video = await VideoModel.loadByUUIDWithFile(program['video'])
if (!video) throw new Error('Video not found.')
if (video.isOwned() === false) throw new Error('Cannot import files of a non owned video.')
async function run () {
await initDatabaseModels(true)
- const video = await VideoModel.loadByUUID(program['video'])
+ const video = await VideoModel.loadByUUIDWithFile(program['video'])
if (!video) throw new Error('Video not found.')
const dataInput = {
const uuid = getUUIDFromFilename(file)
let video: VideoModel
- if (uuid) video = await VideoModel.loadByUUID(uuid)
+ if (uuid) video = await VideoModel.loadByUUIDWithFile(uuid)
if (!uuid || !video) toDelete.push(join(directory, file))
}
}
async function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {
- const videoId = +req.params.videoId
+ const videoId = res.locals.video.id
const accountId = +res.locals.oauth.token.User.Account.id
const ratingObj = await AccountVideoRateModel.load(accountId, videoId, null)
let resultList: ResultList<VideoCommentModel>
if (video.commentsEnabled === true) {
- resultList = await VideoCommentModel.listThreadCommentsForApi(res.locals.video.id, res.locals.videoCommentThread.id)
+ resultList = await VideoCommentModel.listThreadCommentsForApi(video.id, res.locals.videoCommentThread.id)
} else {
resultList = {
total: 0,
return true
}
-async function isVideoExist (id: string, res: Response) {
+async function isVideoExist (id: string, res: Response, fetchType: 'all' | 'only-video' | 'id' | 'none' = 'all') {
let video: VideoModel | null
- if (validator.isInt(id)) {
- video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
- } else { // UUID
- video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
+ if (fetchType === 'all') {
+ video = await VideoModel.loadAndPopulateAccountAndServerAndTags(id)
+ } else if (fetchType === 'only-video') {
+ video = await VideoModel.load(id)
+ } else if (fetchType === 'id' || fetchType === 'none') {
+ video = await VideoModel.loadOnlyId(id)
}
if (video === null) {
return false
}
- res.locals.video = video
+ if (fetchType !== 'none') res.locals.video = video
return true
}
if (videoCaption.isOwned()) throw new Error('Cannot load remote caption of owned video.')
// Used to fetch the path
- const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(videoId)
+ const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId)
if (!video) return undefined
const remoteStaticPath = videoCaption.getCaptionStaticPath()
}
async getFilePath (videoUUID: string) {
- const video = await VideoModel.loadByUUID(videoUUID)
+ const video = await VideoModel.loadByUUIDWithFile(videoUUID)
if (!video) return undefined
if (video.isOwned()) return join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName())
}
protected async loadRemoteFile (key: string) {
- const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(key)
+ const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(key)
if (!video) return undefined
if (video.isOwned()) throw new Error('Cannot load remote preview of owned video.')
let videoPromise: Bluebird<VideoModel>
// Let Angular application handle errors
- if (validator.isUUID(videoId, 4)) {
- videoPromise = VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(videoId)
- } else if (validator.isInt(videoId)) {
- videoPromise = VideoModel.loadAndPopulateAccountAndServerAndTags(+videoId)
+ if (validator.isInt(videoId) || validator.isUUID(videoId, 4)) {
+ videoPromise = VideoModel.loadAndPopulateAccountAndServerAndTags(videoId)
} else {
return ClientHtml.getIndexHTML(req, res)
}
const payload = job.data as VideoFileImportPayload
logger.info('Processing video file import in job %d.', job.id)
- const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(payload.videoUUID)
+ const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(payload.videoUUID)
// No video, maybe deleted?
if (!video) {
logger.info('Do not process job %d, video does not exist.', job.id)
const payload = job.data as VideoFilePayload
logger.info('Processing video file in job %d.', job.id)
- const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(payload.videoUUID)
+ const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(payload.videoUUID)
// No video, maybe deleted?
if (!video) {
logger.info('Do not process job %d, video does not exist.', job.id)
return sequelizeTypescript.transaction(async t => {
// Maybe the video changed in database, refresh it
- let videoDatabase = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid, t)
+ let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
// Video does not exist anymore
if (!videoDatabase) return undefined
return sequelizeTypescript.transaction(async t => {
// Maybe the video changed in database, refresh it
- const videoDatabase = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid, t)
+ const videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
// Video does not exist anymore
if (!videoDatabase) return undefined
const videoUpdated = await video.save({ transaction: t })
// Now we can federate the video (reload from database, we need more attributes)
- const videoForFederation = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid, t)
+ const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
await federateVideoIfNeeded(videoForFederation, true, t)
// Update video import object
logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
if (areValidationErrors(req, res)) return
- if (!await isVideoExist(req.params.videoId, res)) return
+ if (!await isVideoExist(req.params.videoId, res, 'id')) return
return next()
}
logger.debug('Checking listVideoCaptions parameters', { parameters: req.params })
if (areValidationErrors(req, res)) return
- if (!await isVideoExist(req.params.videoId, res)) return
+ if (!await isVideoExist(req.params.videoId, res, 'id')) return
return next()
}
logger.debug('Checking listVideoCommentThreads parameters.', { parameters: req.params })
if (areValidationErrors(req, res)) return
- if (!await isVideoExist(req.params.videoId, res)) return
+ if (!await isVideoExist(req.params.videoId, res, 'only-video')) return
return next()
}
logger.debug('Checking listVideoThreadComments parameters.', { parameters: req.params })
if (areValidationErrors(req, res)) return
- if (!await isVideoExist(req.params.videoId, res)) return
+ if (!await isVideoExist(req.params.videoId, res, 'only-video')) return
if (!await isVideoCommentThreadExist(req.params.threadId, res.locals.video, res)) return
return next()
videoModelToFormattedDetailsJSON,
videoModelToFormattedJSON
} from './video-format-utils'
+import * as validator from 'validator'
// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
const indexes: Sequelize.DefineIndexesOptions[] = [
required: false,
include: [
{
+ attributes: [ 'fileUrl' ],
model: () => VideoRedundancyModel.unscoped(),
required: false
}
return VideoModel.getAvailableForApi(query, queryOptions)
}
- static load (id: number, t?: Sequelize.Transaction) {
- return VideoModel.findById(id, { transaction: t })
- }
-
- static loadWithFile (id: number, t?: Sequelize.Transaction, logging?: boolean) {
- return VideoModel.scope(ScopeNames.WITH_FILES)
- .findById(id, { transaction: t, logging })
- }
-
- static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) {
- const query: IFindOptions<VideoModel> = {
- where: {
- url
- }
+ static load (id: number | string, t?: Sequelize.Transaction) {
+ const where = VideoModel.buildWhereIdOrUUID(id)
+ const options = {
+ where,
+ transaction: t
}
- if (t !== undefined) query.transaction = t
-
- return VideoModel.scope([ ScopeNames.WITH_ACCOUNT_DETAILS, ScopeNames.WITH_FILES ]).findOne(query)
+ return VideoModel.findOne(options)
}
- static loadAndPopulateAccountAndServerAndTags (id: number) {
+ static loadOnlyId (id: number | string, t?: Sequelize.Transaction) {
+ const where = VideoModel.buildWhereIdOrUUID(id)
+
const options = {
- order: [ [ 'Tags', 'name', 'ASC' ] ]
+ attributes: [ 'id' ],
+ where,
+ transaction: t
}
- return VideoModel
- .scope([
- ScopeNames.WITH_TAGS,
- ScopeNames.WITH_BLACKLISTED,
- ScopeNames.WITH_FILES,
- ScopeNames.WITH_ACCOUNT_DETAILS,
- ScopeNames.WITH_SCHEDULED_UPDATE
- ])
- .findById(id, options)
+ return VideoModel.findOne(options)
+ }
+
+ static loadWithFile (id: number, t?: Sequelize.Transaction, logging?: boolean) {
+ return VideoModel.scope(ScopeNames.WITH_FILES)
+ .findById(id, { transaction: t, logging })
}
- static loadByUUID (uuid: string) {
+ static loadByUUIDWithFile (uuid: string) {
const options = {
where: {
uuid
.findOne(options)
}
- static loadByUUIDAndPopulateAccountAndServerAndTags (uuid: string, t?: Sequelize.Transaction) {
+ static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) {
+ const query: IFindOptions<VideoModel> = {
+ where: {
+ url
+ }
+ }
+
+ if (t !== undefined) query.transaction = t
+
+ return VideoModel.scope([ ScopeNames.WITH_ACCOUNT_DETAILS, ScopeNames.WITH_FILES ]).findOne(query)
+ }
+
+ static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Sequelize.Transaction) {
+ const where = VideoModel.buildWhereIdOrUUID(id)
+
const options = {
order: [ [ 'Tags', 'name', 'ASC' ] ],
- where: {
- uuid
- },
+ where,
transaction: t
}
return VIDEO_STATES[ id ] || 'Unknown'
}
+ static buildWhereIdOrUUID (id: number | string) {
+ return validator.isInt('' + id) ? { id } : { uuid: id }
+ }
+
getOriginalFile () {
if (Array.isArray(this.VideoFiles) === false) return undefined