Add notification settings migration

This commit is contained in:
Chocobozzz 2018-12-28 13:47:17 +01:00 committed by Chocobozzz
parent cef534ed53
commit e8d246d526
7 changed files with 81 additions and 33 deletions

View File

@ -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

View File

@ -16,7 +16,7 @@ let config: IConfig = require('config')
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const LAST_MIGRATION_VERSION = 310 const LAST_MIGRATION_VERSION = 315
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -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
}

View File

@ -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) {

View File

@ -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)
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -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

View File

@ -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 })