Add notification settings migration
This commit is contained in:
parent
cef534ed53
commit
e8d246d526
|
@ -264,7 +264,6 @@ async function addVideo (req: express.Request, res: express.Response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
await federateVideoIfNeeded(video, true, t)
|
await federateVideoIfNeeded(video, true, t)
|
||||||
Notifier.Instance.notifyOnNewVideo(video)
|
|
||||||
|
|
||||||
auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON()))
|
auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON()))
|
||||||
logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid)
|
logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid)
|
||||||
|
@ -272,6 +271,8 @@ async function addVideo (req: express.Request, res: express.Response) {
|
||||||
return videoCreated
|
return videoCreated
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Notifier.Instance.notifyOnNewVideo(videoCreated)
|
||||||
|
|
||||||
if (video.state === VideoState.TO_TRANSCODE) {
|
if (video.state === VideoState.TO_TRANSCODE) {
|
||||||
// Put uuid because we don't have id auto incremented for now
|
// Put uuid because we don't have id auto incremented for now
|
||||||
const dataInput = {
|
const dataInput = {
|
||||||
|
@ -311,10 +312,8 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await sequelizeTypescript.transaction(async t => {
|
const videoInstanceUpdated = await sequelizeTypescript.transaction(async t => {
|
||||||
const sequelizeOptions = {
|
const sequelizeOptions = { transaction: t }
|
||||||
transaction: t
|
|
||||||
}
|
|
||||||
const oldVideoChannel = videoInstance.VideoChannel
|
const oldVideoChannel = videoInstance.VideoChannel
|
||||||
|
|
||||||
if (videoInfoToUpdate.name !== undefined) videoInstance.set('name', videoInfoToUpdate.name)
|
if (videoInfoToUpdate.name !== undefined) videoInstance.set('name', videoInfoToUpdate.name)
|
||||||
|
@ -367,17 +366,19 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
||||||
const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE
|
const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE
|
||||||
await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t)
|
await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t)
|
||||||
|
|
||||||
if (wasUnlistedVideo || wasPrivateVideo) {
|
|
||||||
Notifier.Instance.notifyOnNewVideo(videoInstanceUpdated)
|
|
||||||
}
|
|
||||||
|
|
||||||
auditLogger.update(
|
auditLogger.update(
|
||||||
getAuditIdFromRes(res),
|
getAuditIdFromRes(res),
|
||||||
new VideoAuditView(videoInstanceUpdated.toFormattedDetailsJSON()),
|
new VideoAuditView(videoInstanceUpdated.toFormattedDetailsJSON()),
|
||||||
oldVideoAuditView
|
oldVideoAuditView
|
||||||
)
|
)
|
||||||
logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid)
|
logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid)
|
||||||
|
|
||||||
|
return videoInstanceUpdated
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (wasUnlistedVideo || wasPrivateVideo) {
|
||||||
|
Notifier.Instance.notifyOnNewVideo(videoInstanceUpdated)
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Force fields we want to update
|
// Force fields we want to update
|
||||||
// If the transaction is retried, sequelize will think the object has not changed
|
// If the transaction is retried, sequelize will think the object has not changed
|
||||||
|
|
|
@ -16,7 +16,7 @@ let config: IConfig = require('config')
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const LAST_MIGRATION_VERSION = 310
|
const LAST_MIGRATION_VERSION = 315
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import * as Sequelize from 'sequelize'
|
||||||
|
|
||||||
|
async function up (utils: {
|
||||||
|
transaction: Sequelize.Transaction,
|
||||||
|
queryInterface: Sequelize.QueryInterface,
|
||||||
|
sequelize: Sequelize.Sequelize
|
||||||
|
}): Promise<void> {
|
||||||
|
|
||||||
|
{
|
||||||
|
const query = `
|
||||||
|
CREATE TABLE IF NOT EXISTS "userNotificationSetting" ("id" SERIAL,
|
||||||
|
"newVideoFromSubscription" INTEGER NOT NULL DEFAULT NULL,
|
||||||
|
"newCommentOnMyVideo" INTEGER NOT NULL DEFAULT NULL,
|
||||||
|
"videoAbuseAsModerator" INTEGER NOT NULL DEFAULT NULL,
|
||||||
|
"blacklistOnMyVideo" INTEGER NOT NULL DEFAULT NULL,
|
||||||
|
"userId" INTEGER REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
"createdAt" TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
|
"updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
|
PRIMARY KEY ("id"))
|
||||||
|
`
|
||||||
|
await utils.sequelize.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const query = 'INSERT INTO "userNotificationSetting" ' +
|
||||||
|
'("newVideoFromSubscription", "newCommentOnMyVideo", "videoAbuseAsModerator", "blacklistOnMyVideo", ' +
|
||||||
|
'"userId", "createdAt", "updatedAt") ' +
|
||||||
|
'(SELECT 2, 2, 4, 4, id, NOW(), NOW() FROM "user")'
|
||||||
|
|
||||||
|
await utils.sequelize.query(query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function down (options) {
|
||||||
|
throw new Error('Not implemented.')
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
up,
|
||||||
|
down
|
||||||
|
}
|
|
@ -204,19 +204,17 @@ async function updateVideoFromAP (options: {
|
||||||
overrideTo?: string[]
|
overrideTo?: string[]
|
||||||
}) {
|
}) {
|
||||||
logger.debug('Updating remote video "%s".', options.videoObject.uuid)
|
logger.debug('Updating remote video "%s".', options.videoObject.uuid)
|
||||||
|
|
||||||
let videoFieldsSave: any
|
let videoFieldsSave: any
|
||||||
|
const wasPrivateVideo = options.video.privacy === VideoPrivacy.PRIVATE
|
||||||
|
const wasUnlistedVideo = options.video.privacy === VideoPrivacy.UNLISTED
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(async t => {
|
||||||
const sequelizeOptions = {
|
const sequelizeOptions = { transaction: t }
|
||||||
transaction: t
|
|
||||||
}
|
|
||||||
|
|
||||||
videoFieldsSave = options.video.toJSON()
|
videoFieldsSave = options.video.toJSON()
|
||||||
|
|
||||||
const wasPrivateVideo = options.video.privacy === VideoPrivacy.PRIVATE
|
|
||||||
const wasUnlistedVideo = options.video.privacy === VideoPrivacy.UNLISTED
|
|
||||||
|
|
||||||
// Check actor has the right to update the video
|
// Check actor has the right to update the video
|
||||||
const videoChannel = options.video.VideoChannel
|
const videoChannel = options.video.VideoChannel
|
||||||
if (videoChannel.Account.id !== options.account.id) {
|
if (videoChannel.Account.id !== options.account.id) {
|
||||||
|
@ -281,15 +279,13 @@ async function updateVideoFromAP (options: {
|
||||||
})
|
})
|
||||||
options.video.VideoCaptions = await Promise.all(videoCaptionsPromises)
|
options.video.VideoCaptions = await Promise.all(videoCaptionsPromises)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
// Notify our users?
|
|
||||||
if (wasPrivateVideo || wasUnlistedVideo) {
|
|
||||||
Notifier.Instance.notifyOnNewVideo(options.video)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Notify our users?
|
||||||
|
if (wasPrivateVideo || wasUnlistedVideo) {
|
||||||
|
Notifier.Instance.notifyOnNewVideo(options.video)
|
||||||
|
}
|
||||||
|
|
||||||
logger.info('Remote video with uuid %s updated', options.videoObject.uuid)
|
logger.info('Remote video with uuid %s updated', options.videoObject.uuid)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (options.video !== undefined && videoFieldsSave !== undefined) {
|
if (options.video !== undefined && videoFieldsSave !== undefined) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as Bull from 'bull'
|
import * as Bull from 'bull'
|
||||||
import { VideoResolution, VideoState, Job } from '../../../../shared'
|
import { VideoResolution, VideoState } from '../../../../shared'
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { VideoModel } from '../../../models/video/video'
|
import { VideoModel } from '../../../models/video/video'
|
||||||
import { JobQueue } from '../job-queue'
|
import { JobQueue } from '../job-queue'
|
||||||
|
@ -8,7 +8,7 @@ import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
||||||
import { sequelizeTypescript } from '../../../initializers'
|
import { sequelizeTypescript } from '../../../initializers'
|
||||||
import * as Bluebird from 'bluebird'
|
import * as Bluebird from 'bluebird'
|
||||||
import { computeResolutionsToTranscode } from '../../../helpers/ffmpeg-utils'
|
import { computeResolutionsToTranscode } from '../../../helpers/ffmpeg-utils'
|
||||||
import { importVideoFile, transcodeOriginalVideofile, optimizeVideofile } from '../../video-transcoding'
|
import { importVideoFile, optimizeVideofile, transcodeOriginalVideofile } from '../../video-transcoding'
|
||||||
import { Notifier } from '../../notifier'
|
import { Notifier } from '../../notifier'
|
||||||
|
|
||||||
export type VideoFilePayload = {
|
export type VideoFilePayload = {
|
||||||
|
@ -68,7 +68,7 @@ async function processVideoFile (job: Bull.Job) {
|
||||||
async function onVideoFileTranscoderOrImportSuccess (video: VideoModel) {
|
async function onVideoFileTranscoderOrImportSuccess (video: VideoModel) {
|
||||||
if (video === undefined) return undefined
|
if (video === undefined) return undefined
|
||||||
|
|
||||||
return sequelizeTypescript.transaction(async t => {
|
const { videoDatabase, isNewVideo } = await sequelizeTypescript.transaction(async t => {
|
||||||
// Maybe the video changed in database, refresh it
|
// Maybe the video changed in database, refresh it
|
||||||
let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
|
let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
|
||||||
// Video does not exist anymore
|
// Video does not exist anymore
|
||||||
|
@ -87,10 +87,11 @@ async function onVideoFileTranscoderOrImportSuccess (video: VideoModel) {
|
||||||
|
|
||||||
// If the video was not published, we consider it is a new one for other instances
|
// If the video was not published, we consider it is a new one for other instances
|
||||||
await federateVideoIfNeeded(videoDatabase, isNewVideo, t)
|
await federateVideoIfNeeded(videoDatabase, isNewVideo, t)
|
||||||
if (isNewVideo) Notifier.Instance.notifyOnNewVideo(video)
|
|
||||||
|
|
||||||
return undefined
|
return { videoDatabase, isNewVideo }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (isNewVideo) Notifier.Instance.notifyOnNewVideo(videoDatabase)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onVideoFileOptimizerSuccess (videoArg: VideoModel, isNewVideo: boolean) {
|
async function onVideoFileOptimizerSuccess (videoArg: VideoModel, isNewVideo: boolean) {
|
||||||
|
@ -99,7 +100,7 @@ async function onVideoFileOptimizerSuccess (videoArg: VideoModel, isNewVideo: bo
|
||||||
// Outside the transaction (IO on disk)
|
// Outside the transaction (IO on disk)
|
||||||
const { videoFileResolution } = await videoArg.getOriginalFileResolution()
|
const { videoFileResolution } = await videoArg.getOriginalFileResolution()
|
||||||
|
|
||||||
return sequelizeTypescript.transaction(async t => {
|
const videoDatabase = await sequelizeTypescript.transaction(async t => {
|
||||||
// Maybe the video changed in database, refresh it
|
// Maybe the video changed in database, refresh it
|
||||||
let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoArg.uuid, t)
|
let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoArg.uuid, t)
|
||||||
// Video does not exist anymore
|
// Video does not exist anymore
|
||||||
|
@ -137,8 +138,11 @@ async function onVideoFileOptimizerSuccess (videoArg: VideoModel, isNewVideo: bo
|
||||||
}
|
}
|
||||||
|
|
||||||
await federateVideoIfNeeded(videoDatabase, isNewVideo, t)
|
await federateVideoIfNeeded(videoDatabase, isNewVideo, t)
|
||||||
if (isNewVideo) Notifier.Instance.notifyOnNewVideo(videoDatabase)
|
|
||||||
|
return videoDatabase
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (isNewVideo) Notifier.Instance.notifyOnNewVideo(videoDatabase)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -180,12 +180,11 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
|
||||||
// Update video DB object
|
// Update video DB object
|
||||||
video.duration = duration
|
video.duration = duration
|
||||||
video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED
|
video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED
|
||||||
const videoUpdated = await video.save({ transaction: t })
|
await video.save({ transaction: t })
|
||||||
|
|
||||||
// Now we can federate the video (reload from database, we need more attributes)
|
// Now we can federate the video (reload from database, we need more attributes)
|
||||||
const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
|
const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
|
||||||
await federateVideoIfNeeded(videoForFederation, true, t)
|
await federateVideoIfNeeded(videoForFederation, true, t)
|
||||||
Notifier.Instance.notifyOnNewVideo(videoForFederation)
|
|
||||||
|
|
||||||
// Update video import object
|
// Update video import object
|
||||||
videoImport.state = VideoImportState.SUCCESS
|
videoImport.state = VideoImportState.SUCCESS
|
||||||
|
@ -193,10 +192,12 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
|
||||||
|
|
||||||
logger.info('Video %s imported.', video.uuid)
|
logger.info('Video %s imported.', video.uuid)
|
||||||
|
|
||||||
videoImportUpdated.Video = videoUpdated
|
videoImportUpdated.Video = videoForFederation
|
||||||
return videoImportUpdated
|
return videoImportUpdated
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Notifier.Instance.notifyOnNewVideo(videoImportUpdated.Video)
|
||||||
|
|
||||||
// Create transcoding jobs?
|
// Create transcoding jobs?
|
||||||
if (videoImportUpdated.Video.state === VideoState.TO_TRANSCODE) {
|
if (videoImportUpdated.Video.state === VideoState.TO_TRANSCODE) {
|
||||||
// Put uuid because we don't have id auto incremented for now
|
// Put uuid because we don't have id auto incremented for now
|
||||||
|
|
|
@ -152,6 +152,8 @@ describe('Test users notifications', function () {
|
||||||
const videoName = 'remote video ' + videoNameId
|
const videoName = 'remote video ' + videoNameId
|
||||||
|
|
||||||
const uuid = await uploadVideoByRemoteAccount(servers, videoNameId)
|
const uuid = await uploadVideoByRemoteAccount(servers, videoNameId)
|
||||||
|
await waitJobs(servers)
|
||||||
|
|
||||||
await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
|
await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -194,6 +196,7 @@ describe('Test users notifications', function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
|
const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
|
||||||
|
await waitJobs(servers)
|
||||||
|
|
||||||
await wait(6000)
|
await wait(6000)
|
||||||
await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
|
await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
|
||||||
|
@ -245,6 +248,7 @@ describe('Test users notifications', function () {
|
||||||
|
|
||||||
const data = { privacy: VideoPrivacy.PRIVATE }
|
const data = { privacy: VideoPrivacy.PRIVATE }
|
||||||
const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
|
const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
|
||||||
|
await waitJobs(servers)
|
||||||
|
|
||||||
await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
|
await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
|
||||||
|
|
||||||
|
@ -276,6 +280,7 @@ describe('Test users notifications', function () {
|
||||||
|
|
||||||
const data = { privacy: VideoPrivacy.PRIVATE }
|
const data = { privacy: VideoPrivacy.PRIVATE }
|
||||||
const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
|
const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
|
||||||
|
await waitJobs(servers)
|
||||||
|
|
||||||
await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
|
await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue