Use sequelize scopes
This commit is contained in:
parent
94edfc3b2a
commit
d48ff09d27
|
@ -58,6 +58,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
|
||||||
this.files = hash.files
|
this.files = hash.files
|
||||||
this.channel = hash.channel
|
this.channel = hash.channel
|
||||||
this.account = hash.account
|
this.account = hash.account
|
||||||
|
this.tags = hash.tags
|
||||||
|
|
||||||
this.likesPercent = (this.likes / (this.likes + this.dislikes)) * 100
|
this.likesPercent = (this.likes / (this.likes + this.dislikes)) * 100
|
||||||
this.dislikesPercent = (this.dislikes / (this.likes + this.dislikes)) * 100
|
this.dislikesPercent = (this.dislikes / (this.likes + this.dislikes)) * 100
|
||||||
|
|
|
@ -22,7 +22,6 @@ export class Video implements VideoServerModel {
|
||||||
isLocal: boolean
|
isLocal: boolean
|
||||||
name: string
|
name: string
|
||||||
serverHost: string
|
serverHost: string
|
||||||
tags: string[]
|
|
||||||
thumbnailPath: string
|
thumbnailPath: string
|
||||||
thumbnailUrl: string
|
thumbnailUrl: string
|
||||||
previewPath: string
|
previewPath: string
|
||||||
|
@ -71,7 +70,6 @@ export class Video implements VideoServerModel {
|
||||||
this.isLocal = hash.isLocal
|
this.isLocal = hash.isLocal
|
||||||
this.name = hash.name
|
this.name = hash.name
|
||||||
this.serverHost = hash.serverHost
|
this.serverHost = hash.serverHost
|
||||||
this.tags = hash.tags
|
|
||||||
this.thumbnailPath = hash.thumbnailPath
|
this.thumbnailPath = hash.thumbnailPath
|
||||||
this.thumbnailUrl = absoluteAPIUrl + hash.thumbnailPath
|
this.thumbnailUrl = absoluteAPIUrl + hash.thumbnailPath
|
||||||
this.previewPath = hash.previewPath
|
this.previewPath = hash.previewPath
|
||||||
|
|
|
@ -78,7 +78,7 @@ const videoChannelsRemoveValidator = [
|
||||||
if (!await isVideoChannelExist(req.params.id, res)) return
|
if (!await isVideoChannelExist(req.params.id, res)) return
|
||||||
|
|
||||||
// Check if the user who did the request is able to delete the video
|
// Check if the user who did the request is able to delete the video
|
||||||
if (!checkUserCanDeleteVideoChannel(res.locals.user, res.locals.videoChannel, res)) return
|
if (!checkUserCanDeleteVideoChannel(res.locals.oauth.token.User, res.locals.videoChannel, res)) return
|
||||||
if (!await checkVideoChannelIsNotTheLastOne(res)) return
|
if (!await checkVideoChannelIsNotTheLastOne(res)) return
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
|
|
|
@ -5,12 +5,12 @@ import {
|
||||||
BeforeUpdate,
|
BeforeUpdate,
|
||||||
Column, CreatedAt,
|
Column, CreatedAt,
|
||||||
DataType,
|
DataType,
|
||||||
Default,
|
Default, DefaultScope,
|
||||||
HasMany,
|
HasMany,
|
||||||
HasOne,
|
HasOne,
|
||||||
Is,
|
Is,
|
||||||
IsEmail,
|
IsEmail,
|
||||||
Model,
|
Model, Scopes,
|
||||||
Table, UpdatedAt
|
Table, UpdatedAt
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { hasUserRight, USER_ROLE_LABELS, UserRight } from '../../../shared'
|
import { hasUserRight, USER_ROLE_LABELS, UserRight } from '../../../shared'
|
||||||
|
@ -27,6 +27,25 @@ import { getSort, throwIfNotValid } from '../utils'
|
||||||
import { VideoChannelModel } from '../video/video-channel'
|
import { VideoChannelModel } from '../video/video-channel'
|
||||||
import { AccountModel } from './account'
|
import { AccountModel } from './account'
|
||||||
|
|
||||||
|
@DefaultScope({
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
@Scopes({
|
||||||
|
withVideoChannel: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
required: true,
|
||||||
|
include: [ () => VideoChannelModel ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'user',
|
tableName: 'user',
|
||||||
indexes: [
|
indexes: [
|
||||||
|
@ -122,8 +141,7 @@ export class UserModel extends Model<UserModel> {
|
||||||
const query = {
|
const query = {
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: [ getSort(sort) ],
|
order: [ getSort(sort) ]
|
||||||
include: [ { model: AccountModel, required: true } ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return UserModel.findAndCountAll(query)
|
return UserModel.findAndCountAll(query)
|
||||||
|
@ -136,19 +154,14 @@ export class UserModel extends Model<UserModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadById (id: number) {
|
static loadById (id: number) {
|
||||||
const options = {
|
return UserModel.findById(id)
|
||||||
include: [ { model: AccountModel, required: true } ]
|
|
||||||
}
|
|
||||||
|
|
||||||
return UserModel.findById(id, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByUsername (username: string) {
|
static loadByUsername (username: string) {
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
username
|
username
|
||||||
},
|
}
|
||||||
include: [ { model: AccountModel, required: true } ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return UserModel.findOne(query)
|
return UserModel.findOne(query)
|
||||||
|
@ -158,29 +171,20 @@ export class UserModel extends Model<UserModel> {
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
username
|
username
|
||||||
},
|
}
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
required: true,
|
|
||||||
include: [ VideoChannelModel ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return UserModel.findOne(query)
|
return UserModel.scope('withVideoChannel').findOne(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByUsernameOrEmail (username: string, email: string) {
|
static loadByUsernameOrEmail (username: string, email: string) {
|
||||||
const query = {
|
const query = {
|
||||||
include: [ { model: AccountModel, required: true } ],
|
|
||||||
where: {
|
where: {
|
||||||
[ Sequelize.Op.or ]: [ { username }, { email } ]
|
[ Sequelize.Op.or ]: [ { username }, { email } ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18387
|
return UserModel.findOne(query)
|
||||||
return (UserModel as any).findOne(query)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static getOriginalVideoFileTotalFromUser (user: UserModel) {
|
private static getOriginalVideoFileTotalFromUser (user: UserModel) {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { Transaction } from 'sequelize'
|
|
||||||
import { AllowNull, Column, Default, IsInt, Model, Table } from 'sequelize-typescript'
|
import { AllowNull, Column, Default, IsInt, Model, Table } from 'sequelize-typescript'
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
|
@ -15,21 +14,4 @@ export class ApplicationModel extends Model<ApplicationModel> {
|
||||||
static countTotal () {
|
static countTotal () {
|
||||||
return ApplicationModel.count()
|
return ApplicationModel.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadMigrationVersion () {
|
|
||||||
const query = {
|
|
||||||
attributes: [ 'migrationVersion' ]
|
|
||||||
}
|
|
||||||
|
|
||||||
return ApplicationModel.findOne(query).then(data => data ? data.migrationVersion : null)
|
|
||||||
}
|
|
||||||
|
|
||||||
static updateMigrationVersion (newVersion: number, transaction: Transaction) {
|
|
||||||
const options = {
|
|
||||||
where: {},
|
|
||||||
transaction: transaction
|
|
||||||
}
|
|
||||||
|
|
||||||
return ApplicationModel.update({ migrationVersion: newVersion }, options)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { logger } from '../../helpers'
|
import { logger } from '../../helpers'
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { UserModel } from '../account/user'
|
import { UserModel } from '../account/user'
|
||||||
|
@ -15,6 +15,25 @@ export type OAuthTokenInfo = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ScopeNames {
|
||||||
|
WITH_ACCOUNT = 'WITH_ACCOUNT'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scopes({
|
||||||
|
[ScopeNames.WITH_ACCOUNT]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => UserModel,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'oAuthToken',
|
tableName: 'oAuthToken',
|
||||||
indexes: [
|
indexes: [
|
||||||
|
@ -115,21 +134,10 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> {
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
accessToken: bearerToken
|
accessToken: bearerToken
|
||||||
},
|
}
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: UserModel,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OAuthTokenModel.findOne(query).then(token => {
|
return OAuthTokenModel.scope(ScopeNames.WITH_ACCOUNT).findOne(query).then(token => {
|
||||||
if (token) token['user'] = token.User
|
if (token) token['user'] = token.User
|
||||||
|
|
||||||
return token
|
return token
|
||||||
|
@ -140,24 +148,15 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> {
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
refreshToken: refreshToken
|
refreshToken: refreshToken
|
||||||
},
|
}
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: UserModel,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OAuthTokenModel.findOne(query).then(token => {
|
return OAuthTokenModel.scope(ScopeNames.WITH_ACCOUNT)
|
||||||
token['user'] = token.User
|
.findOne(query)
|
||||||
|
.then(token => {
|
||||||
|
token['user'] = token.User
|
||||||
|
|
||||||
return token
|
return token
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,35 @@
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { VideoChannelModel } from './video-channel'
|
import { VideoChannelModel } from './video-channel'
|
||||||
|
|
||||||
|
enum ScopeNames {
|
||||||
|
FULL = 'FULL',
|
||||||
|
WITH_ACCOUNT = 'WITH_ACCOUNT'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scopes({
|
||||||
|
[ScopeNames.FULL]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: () => VideoChannelModel,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
[ScopeNames.WITH_ACCOUNT]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'videoChannelShare',
|
tableName: 'videoChannelShare',
|
||||||
indexes: [
|
indexes: [
|
||||||
|
@ -46,15 +73,11 @@ export class VideoChannelShareModel extends Model<VideoChannelShareModel> {
|
||||||
VideoChannel: VideoChannelModel
|
VideoChannel: VideoChannelModel
|
||||||
|
|
||||||
static load (accountId: number, videoChannelId: number, t: Sequelize.Transaction) {
|
static load (accountId: number, videoChannelId: number, t: Sequelize.Transaction) {
|
||||||
return VideoChannelShareModel.findOne({
|
return VideoChannelShareModel.scope(ScopeNames.FULL).findOne({
|
||||||
where: {
|
where: {
|
||||||
accountId,
|
accountId,
|
||||||
videoChannelId
|
videoChannelId
|
||||||
},
|
},
|
||||||
include: [
|
|
||||||
AccountModel,
|
|
||||||
VideoChannelModel
|
|
||||||
],
|
|
||||||
transaction: t
|
transaction: t
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -64,16 +87,10 @@ export class VideoChannelShareModel extends Model<VideoChannelShareModel> {
|
||||||
where: {
|
where: {
|
||||||
videoChannelId
|
videoChannelId
|
||||||
},
|
},
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
transaction: t
|
transaction: t
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelShareModel.findAll(query)
|
return VideoChannelShareModel.scope(ScopeNames.WITH_ACCOUNT).findAll(query)
|
||||||
.then(res => res.map(r => r.Account))
|
.then(res => res.map(r => r.Account))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
HasMany,
|
HasMany,
|
||||||
Is,
|
Is,
|
||||||
IsUUID,
|
IsUUID,
|
||||||
Model,
|
Model, Scopes,
|
||||||
Table,
|
Table,
|
||||||
UpdatedAt
|
UpdatedAt
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
|
@ -28,6 +28,26 @@ import { getSort, throwIfNotValid } from '../utils'
|
||||||
import { VideoModel } from './video'
|
import { VideoModel } from './video'
|
||||||
import { VideoChannelShareModel } from './video-channel-share'
|
import { VideoChannelShareModel } from './video-channel-share'
|
||||||
|
|
||||||
|
enum ScopeNames {
|
||||||
|
WITH_ACCOUNT = 'WITH_ACCOUNT',
|
||||||
|
WITH_VIDEOS = 'WITH_VIDEOS'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scopes({
|
||||||
|
[ScopeNames.WITH_ACCOUNT]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
include: [ { model: () => ServerModel, required: false } ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
[ScopeNames.WITH_VIDEOS]: {
|
||||||
|
include: [
|
||||||
|
() => VideoModel
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'videoChannel',
|
tableName: 'videoChannel',
|
||||||
indexes: [
|
indexes: [
|
||||||
|
@ -122,17 +142,10 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
||||||
const query = {
|
const query = {
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: [ getSort(sort) ],
|
order: [ getSort(sort) ]
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
required: true,
|
|
||||||
include: [ { model: ServerModel, required: false } ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelModel.findAndCountAll(query)
|
return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findAndCountAll(query)
|
||||||
.then(({ rows, count }) => {
|
.then(({ rows, count }) => {
|
||||||
return { total: count, data: rows }
|
return { total: count, data: rows }
|
||||||
})
|
})
|
||||||
|
@ -159,29 +172,16 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByUUID (uuid: string, t?: Sequelize.Transaction) {
|
static loadByUrl (url: string, t?: Sequelize.Transaction) {
|
||||||
const query: IFindOptions<VideoChannelModel> = {
|
const query: IFindOptions<VideoChannelModel> = {
|
||||||
where: {
|
where: {
|
||||||
uuid
|
url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t !== undefined) query.transaction = t
|
if (t !== undefined) query.transaction = t
|
||||||
|
|
||||||
return VideoChannelModel.findOne(query)
|
return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(query)
|
||||||
}
|
|
||||||
|
|
||||||
static loadByUrl (url: string, t?: Sequelize.Transaction) {
|
|
||||||
const query: IFindOptions<VideoChannelModel> = {
|
|
||||||
where: {
|
|
||||||
url
|
|
||||||
},
|
|
||||||
include: [ AccountModel ]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t !== undefined) query.transaction = t
|
|
||||||
|
|
||||||
return VideoChannelModel.findOne(query)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByUUIDOrUrl (uuid: string, url: string, t?: Sequelize.Transaction) {
|
static loadByUUIDOrUrl (uuid: string, url: string, t?: Sequelize.Transaction) {
|
||||||
|
@ -199,90 +199,39 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
||||||
return VideoChannelModel.findOne(query)
|
return VideoChannelModel.findOne(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByHostAndUUID (fromHost: string, uuid: string, t?: Sequelize.Transaction) {
|
|
||||||
const query: IFindOptions<VideoChannelModel> = {
|
|
||||||
where: {
|
|
||||||
uuid
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: ServerModel,
|
|
||||||
required: true,
|
|
||||||
where: {
|
|
||||||
host: fromHost
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t !== undefined) query.transaction = t
|
|
||||||
|
|
||||||
return VideoChannelModel.findOne(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadByIdAndAccount (id: number, accountId: number) {
|
static loadByIdAndAccount (id: number, accountId: number) {
|
||||||
const options = {
|
const options = {
|
||||||
where: {
|
where: {
|
||||||
id,
|
id,
|
||||||
accountId
|
accountId
|
||||||
},
|
}
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
include: [ { model: ServerModel, required: false } ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelModel.findOne(options)
|
return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadAndPopulateAccount (id: number) {
|
static loadAndPopulateAccount (id: number) {
|
||||||
const options = {
|
return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findById(id)
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
include: [ { model: ServerModel, required: false } ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
return VideoChannelModel.findById(id, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByUUIDAndPopulateAccount (uuid: string) {
|
static loadByUUIDAndPopulateAccount (uuid: string) {
|
||||||
const options = {
|
const options = {
|
||||||
where: {
|
where: {
|
||||||
uuid
|
uuid
|
||||||
},
|
}
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
include: [ { model: ServerModel, required: false } ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelModel.findOne(options)
|
return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadAndPopulateAccountAndVideos (id: number) {
|
static loadAndPopulateAccountAndVideos (id: number) {
|
||||||
const options = {
|
const options = {
|
||||||
include: [
|
include: [
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
include: [ { model: ServerModel, required: false } ]
|
|
||||||
},
|
|
||||||
VideoModel
|
VideoModel
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelModel.findById(id, options)
|
return VideoChannelModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ]).findById(id, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
isOwned () {
|
isOwned () {
|
||||||
|
|
|
@ -1,8 +1,35 @@
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { VideoModel } from './video'
|
import { VideoModel } from './video'
|
||||||
|
|
||||||
|
enum ScopeNames {
|
||||||
|
FULL = 'FULL',
|
||||||
|
WITH_ACCOUNT = 'WITH_ACCOUNT'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scopes({
|
||||||
|
[ScopeNames.FULL]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: () => VideoModel,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
[ScopeNames.WITH_ACCOUNT]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'videoShare',
|
tableName: 'videoShare',
|
||||||
indexes: [
|
indexes: [
|
||||||
|
@ -46,14 +73,11 @@ export class VideoShareModel extends Model<VideoShareModel> {
|
||||||
Video: VideoModel
|
Video: VideoModel
|
||||||
|
|
||||||
static load (accountId: number, videoId: number, t: Sequelize.Transaction) {
|
static load (accountId: number, videoId: number, t: Sequelize.Transaction) {
|
||||||
return VideoShareModel.findOne({
|
return VideoShareModel.scope(ScopeNames.WITH_ACCOUNT).findOne({
|
||||||
where: {
|
where: {
|
||||||
accountId,
|
accountId,
|
||||||
videoId
|
videoId
|
||||||
},
|
},
|
||||||
include: [
|
|
||||||
AccountModel
|
|
||||||
],
|
|
||||||
transaction: t
|
transaction: t
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -72,7 +96,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
|
||||||
transaction: t
|
transaction: t
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoShareModel.findAll(query)
|
return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
|
||||||
.then(res => res.map(r => r.Account))
|
.then(res => res.map(r => r.Account))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,12 +21,14 @@ import {
|
||||||
IsUUID,
|
IsUUID,
|
||||||
Min,
|
Min,
|
||||||
Model,
|
Model,
|
||||||
|
Scopes,
|
||||||
Table,
|
Table,
|
||||||
UpdatedAt
|
UpdatedAt
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { IIncludeOptions } from 'sequelize-typescript/lib/interfaces/IIncludeOptions'
|
import { IIncludeOptions } from 'sequelize-typescript/lib/interfaces/IIncludeOptions'
|
||||||
import { VideoPrivacy, VideoResolution } from '../../../shared'
|
import { VideoPrivacy, VideoResolution } from '../../../shared'
|
||||||
import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
|
import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
|
||||||
|
import { Video, VideoDetails } from '../../../shared/models/videos'
|
||||||
import {
|
import {
|
||||||
activityPubCollection,
|
activityPubCollection,
|
||||||
createTorrentPromise,
|
createTorrentPromise,
|
||||||
|
@ -76,6 +78,79 @@ import { VideoFileModel } from './video-file'
|
||||||
import { VideoShareModel } from './video-share'
|
import { VideoShareModel } from './video-share'
|
||||||
import { VideoTagModel } from './video-tag'
|
import { VideoTagModel } from './video-tag'
|
||||||
|
|
||||||
|
enum ScopeNames {
|
||||||
|
NOT_IN_BLACKLIST = 'NOT_IN_BLACKLIST',
|
||||||
|
PUBLIC = 'PUBLIC',
|
||||||
|
WITH_ACCOUNT = 'WITH_ACCOUNT',
|
||||||
|
WITH_TAGS = 'WITH_TAGS',
|
||||||
|
WITH_FILES = 'WITH_FILES',
|
||||||
|
WITH_SHARES = 'WITH_SHARES',
|
||||||
|
WITH_RATES = 'WITH_RATES'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scopes({
|
||||||
|
[ScopeNames.NOT_IN_BLACKLIST]: {
|
||||||
|
where: {
|
||||||
|
id: {
|
||||||
|
[Sequelize.Op.notIn]: Sequelize.literal(
|
||||||
|
'(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[ScopeNames.PUBLIC]: {
|
||||||
|
where: {
|
||||||
|
privacy: VideoPrivacy.PUBLIC
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[ScopeNames.WITH_ACCOUNT]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => VideoChannelModel,
|
||||||
|
required: true,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountModel,
|
||||||
|
required: true,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => ServerModel,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
[ScopeNames.WITH_TAGS]: {
|
||||||
|
include: [ () => TagModel ]
|
||||||
|
},
|
||||||
|
[ScopeNames.WITH_FILES]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => VideoFileModel,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
[ScopeNames.WITH_SHARES]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => VideoShareModel,
|
||||||
|
include: [ () => AccountModel ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
[ScopeNames.WITH_RATES]: {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: () => AccountVideoRateModel,
|
||||||
|
include: [ () => AccountModel ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'video',
|
tableName: 'video',
|
||||||
indexes: [
|
indexes: [
|
||||||
|
@ -273,11 +348,7 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
static list () {
|
static list () {
|
||||||
const query = {
|
return VideoModel.scope(ScopeNames.WITH_FILES).findAll()
|
||||||
include: [ VideoFileModel ]
|
|
||||||
}
|
|
||||||
|
|
||||||
return VideoModel.findAll(query)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static listAllAndSharedByAccountForOutbox (accountId: number, start: number, count: number) {
|
static listAllAndSharedByAccountForOutbox (accountId: number, start: number, count: number) {
|
||||||
|
@ -363,10 +434,9 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
|
|
||||||
static listUserVideosForApi (userId: number, start: number, count: number, sort: string) {
|
static listUserVideosForApi (userId: number, start: number, count: number, sort: string) {
|
||||||
const query = {
|
const query = {
|
||||||
distinct: true,
|
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: [ getSort(sort), [ 'Tags', 'name', 'ASC' ] ],
|
order: [ getSort(sort) ],
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: VideoChannelModel,
|
model: VideoChannelModel,
|
||||||
|
@ -380,8 +450,7 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
TagModel
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,74 +464,35 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
|
|
||||||
static listForApi (start: number, count: number, sort: string) {
|
static listForApi (start: number, count: number, sort: string) {
|
||||||
const query = {
|
const query = {
|
||||||
distinct: true,
|
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: [ getSort(sort), [ 'Tags', 'name', 'ASC' ] ],
|
order: [ getSort(sort) ]
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: VideoChannelModel,
|
|
||||||
required: true,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
required: true,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: ServerModel,
|
|
||||||
required: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
TagModel
|
|
||||||
],
|
|
||||||
where: this.createBaseVideosWhere()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoModel.findAndCountAll(query).then(({ rows, count }) => {
|
return VideoModel.scope([ ScopeNames.NOT_IN_BLACKLIST, ScopeNames.PUBLIC, ScopeNames.WITH_ACCOUNT ])
|
||||||
return {
|
.findAndCountAll(query)
|
||||||
data: rows,
|
.then(({ rows, count }) => {
|
||||||
total: count
|
return {
|
||||||
}
|
data: rows,
|
||||||
})
|
total: count
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static load (id: number) {
|
static load (id: number) {
|
||||||
return VideoModel.findById(id)
|
return VideoModel.findById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByUUID (uuid: string, t?: Sequelize.Transaction) {
|
|
||||||
const query: IFindOptions<VideoModel> = {
|
|
||||||
where: {
|
|
||||||
uuid
|
|
||||||
},
|
|
||||||
include: [ VideoFileModel ]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t !== undefined) query.transaction = t
|
|
||||||
|
|
||||||
return VideoModel.findOne(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) {
|
static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) {
|
||||||
const query: IFindOptions<VideoModel> = {
|
const query: IFindOptions<VideoModel> = {
|
||||||
where: {
|
where: {
|
||||||
url
|
url
|
||||||
},
|
}
|
||||||
include: [
|
|
||||||
VideoFileModel,
|
|
||||||
{
|
|
||||||
model: VideoChannelModel,
|
|
||||||
include: [ AccountModel ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t !== undefined) query.transaction = t
|
if (t !== undefined) query.transaction = t
|
||||||
|
|
||||||
return VideoModel.findOne(query)
|
return VideoModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_FILES ]).findOne(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByUUIDOrURL (uuid: string, url: string, t?: Sequelize.Transaction) {
|
static loadByUUIDOrURL (uuid: string, url: string, t?: Sequelize.Transaction) {
|
||||||
|
@ -472,42 +502,22 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
{ uuid },
|
{ uuid },
|
||||||
{ url }
|
{ url }
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
include: [ VideoFileModel ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t !== undefined) query.transaction = t
|
if (t !== undefined) query.transaction = t
|
||||||
|
|
||||||
return VideoModel.findOne(query)
|
return VideoModel.scope(ScopeNames.WITH_FILES).findOne(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadAndPopulateAccountAndServerAndTags (id: number) {
|
static loadAndPopulateAccountAndServerAndTags (id: number) {
|
||||||
const options = {
|
const options = {
|
||||||
order: [ [ 'Tags', 'name', 'ASC' ] ],
|
order: [ [ 'Tags', 'name', 'ASC' ] ]
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: VideoChannelModel,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
include: [ { model: ServerModel, required: false } ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: AccountVideoRateModel,
|
|
||||||
include: [ AccountModel ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: VideoShareModel,
|
|
||||||
include: [ AccountModel ]
|
|
||||||
},
|
|
||||||
TagModel,
|
|
||||||
VideoFileModel
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoModel.findById(id, options)
|
return VideoModel
|
||||||
|
.scope([ ScopeNames.WITH_RATES, ScopeNames.WITH_SHARES, ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ])
|
||||||
|
.findById(id, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadByUUIDAndPopulateAccountAndServerAndTags (uuid: string) {
|
static loadByUUIDAndPopulateAccountAndServerAndTags (uuid: string) {
|
||||||
|
@ -515,31 +525,12 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
order: [ [ 'Tags', 'name', 'ASC' ] ],
|
order: [ [ 'Tags', 'name', 'ASC' ] ],
|
||||||
where: {
|
where: {
|
||||||
uuid
|
uuid
|
||||||
},
|
}
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: VideoChannelModel,
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: AccountModel,
|
|
||||||
include: [ { model: ServerModel, required: false } ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: AccountVideoRateModel,
|
|
||||||
include: [ AccountModel ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: VideoShareModel,
|
|
||||||
include: [ AccountModel ]
|
|
||||||
},
|
|
||||||
TagModel,
|
|
||||||
VideoFileModel
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoModel.findOne(options)
|
return VideoModel
|
||||||
|
.scope([ ScopeNames.WITH_RATES, ScopeNames.WITH_SHARES, ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ])
|
||||||
|
.findOne(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
static searchAndPopulateAccountAndServerAndTags (value: string, start: number, count: number, sort: string) {
|
static searchAndPopulateAccountAndServerAndTags (value: string, start: number, count: number, sort: string) {
|
||||||
|
@ -564,11 +555,11 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const query: IFindOptions<VideoModel> = {
|
const query: IFindOptions<VideoModel> = {
|
||||||
distinct: true,
|
distinct: true, // Because we have tags
|
||||||
where: this.createBaseVideosWhere(),
|
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: [ getSort(sort), [ 'Tags', 'name', 'ASC' ] ]
|
order: [ getSort(sort) ],
|
||||||
|
where: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: search on tags too
|
// TODO: search on tags too
|
||||||
|
@ -595,23 +586,13 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
videoChannelInclude, tagInclude
|
videoChannelInclude, tagInclude
|
||||||
]
|
]
|
||||||
|
|
||||||
return VideoModel.findAndCountAll(query).then(({ rows, count }) => {
|
return VideoModel.scope([ ScopeNames.NOT_IN_BLACKLIST, ScopeNames.PUBLIC ])
|
||||||
return {
|
.findAndCountAll(query).then(({ rows, count }) => {
|
||||||
data: rows,
|
return {
|
||||||
total: count
|
data: rows,
|
||||||
}
|
total: count
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
private static createBaseVideosWhere () {
|
|
||||||
return {
|
|
||||||
id: {
|
|
||||||
[Sequelize.Op.notIn]: VideoModel.sequelize.literal(
|
|
||||||
'(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")'
|
|
||||||
)
|
|
||||||
},
|
|
||||||
privacy: VideoPrivacy.PUBLIC
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getOriginalFile () {
|
getOriginalFile () {
|
||||||
|
@ -733,13 +714,12 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
views: this.views,
|
views: this.views,
|
||||||
likes: this.likes,
|
likes: this.likes,
|
||||||
dislikes: this.dislikes,
|
dislikes: this.dislikes,
|
||||||
tags: map<TagModel, string>(this.Tags, 'name'),
|
|
||||||
thumbnailPath: this.getThumbnailPath(),
|
thumbnailPath: this.getThumbnailPath(),
|
||||||
previewPath: this.getPreviewPath(),
|
previewPath: this.getPreviewPath(),
|
||||||
embedPath: this.getEmbedPath(),
|
embedPath: this.getEmbedPath(),
|
||||||
createdAt: this.createdAt,
|
createdAt: this.createdAt,
|
||||||
updatedAt: this.updatedAt
|
updatedAt: this.updatedAt
|
||||||
}
|
} as Video
|
||||||
}
|
}
|
||||||
|
|
||||||
toFormattedDetailsJSON () {
|
toFormattedDetailsJSON () {
|
||||||
|
@ -755,6 +735,7 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
descriptionPath: this.getDescriptionPath(),
|
descriptionPath: this.getDescriptionPath(),
|
||||||
channel: this.VideoChannel.toFormattedJSON(),
|
channel: this.VideoChannel.toFormattedJSON(),
|
||||||
account: this.VideoChannel.Account.toFormattedJSON(),
|
account: this.VideoChannel.Account.toFormattedJSON(),
|
||||||
|
tags: map<TagModel, string>(this.Tags, 'name'),
|
||||||
files: []
|
files: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,7 +760,7 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
return -1
|
return -1
|
||||||
})
|
})
|
||||||
|
|
||||||
return Object.assign(formattedJson, detailsJson)
|
return Object.assign(formattedJson, detailsJson) as VideoDetails
|
||||||
}
|
}
|
||||||
|
|
||||||
toActivityPubObject (): VideoTorrentObject {
|
toActivityPubObject (): VideoTorrentObject {
|
||||||
|
|
|
@ -132,7 +132,6 @@ describe('Test a single server', function () {
|
||||||
expect(video.serverHost).to.equal('localhost:9001')
|
expect(video.serverHost).to.equal('localhost:9001')
|
||||||
expect(video.accountName).to.equal('root')
|
expect(video.accountName).to.equal('root')
|
||||||
expect(video.isLocal).to.be.true
|
expect(video.isLocal).to.be.true
|
||||||
expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
|
|
||||||
expect(dateIsValid(video.createdAt)).to.be.true
|
expect(dateIsValid(video.createdAt)).to.be.true
|
||||||
expect(dateIsValid(video.updatedAt)).to.be.true
|
expect(dateIsValid(video.updatedAt)).to.be.true
|
||||||
|
|
||||||
|
@ -181,7 +180,6 @@ describe('Test a single server', function () {
|
||||||
expect(video.serverHost).to.equal('localhost:9001')
|
expect(video.serverHost).to.equal('localhost:9001')
|
||||||
expect(video.accountName).to.equal('root')
|
expect(video.accountName).to.equal('root')
|
||||||
expect(video.isLocal).to.be.true
|
expect(video.isLocal).to.be.true
|
||||||
expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
|
|
||||||
expect(dateIsValid(video.createdAt)).to.be.true
|
expect(dateIsValid(video.createdAt)).to.be.true
|
||||||
expect(dateIsValid(video.updatedAt)).to.be.true
|
expect(dateIsValid(video.updatedAt)).to.be.true
|
||||||
expect(video.channel.name).to.equal('Default root channel')
|
expect(video.channel.name).to.equal('Default root channel')
|
||||||
|
@ -248,7 +246,6 @@ describe('Test a single server', function () {
|
||||||
expect(video.serverHost).to.equal('localhost:9001')
|
expect(video.serverHost).to.equal('localhost:9001')
|
||||||
expect(video.accountName).to.equal('root')
|
expect(video.accountName).to.equal('root')
|
||||||
expect(video.isLocal).to.be.true
|
expect(video.isLocal).to.be.true
|
||||||
expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
|
|
||||||
expect(dateIsValid(video.createdAt)).to.be.true
|
expect(dateIsValid(video.createdAt)).to.be.true
|
||||||
expect(dateIsValid(video.updatedAt)).to.be.true
|
expect(dateIsValid(video.updatedAt)).to.be.true
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ describe('Test video abuses', function () {
|
||||||
await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes)
|
await uploadVideo(servers[1].url, servers[1].accessToken, video2Attributes)
|
||||||
|
|
||||||
// Wait videos propagation, server 2 has transcoding enabled
|
// Wait videos propagation, server 2 has transcoding enabled
|
||||||
await wait(10000)
|
await wait(15000)
|
||||||
|
|
||||||
const res = await getVideosList(servers[0].url)
|
const res = await getVideosList(servers[0].url)
|
||||||
const videos = res.body.data
|
const videos = res.body.data
|
||||||
|
|
|
@ -28,7 +28,6 @@ export interface Video {
|
||||||
isLocal: boolean
|
isLocal: boolean
|
||||||
name: string
|
name: string
|
||||||
serverHost: string
|
serverHost: string
|
||||||
tags: string[]
|
|
||||||
thumbnailPath: string
|
thumbnailPath: string
|
||||||
previewPath: string
|
previewPath: string
|
||||||
embedPath: string
|
embedPath: string
|
||||||
|
@ -43,6 +42,7 @@ export interface VideoDetails extends Video {
|
||||||
privacyLabel: string
|
privacyLabel: string
|
||||||
descriptionPath: string
|
descriptionPath: string
|
||||||
channel: VideoChannel
|
channel: VideoChannel
|
||||||
|
tags: string[]
|
||||||
files: VideoFile[]
|
files: VideoFile[]
|
||||||
account: Account
|
account: Account
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue