2017-11-15 17:56:21 +01:00
|
|
|
import * as Sequelize from 'sequelize'
|
2019-03-19 16:23:02 +01:00
|
|
|
import { Op } from 'sequelize'
|
2018-02-15 14:46:26 +01:00
|
|
|
import * as Bluebird from 'bluebird'
|
2018-01-26 15:49:57 +01:00
|
|
|
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
|
|
|
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
|
|
|
import { CONSTRAINTS_FIELDS } from '../../initializers'
|
2018-01-03 16:38:50 +01:00
|
|
|
import { AccountModel } from '../account/account'
|
2017-12-14 17:38:41 +01:00
|
|
|
import { ActorModel } from '../activitypub/actor'
|
2018-01-26 15:49:57 +01:00
|
|
|
import { throwIfNotValid } from '../utils'
|
2017-12-12 17:53:50 +01:00
|
|
|
import { VideoModel } from './video'
|
2018-01-03 16:38:50 +01:00
|
|
|
import { VideoChannelModel } from './video-channel'
|
2017-11-15 17:56:21 +01:00
|
|
|
|
2017-12-14 10:07:57 +01:00
|
|
|
enum ScopeNames {
|
|
|
|
FULL = 'FULL',
|
2017-12-14 17:38:41 +01:00
|
|
|
WITH_ACTOR = 'WITH_ACTOR'
|
2017-12-14 10:07:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Scopes({
|
|
|
|
[ScopeNames.FULL]: {
|
|
|
|
include: [
|
|
|
|
{
|
2017-12-14 17:38:41 +01:00
|
|
|
model: () => ActorModel,
|
2017-12-14 10:07:57 +01:00
|
|
|
required: true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
model: () => VideoModel,
|
|
|
|
required: true
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
2017-12-14 17:38:41 +01:00
|
|
|
[ScopeNames.WITH_ACTOR]: {
|
2017-12-14 10:07:57 +01:00
|
|
|
include: [
|
|
|
|
{
|
2017-12-14 17:38:41 +01:00
|
|
|
model: () => ActorModel,
|
2017-12-14 10:07:57 +01:00
|
|
|
required: true
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
})
|
2017-12-12 17:53:50 +01:00
|
|
|
@Table({
|
|
|
|
tableName: 'videoShare',
|
|
|
|
indexes: [
|
2017-11-15 17:56:21 +01:00
|
|
|
{
|
2017-12-14 17:38:41 +01:00
|
|
|
fields: [ 'actorId' ]
|
2017-12-12 17:53:50 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
fields: [ 'videoId' ]
|
2018-01-26 15:49:57 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
fields: [ 'url' ],
|
|
|
|
unique: true
|
2017-11-15 17:56:21 +01:00
|
|
|
}
|
|
|
|
]
|
2017-12-12 17:53:50 +01:00
|
|
|
})
|
|
|
|
export class VideoShareModel extends Model<VideoShareModel> {
|
2018-01-26 15:49:57 +01:00
|
|
|
|
|
|
|
@AllowNull(false)
|
|
|
|
@Is('VideoShareUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
|
|
|
|
@Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_SHARE.URL.max))
|
|
|
|
url: string
|
|
|
|
|
2017-12-12 17:53:50 +01:00
|
|
|
@CreatedAt
|
|
|
|
createdAt: Date
|
2017-11-15 17:56:21 +01:00
|
|
|
|
2017-12-12 17:53:50 +01:00
|
|
|
@UpdatedAt
|
|
|
|
updatedAt: Date
|
2017-11-15 17:56:21 +01:00
|
|
|
|
2017-12-14 17:38:41 +01:00
|
|
|
@ForeignKey(() => ActorModel)
|
2017-12-12 17:53:50 +01:00
|
|
|
@Column
|
2017-12-14 17:38:41 +01:00
|
|
|
actorId: number
|
2017-11-15 17:56:21 +01:00
|
|
|
|
2017-12-14 17:38:41 +01:00
|
|
|
@BelongsTo(() => ActorModel, {
|
2017-11-15 17:56:21 +01:00
|
|
|
foreignKey: {
|
|
|
|
allowNull: false
|
|
|
|
},
|
|
|
|
onDelete: 'cascade'
|
|
|
|
})
|
2017-12-14 17:38:41 +01:00
|
|
|
Actor: ActorModel
|
2017-11-15 17:56:21 +01:00
|
|
|
|
2017-12-12 17:53:50 +01:00
|
|
|
@ForeignKey(() => VideoModel)
|
|
|
|
@Column
|
|
|
|
videoId: number
|
|
|
|
|
|
|
|
@BelongsTo(() => VideoModel, {
|
2017-11-15 17:56:21 +01:00
|
|
|
foreignKey: {
|
2017-12-12 17:53:50 +01:00
|
|
|
allowNull: false
|
2017-11-15 17:56:21 +01:00
|
|
|
},
|
|
|
|
onDelete: 'cascade'
|
|
|
|
})
|
2017-12-12 17:53:50 +01:00
|
|
|
Video: VideoModel
|
2017-11-27 14:44:51 +01:00
|
|
|
|
2018-11-14 15:01:28 +01:00
|
|
|
static load (actorId: number, videoId: number, t?: Sequelize.Transaction) {
|
2017-12-14 17:38:41 +01:00
|
|
|
return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({
|
2017-12-12 17:53:50 +01:00
|
|
|
where: {
|
2017-12-14 17:38:41 +01:00
|
|
|
actorId,
|
2017-12-12 17:53:50 +01:00
|
|
|
videoId
|
|
|
|
},
|
|
|
|
transaction: t
|
|
|
|
})
|
2017-11-16 15:55:01 +01:00
|
|
|
}
|
|
|
|
|
2018-05-11 15:10:13 +02:00
|
|
|
static loadByUrl (url: string, t: Sequelize.Transaction) {
|
2018-05-31 10:23:56 +02:00
|
|
|
return VideoShareModel.scope(ScopeNames.FULL).findOne({
|
2018-05-11 15:10:13 +02:00
|
|
|
where: {
|
|
|
|
url
|
|
|
|
},
|
|
|
|
transaction: t
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-12-14 17:38:41 +01:00
|
|
|
static loadActorsByShare (videoId: number, t: Sequelize.Transaction) {
|
2017-12-12 17:53:50 +01:00
|
|
|
const query = {
|
|
|
|
where: {
|
|
|
|
videoId
|
|
|
|
},
|
|
|
|
include: [
|
|
|
|
{
|
2017-12-14 17:38:41 +01:00
|
|
|
model: ActorModel,
|
2017-12-12 17:53:50 +01:00
|
|
|
required: true
|
|
|
|
}
|
|
|
|
],
|
|
|
|
transaction: t
|
|
|
|
}
|
|
|
|
|
2017-12-14 10:07:57 +01:00
|
|
|
return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
|
2017-12-14 17:38:41 +01:00
|
|
|
.then(res => res.map(r => r.Actor))
|
2017-12-12 17:53:50 +01:00
|
|
|
}
|
2018-01-03 16:38:50 +01:00
|
|
|
|
2019-03-05 10:58:44 +01:00
|
|
|
static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Sequelize.Transaction): Bluebird<ActorModel[]> {
|
2018-01-03 16:38:50 +01:00
|
|
|
const query = {
|
|
|
|
attributes: [],
|
|
|
|
include: [
|
|
|
|
{
|
|
|
|
model: ActorModel,
|
|
|
|
required: true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
attributes: [],
|
|
|
|
model: VideoModel,
|
|
|
|
required: true,
|
|
|
|
include: [
|
|
|
|
{
|
|
|
|
attributes: [],
|
|
|
|
model: VideoChannelModel.unscoped(),
|
|
|
|
required: true,
|
|
|
|
include: [
|
|
|
|
{
|
|
|
|
attributes: [],
|
|
|
|
model: AccountModel.unscoped(),
|
|
|
|
required: true,
|
|
|
|
where: {
|
|
|
|
actorId: actorOwnerId
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
transaction: t
|
|
|
|
}
|
|
|
|
|
|
|
|
return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
|
|
|
|
.then(res => res.map(r => r.Actor))
|
|
|
|
}
|
2018-02-15 14:46:26 +01:00
|
|
|
|
|
|
|
static loadActorsByVideoChannel (videoChannelId: number, t: Sequelize.Transaction): Bluebird<ActorModel[]> {
|
|
|
|
const query = {
|
|
|
|
attributes: [],
|
|
|
|
include: [
|
|
|
|
{
|
|
|
|
model: ActorModel,
|
|
|
|
required: true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
attributes: [],
|
|
|
|
model: VideoModel,
|
|
|
|
required: true,
|
|
|
|
where: {
|
|
|
|
channelId: videoChannelId
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
|
|
|
transaction: t
|
|
|
|
}
|
|
|
|
|
|
|
|
return VideoShareModel.scope(ScopeNames.FULL)
|
|
|
|
.findAll(query)
|
|
|
|
.then(res => res.map(r => r.Actor))
|
|
|
|
}
|
2018-05-25 16:21:16 +02:00
|
|
|
|
|
|
|
static listAndCountByVideoId (videoId: number, start: number, count: number, t?: Sequelize.Transaction) {
|
|
|
|
const query = {
|
2018-06-13 17:43:30 +02:00
|
|
|
offset: start,
|
|
|
|
limit: count,
|
2018-05-25 16:21:16 +02:00
|
|
|
where: {
|
|
|
|
videoId
|
|
|
|
},
|
|
|
|
transaction: t
|
|
|
|
}
|
|
|
|
|
|
|
|
return VideoShareModel.findAndCountAll(query)
|
|
|
|
}
|
2019-03-19 16:23:02 +01:00
|
|
|
|
|
|
|
static cleanOldSharesOf (videoId: number, beforeUpdatedAt: Date) {
|
|
|
|
const query = {
|
|
|
|
where: {
|
|
|
|
updatedAt: {
|
|
|
|
[Op.lt]: beforeUpdatedAt
|
|
|
|
},
|
|
|
|
videoId
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return VideoShareModel.destroy(query)
|
|
|
|
}
|
2017-11-16 15:55:01 +01:00
|
|
|
}
|