Update channel updatedAt when uploading a video

pull/4107/head
Chocobozzz 2021-05-07 17:14:39 +02:00
parent 1e0741d165
commit e024fd6a74
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
12 changed files with 95 additions and 38 deletions

View File

@ -248,6 +248,9 @@ async function addVideo (req: express.Request, res: express.Response) {
}, { transaction: t })
}
// Channel has a new content, set as updated
await videoCreated.VideoChannel.setAsUpdated(t)
await autoBlacklistVideoIfNeeded({
video,
user: res.locals.oauth.token.User,

View File

@ -1,8 +1,9 @@
import * as retry from 'async/retry'
import * as Bluebird from 'bluebird'
import { QueryTypes, Transaction } from 'sequelize'
import { Model } from 'sequelize-typescript'
import { sequelizeTypescript } from '@server/initializers/database'
import { logger } from './logger'
import { Transaction } from 'sequelize'
function retryTransactionWrapper <T, A, B, C, D> (
functionToRetry: (arg1: A, arg2: B, arg3: C, arg4: D) => Promise<T> | Bluebird<T>,
@ -96,6 +97,18 @@ function deleteNonExistingModels <T extends { hasSameUniqueKeysThan (other: T):
.map(f => f.destroy({ transaction: t }))
}
// Sequelize always skip the update if we only update updatedAt field
function setAsUpdated (table: string, id: number, transaction?: Transaction) {
return sequelizeTypescript.query(
`UPDATE "${table}" SET "updatedAt" = :updatedAt WHERE id = :id`,
{
replacements: { table, id, updatedAt: new Date() },
type: QueryTypes.UPDATE,
transaction
}
)
}
// ---------------------------------------------------------------------------
export {
@ -104,5 +117,6 @@ export {
transactionRetryer,
updateInstanceWithAnother,
afterCommitIfTransaction,
deleteNonExistingModels
deleteNonExistingModels,
setAsUpdated
}

View File

@ -154,8 +154,6 @@ async function updateActorInstance (actorInstance: ActorModel, attributes: Activ
const followersCount = await fetchActorTotalItems(attributes.followers)
const followingCount = await fetchActorTotalItems(attributes.following)
logger.info('coucou', { attributes })
actorInstance.type = attributes.type
actorInstance.preferredUsername = attributes.preferredUsername
actorInstance.url = attributes.id

View File

@ -697,6 +697,9 @@ async function createVideo (videoObject: VideoObject, channel: MChannelAccountLi
videoCreated.VideoLive = await videoLive.save({ transaction: t })
}
// We added a video in this channel, set it as updated
await channel.setAsUpdated(t)
const autoBlacklisted = await autoBlacklistVideoIfNeeded({
video: videoCreated,
user: undefined,

View File

@ -411,6 +411,7 @@ export class AccountModel extends Model {
id: this.id,
displayName: this.getDisplayName(),
description: this.description,
updatedAt: this.updatedAt,
userId: this.userId ? this.userId : undefined
}

View File

@ -557,8 +557,7 @@ export class ActorModel extends Model {
followingCount: this.followingCount,
followersCount: this.followersCount,
banner,
createdAt: this.getCreatedAt(),
updatedAt: this.updatedAt
createdAt: this.getCreatedAt()
})
}

View File

@ -1,4 +1,4 @@
import { FindOptions, Includeable, literal, Op, QueryTypes, ScopeOptions } from 'sequelize'
import { FindOptions, Includeable, literal, Op, QueryTypes, ScopeOptions, Transaction } from 'sequelize'
import {
AllowNull,
BeforeDestroy,
@ -17,6 +17,7 @@ import {
Table,
UpdatedAt
} from 'sequelize-typescript'
import { setAsUpdated } from '@server/helpers/database-utils'
import { MAccountActor } from '@server/types/models'
import { ActivityPubActor } from '../../../shared/models/activitypub'
import { VideoChannel, VideoChannelSummary } from '../../../shared/models/videos'
@ -653,6 +654,7 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`
description: this.description,
support: this.support,
isLocal: this.Actor.isOwned(),
updatedAt: this.updatedAt,
ownerAccount: undefined,
videosCount,
viewsPerDay
@ -689,4 +691,8 @@ ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"`
isOutdated () {
return this.Actor.isOutdated()
}
setAsUpdated (transaction: Transaction) {
return setAsUpdated('videoChannel', this.id, transaction)
}
}

View File

@ -24,6 +24,7 @@ import {
Table,
UpdatedAt
} from 'sequelize-typescript'
import { setAsUpdated } from '@server/helpers/database-utils'
import { buildNSFWFilter } from '@server/helpers/express-utils'
import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video'
import { LiveManager } from '@server/lib/live-manager'
@ -2053,11 +2054,7 @@ export class VideoModel extends Model {
}
setAsRefreshed () {
const options = {
where: { id: this.id }
}
return VideoModel.update({ updatedAt: new Date() }, options)
return setAsUpdated('video', this.id)
}
requiresAuth () {

View File

@ -3,6 +3,7 @@
import 'mocha'
import * as chai from 'chai'
import { basename } from 'path'
import { ACTOR_IMAGES_SIZE } from '@server/initializers/constants'
import {
cleanupTests,
createUser,
@ -13,6 +14,7 @@ import {
getVideo,
getVideoChannel,
getVideoChannelVideos,
setDefaultVideoChannel,
testImage,
updateVideo,
updateVideoChannelImage,
@ -33,7 +35,6 @@ import {
} from '../../../../shared/extra-utils/index'
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
import { User, Video, VideoChannel, VideoDetails } from '../../../../shared/index'
import { ACTOR_IMAGES_SIZE } from '@server/initializers/constants'
const expect = chai.expect
@ -47,9 +48,10 @@ async function findChannel (server: ServerInfo, channelId: number) {
describe('Test video channels', function () {
let servers: ServerInfo[]
let userInfo: User
let firstVideoChannelId: number
let secondVideoChannelId: number
let totoChannel: number
let videoUUID: string
let accountName: string
before(async function () {
this.timeout(60000)
@ -57,16 +59,9 @@ describe('Test video channels', function () {
servers = await flushAndRunMultipleServers(2)
await setAccessTokensToServers(servers)
await setDefaultVideoChannel(servers)
await doubleFollow(servers[0], servers[1])
{
const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
const user: User = res.body
firstVideoChannelId = user.videoChannels[0].id
}
await waitJobs(servers)
})
it('Should have one video channel (created with root)', async () => {
@ -116,12 +111,14 @@ describe('Test video channels', function () {
expect(videoChannels[1].displayName).to.equal('second video channel')
expect(videoChannels[1].description).to.equal('super video channel description')
expect(videoChannels[1].support).to.equal('super video channel support text')
accountName = userInfo.account.name + '@' + userInfo.account.host
})
it('Should have two video channels when getting account channels on server 1', async function () {
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host
accountName
})
expect(res.body.total).to.equal(2)
@ -142,7 +139,7 @@ describe('Test video channels', function () {
{
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host,
accountName,
start: 0,
count: 1,
sort: 'createdAt'
@ -158,7 +155,7 @@ describe('Test video channels', function () {
{
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host,
accountName,
start: 0,
count: 1,
sort: '-createdAt'
@ -174,7 +171,7 @@ describe('Test video channels', function () {
{
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host,
accountName,
start: 1,
count: 1,
sort: '-createdAt'
@ -191,7 +188,7 @@ describe('Test video channels', function () {
it('Should have one video channel when getting account channels on server 2', async function () {
const res = await getAccountVideoChannelsList({
url: servers[1].url,
accountName: userInfo.account.name + '@' + userInfo.account.host
accountName
})
expect(res.body.total).to.equal(1)
@ -379,7 +376,7 @@ describe('Test video channels', function () {
it('Should change the video channel of a video', async function () {
this.timeout(10000)
await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { channelId: firstVideoChannelId })
await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { channelId: servers[0].videoChannel.id })
await waitJobs(servers)
})
@ -419,7 +416,8 @@ describe('Test video channels', function () {
it('Should create the main channel with an uuid if there is a conflict', async function () {
{
const videoChannel = { name: 'toto_channel', displayName: 'My toto channel' }
await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel)
const res = await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel)
totoChannel = res.body.videoChannel.id
}
{
@ -438,7 +436,7 @@ describe('Test video channels', function () {
{
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host,
accountName,
withStats: true
})
@ -456,7 +454,7 @@ describe('Test video channels', function () {
}
{
// video has been posted on channel firstVideoChannelId since last update
// video has been posted on channel servers[0].videoChannel.id since last update
await viewVideo(servers[0].url, videoUUID, 204, '0.0.0.1,127.0.0.1')
await viewVideo(servers[0].url, videoUUID, 204, '0.0.0.2,127.0.0.1')
@ -465,10 +463,10 @@ describe('Test video channels', function () {
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host,
accountName,
withStats: true
})
const channelWithView = res.body.data.find((channel: VideoChannel) => channel.id === firstVideoChannelId)
const channelWithView = res.body.data.find((channel: VideoChannel) => channel.id === servers[0].videoChannel.id)
expect(channelWithView.viewsPerDay.slice(-1)[0].views).to.equal(2)
}
})
@ -476,7 +474,7 @@ describe('Test video channels', function () {
it('Should report correct videos count', async function () {
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host,
accountName,
withStats: true
})
const channels: VideoChannel[] = res.body.data
@ -492,7 +490,7 @@ describe('Test video channels', function () {
{
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host,
accountName,
search: 'root'
})
expect(res.body.total).to.equal(1)
@ -504,7 +502,7 @@ describe('Test video channels', function () {
{
const res = await getAccountVideoChannelsList({
url: servers[0].url,
accountName: userInfo.account.name + '@' + userInfo.account.host,
accountName,
search: 'does not exist'
})
expect(res.body.total).to.equal(0)
@ -514,6 +512,40 @@ describe('Test video channels', function () {
}
})
it('Should list channels by updatedAt desc if a video has been uploaded', async function () {
this.timeout(30000)
await uploadVideo(servers[0].url, servers[0].accessToken, { channelId: totoChannel })
await waitJobs(servers)
for (const server of servers) {
const res = await getAccountVideoChannelsList({
url: server.url,
accountName,
sort: '-updatedAt'
})
const channels: VideoChannel[] = res.body.data
expect(channels[0].name).to.equal('toto_channel')
expect(channels[1].name).to.equal('root_channel')
}
await uploadVideo(servers[0].url, servers[0].accessToken, { channelId: servers[0].videoChannel.id })
await waitJobs(servers)
for (const server of servers) {
const res = await getAccountVideoChannelsList({
url: server.url,
accountName,
sort: '-updatedAt'
})
const channels: VideoChannel[] = res.body.data
expect(channels[0].name).to.equal('root_channel')
expect(channels[1].name).to.equal('toto_channel')
}
})
after(async function () {
await cleanupTests(servers)
})

View File

@ -5,6 +5,8 @@ export interface Account extends Actor {
displayName: string
description: string
updatedAt: Date | string
userId?: number
}

View File

@ -8,6 +8,5 @@ export interface Actor {
followingCount: number
followersCount: number
createdAt: Date | string
updatedAt: Date | string
avatar?: ActorImage
}

View File

@ -11,6 +11,9 @@ export interface VideoChannel extends Actor {
description: string
support: string
isLocal: boolean
updatedAt: Date | string
ownerAccount?: Account
videosCount?: number