]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/video-share.ts
Stronger model typings
[github/Chocobozzz/PeerTube.git] / server / models / video / video-share.ts
CommitLineData
2422c46b 1import * as Bluebird from 'bluebird'
4ba3b8ea
C
2import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
3import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
74dc3bca 4import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
265ba139 5import { AccountModel } from '../account/account'
50d6de9c 6import { ActorModel } from '../activitypub/actor'
6b9c966f 7import { buildLocalActorIdsIn, throwIfNotValid } from '../utils'
3fd3ab2d 8import { VideoModel } from './video'
265ba139 9import { VideoChannelModel } from './video-channel'
970ceac0 10import { Op, Transaction } from 'sequelize'
453e83ea
C
11import { MVideoShareActor, MVideoShareFull } from '../../typings/models/video'
12import { MActorDefault } from '../../typings/models'
d8465018 13
d48ff09d
C
14enum ScopeNames {
15 FULL = 'FULL',
50d6de9c 16 WITH_ACTOR = 'WITH_ACTOR'
d48ff09d
C
17}
18
3acc5084 19@Scopes(() => ({
d48ff09d
C
20 [ScopeNames.FULL]: {
21 include: [
22 {
3acc5084 23 model: ActorModel,
d48ff09d
C
24 required: true
25 },
26 {
3acc5084 27 model: VideoModel,
d48ff09d
C
28 required: true
29 }
30 ]
31 },
50d6de9c 32 [ScopeNames.WITH_ACTOR]: {
d48ff09d
C
33 include: [
34 {
3acc5084 35 model: ActorModel,
d48ff09d
C
36 required: true
37 }
38 ]
39 }
3acc5084 40}))
3fd3ab2d
C
41@Table({
42 tableName: 'videoShare',
43 indexes: [
d8465018 44 {
50d6de9c 45 fields: [ 'actorId' ]
3fd3ab2d
C
46 },
47 {
48 fields: [ 'videoId' ]
4ba3b8ea
C
49 },
50 {
51 fields: [ 'url' ],
52 unique: true
d8465018 53 }
d8465018 54 ]
3fd3ab2d
C
55})
56export class VideoShareModel extends Model<VideoShareModel> {
4ba3b8ea
C
57
58 @AllowNull(false)
59 @Is('VideoShareUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
60 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_SHARE.URL.max))
61 url: string
62
3fd3ab2d
C
63 @CreatedAt
64 createdAt: Date
d8465018 65
3fd3ab2d
C
66 @UpdatedAt
67 updatedAt: Date
d8465018 68
50d6de9c 69 @ForeignKey(() => ActorModel)
3fd3ab2d 70 @Column
50d6de9c 71 actorId: number
d8465018 72
50d6de9c 73 @BelongsTo(() => ActorModel, {
d8465018 74 foreignKey: {
d8465018
C
75 allowNull: false
76 },
77 onDelete: 'cascade'
78 })
50d6de9c 79 Actor: ActorModel
d8465018 80
3fd3ab2d
C
81 @ForeignKey(() => VideoModel)
82 @Column
83 videoId: number
84
85 @BelongsTo(() => VideoModel, {
d8465018 86 foreignKey: {
3fd3ab2d 87 allowNull: false
d8465018
C
88 },
89 onDelete: 'cascade'
90 })
3fd3ab2d 91 Video: VideoModel
4e50b6a1 92
453e83ea 93 static load (actorId: number, videoId: number, t?: Transaction): Bluebird<MVideoShareActor> {
50d6de9c 94 return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({
3fd3ab2d 95 where: {
50d6de9c 96 actorId,
3fd3ab2d
C
97 videoId
98 },
3fd3ab2d
C
99 transaction: t
100 })
d7d5611c
C
101 }
102
453e83ea 103 static loadByUrl (url: string, t: Transaction): Bluebird<MVideoShareFull> {
9588d4f4 104 return VideoShareModel.scope(ScopeNames.FULL).findOne({
0f320037
C
105 where: {
106 url
107 },
108 transaction: t
109 })
110 }
111
453e83ea 112 static loadActorsByShare (videoId: number, t: Transaction): Bluebird<MActorDefault[]> {
3fd3ab2d
C
113 const query = {
114 where: {
115 videoId
116 },
117 include: [
118 {
50d6de9c 119 model: ActorModel,
3fd3ab2d
C
120 required: true
121 }
122 ],
123 transaction: t
124 }
125
d48ff09d 126 return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
453e83ea 127 .then((res: MVideoShareFull[]) => res.map(r => r.Actor))
3fd3ab2d 128 }
265ba139 129
453e83ea 130 static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Transaction): Bluebird<MActorDefault[]> {
265ba139
C
131 const query = {
132 attributes: [],
133 include: [
134 {
135 model: ActorModel,
136 required: true
137 },
138 {
139 attributes: [],
140 model: VideoModel,
141 required: true,
142 include: [
143 {
144 attributes: [],
145 model: VideoChannelModel.unscoped(),
146 required: true,
147 include: [
148 {
149 attributes: [],
150 model: AccountModel.unscoped(),
151 required: true,
152 where: {
153 actorId: actorOwnerId
154 }
155 }
156 ]
157 }
158 ]
159 }
160 ],
161 transaction: t
162 }
163
164 return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
165 .then(res => res.map(r => r.Actor))
166 }
2422c46b 167
453e83ea 168 static loadActorsByVideoChannel (videoChannelId: number, t: Transaction): Bluebird<MActorDefault[]> {
2422c46b
C
169 const query = {
170 attributes: [],
171 include: [
172 {
173 model: ActorModel,
174 required: true
175 },
176 {
177 attributes: [],
178 model: VideoModel,
179 required: true,
180 where: {
181 channelId: videoChannelId
182 }
183 }
184 ],
185 transaction: t
186 }
187
188 return VideoShareModel.scope(ScopeNames.FULL)
189 .findAll(query)
190 .then(res => res.map(r => r.Actor))
191 }
8fffe21a 192
970ceac0 193 static listAndCountByVideoId (videoId: number, start: number, count: number, t?: Transaction) {
8fffe21a 194 const query = {
9a4a9b6c
C
195 offset: start,
196 limit: count,
8fffe21a
C
197 where: {
198 videoId
199 },
200 transaction: t
201 }
202
203 return VideoShareModel.findAndCountAll(query)
204 }
2ba92871
C
205
206 static cleanOldSharesOf (videoId: number, beforeUpdatedAt: Date) {
207 const query = {
208 where: {
209 updatedAt: {
970ceac0 210 [Op.lt]: beforeUpdatedAt
2ba92871 211 },
6b9c966f
C
212 videoId,
213 actorId: {
214 [Op.notIn]: buildLocalActorIdsIn()
970ceac0 215 }
6b9c966f 216 }
2ba92871
C
217 }
218
219 return VideoShareModel.destroy(query)
220 }
d7d5611c 221}