aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/video-abuse.ts13
-rw-r--r--server/models/video/video-channel-share.ts96
-rw-r--r--server/models/video/video-channel.ts164
-rw-r--r--server/models/video/video-share.ts32
-rw-r--r--server/models/video/video.ts78
5 files changed, 137 insertions, 246 deletions
diff --git a/server/models/video/video-abuse.ts b/server/models/video/video-abuse.ts
index d0ee969fb..182971c4e 100644
--- a/server/models/video/video-abuse.ts
+++ b/server/models/video/video-abuse.ts
@@ -3,7 +3,6 @@ import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
3import { isVideoAbuseReasonValid } from '../../helpers/custom-validators/videos' 3import { isVideoAbuseReasonValid } from '../../helpers/custom-validators/videos'
4import { CONFIG } from '../../initializers' 4import { CONFIG } from '../../initializers'
5import { AccountModel } from '../account/account' 5import { AccountModel } from '../account/account'
6import { ServerModel } from '../server/server'
7import { getSort, throwIfNotValid } from '../utils' 6import { getSort, throwIfNotValid } from '../utils'
8import { VideoModel } from './video' 7import { VideoModel } from './video'
9 8
@@ -63,13 +62,7 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
63 include: [ 62 include: [
64 { 63 {
65 model: AccountModel, 64 model: AccountModel,
66 required: true, 65 required: true
67 include: [
68 {
69 model: ServerModel,
70 required: false
71 }
72 ]
73 }, 66 },
74 { 67 {
75 model: VideoModel, 68 model: VideoModel,
@@ -87,8 +80,8 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
87 toFormattedJSON () { 80 toFormattedJSON () {
88 let reporterServerHost 81 let reporterServerHost
89 82
90 if (this.Account.Server) { 83 if (this.Account.Actor.Server) {
91 reporterServerHost = this.Account.Server.host 84 reporterServerHost = this.Account.Actor.Server.host
92 } else { 85 } else {
93 // It means it's our video 86 // It means it's our video
94 reporterServerHost = CONFIG.WEBSERVER.HOST 87 reporterServerHost = CONFIG.WEBSERVER.HOST
diff --git a/server/models/video/video-channel-share.ts b/server/models/video/video-channel-share.ts
deleted file mode 100644
index f5b7a7cd5..000000000
--- a/server/models/video/video-channel-share.ts
+++ /dev/null
@@ -1,96 +0,0 @@
1import * as Sequelize from 'sequelize'
2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
3import { AccountModel } from '../account/account'
4import { VideoChannelModel } from './video-channel'
5
6enum ScopeNames {
7 FULL = 'FULL',
8 WITH_ACCOUNT = 'WITH_ACCOUNT'
9}
10
11@Scopes({
12 [ScopeNames.FULL]: {
13 include: [
14 {
15 model: () => AccountModel,
16 required: true
17 },
18 {
19 model: () => VideoChannelModel,
20 required: true
21 }
22 ]
23 },
24 [ScopeNames.WITH_ACCOUNT]: {
25 include: [
26 {
27 model: () => AccountModel,
28 required: true
29 }
30 ]
31 }
32})
33@Table({
34 tableName: 'videoChannelShare',
35 indexes: [
36 {
37 fields: [ 'accountId' ]
38 },
39 {
40 fields: [ 'videoChannelId' ]
41 }
42 ]
43})
44export class VideoChannelShareModel extends Model<VideoChannelShareModel> {
45 @CreatedAt
46 createdAt: Date
47
48 @UpdatedAt
49 updatedAt: Date
50
51 @ForeignKey(() => AccountModel)
52 @Column
53 accountId: number
54
55 @BelongsTo(() => AccountModel, {
56 foreignKey: {
57 allowNull: false
58 },
59 onDelete: 'cascade'
60 })
61 Account: AccountModel
62
63 @ForeignKey(() => VideoChannelModel)
64 @Column
65 videoChannelId: number
66
67 @BelongsTo(() => VideoChannelModel, {
68 foreignKey: {
69 allowNull: false
70 },
71 onDelete: 'cascade'
72 })
73 VideoChannel: VideoChannelModel
74
75 static load (accountId: number, videoChannelId: number, t: Sequelize.Transaction) {
76 return VideoChannelShareModel.scope(ScopeNames.FULL).findOne({
77 where: {
78 accountId,
79 videoChannelId
80 },
81 transaction: t
82 })
83 }
84
85 static loadAccountsByShare (videoChannelId: number, t: Sequelize.Transaction) {
86 const query = {
87 where: {
88 videoChannelId
89 },
90 transaction: t
91 }
92
93 return VideoChannelShareModel.scope(ScopeNames.WITH_ACCOUNT).findAll(query)
94 .then(res => res.map(r => r.Account))
95 }
96}
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index fe44d3d53..acc2486b3 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -1,42 +1,52 @@
1import * as Sequelize from 'sequelize'
2import { 1import {
3 AfterDestroy, 2 AfterDestroy,
4 AllowNull, 3 AllowNull,
5 BelongsTo, 4 BelongsTo,
6 Column, 5 Column,
7 CreatedAt, 6 CreatedAt,
8 DataType, 7 DefaultScope,
9 Default,
10 ForeignKey, 8 ForeignKey,
11 HasMany, 9 HasMany,
12 Is, 10 Is,
13 IsUUID,
14 Model, 11 Model,
15 Scopes, 12 Scopes,
16 Table, 13 Table,
17 UpdatedAt 14 UpdatedAt
18} from 'sequelize-typescript' 15} from 'sequelize-typescript'
19import { IFindOptions } from 'sequelize-typescript/lib/interfaces/IFindOptions' 16import { ActivityPubActor } from '../../../shared/models/activitypub'
20import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels' 17import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels'
21import { sendDeleteVideoChannel } from '../../lib/activitypub/send' 18import { sendDeleteActor } from '../../lib/activitypub/send'
22import { AccountModel } from '../account/account' 19import { AccountModel } from '../account/account'
23import { ActorModel } from '../activitypub/actor' 20import { ActorModel } from '../activitypub/actor'
24import { ServerModel } from '../server/server'
25import { getSort, throwIfNotValid } from '../utils' 21import { getSort, throwIfNotValid } from '../utils'
26import { VideoModel } from './video' 22import { VideoModel } from './video'
27import { VideoChannelShareModel } from './video-channel-share'
28 23
29enum ScopeNames { 24enum ScopeNames {
30 WITH_ACCOUNT = 'WITH_ACCOUNT', 25 WITH_ACCOUNT = 'WITH_ACCOUNT',
26 WITH_ACTOR = 'WITH_ACTOR',
31 WITH_VIDEOS = 'WITH_VIDEOS' 27 WITH_VIDEOS = 'WITH_VIDEOS'
32} 28}
33 29
30@DefaultScope({
31 include: [
32 {
33 model: () => ActorModel,
34 required: true
35 }
36 ]
37})
34@Scopes({ 38@Scopes({
35 [ScopeNames.WITH_ACCOUNT]: { 39 [ScopeNames.WITH_ACCOUNT]: {
36 include: [ 40 include: [
37 { 41 {
38 model: () => AccountModel, 42 model: () => AccountModel,
39 include: [ { model: () => ServerModel, required: false } ] 43 required: true,
44 include: [
45 {
46 model: () => ActorModel,
47 required: true
48 }
49 ]
40 } 50 }
41 ] 51 ]
42 }, 52 },
@@ -44,6 +54,11 @@ enum ScopeNames {
44 include: [ 54 include: [
45 () => VideoModel 55 () => VideoModel
46 ] 56 ]
57 },
58 [ScopeNames.WITH_ACTOR]: {
59 include: [
60 () => ActorModel
61 ]
47 } 62 }
48}) 63})
49@Table({ 64@Table({
@@ -57,12 +72,6 @@ enum ScopeNames {
57export class VideoChannelModel extends Model<VideoChannelModel> { 72export class VideoChannelModel extends Model<VideoChannelModel> {
58 73
59 @AllowNull(false) 74 @AllowNull(false)
60 @Default(DataType.UUIDV4)
61 @IsUUID(4)
62 @Column(DataType.UUID)
63 uuid: string
64
65 @AllowNull(false)
66 @Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name')) 75 @Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name'))
67 @Column 76 @Column
68 name: string 77 name: string
@@ -72,10 +81,6 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
72 @Column 81 @Column
73 description: string 82 description: string
74 83
75 @AllowNull(false)
76 @Column
77 remote: boolean
78
79 @CreatedAt 84 @CreatedAt
80 createdAt: Date 85 createdAt: Date
81 86
@@ -115,19 +120,10 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
115 }) 120 })
116 Videos: VideoModel[] 121 Videos: VideoModel[]
117 122
118 @HasMany(() => VideoChannelShareModel, {
119 foreignKey: {
120 name: 'channelId',
121 allowNull: false
122 },
123 onDelete: 'CASCADE'
124 })
125 VideoChannelShares: VideoChannelShareModel[]
126
127 @AfterDestroy 123 @AfterDestroy
128 static sendDeleteIfOwned (instance: VideoChannelModel) { 124 static sendDeleteIfOwned (instance: VideoChannelModel) {
129 if (instance.isOwned()) { 125 if (instance.Actor.isOwned()) {
130 return sendDeleteVideoChannel(instance, undefined) 126 return sendDeleteActor(instance.Actor, undefined)
131 } 127 }
132 128
133 return undefined 129 return undefined
@@ -150,7 +146,9 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
150 order: [ getSort(sort) ] 146 order: [ getSort(sort) ]
151 } 147 }
152 148
153 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findAndCountAll(query) 149 return VideoChannelModel
150 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
151 .findAndCountAll(query)
154 .then(({ rows, count }) => { 152 .then(({ rows, count }) => {
155 return { total: count, data: rows } 153 return { total: count, data: rows }
156 }) 154 })
@@ -165,51 +163,18 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
165 where: { 163 where: {
166 id: accountId 164 id: accountId
167 }, 165 },
168 required: true, 166 required: true
169 include: [ { model: ServerModel, required: false } ]
170 } 167 }
171 ] 168 ]
172 } 169 }
173 170
174 return VideoChannelModel.findAndCountAll(query) 171 return VideoChannelModel
172 .findAndCountAll(query)
175 .then(({ rows, count }) => { 173 .then(({ rows, count }) => {
176 return { total: count, data: rows } 174 return { total: count, data: rows }
177 }) 175 })
178 } 176 }
179 177
180 static loadByUrl (url: string, t?: Sequelize.Transaction) {
181 const query: IFindOptions<VideoChannelModel> = {
182 include: [
183 {
184 model: ActorModel,
185 required: true,
186 where: {
187 url
188 }
189 }
190 ]
191 }
192
193 if (t !== undefined) query.transaction = t
194
195 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(query)
196 }
197
198 static loadByUUIDOrUrl (uuid: string, url: string, t?: Sequelize.Transaction) {
199 const query: IFindOptions<VideoChannelModel> = {
200 where: {
201 [ Sequelize.Op.or ]: [
202 { uuid },
203 { url }
204 ]
205 }
206 }
207
208 if (t !== undefined) query.transaction = t
209
210 return VideoChannelModel.findOne(query)
211 }
212
213 static loadByIdAndAccount (id: number, accountId: number) { 178 static loadByIdAndAccount (id: number, accountId: number) {
214 const options = { 179 const options = {
215 where: { 180 where: {
@@ -218,21 +183,33 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
218 } 183 }
219 } 184 }
220 185
221 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(options) 186 return VideoChannelModel
187 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
188 .findOne(options)
222 } 189 }
223 190
224 static loadAndPopulateAccount (id: number) { 191 static loadAndPopulateAccount (id: number) {
225 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findById(id) 192 return VideoChannelModel
193 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
194 .findById(id)
226 } 195 }
227 196
228 static loadByUUIDAndPopulateAccount (uuid: string) { 197 static loadByUUIDAndPopulateAccount (uuid: string) {
229 const options = { 198 const options = {
230 where: { 199 include: [
231 uuid 200 {
232 } 201 model: ActorModel,
202 required: true,
203 where: {
204 uuid
205 }
206 }
207 ]
233 } 208 }
234 209
235 return VideoChannelModel.scope(ScopeNames.WITH_ACCOUNT).findOne(options) 210 return VideoChannelModel
211 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
212 .findOne(options)
236 } 213 }
237 214
238 static loadAndPopulateAccountAndVideos (id: number) { 215 static loadAndPopulateAccountAndVideos (id: number) {
@@ -242,39 +219,36 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
242 ] 219 ]
243 } 220 }
244 221
245 return VideoChannelModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ]).findById(id, options) 222 return VideoChannelModel
246 } 223 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ])
247 224 .findById(id, options)
248 isOwned () {
249 return this.remote === false
250 } 225 }
251 226
252 toFormattedJSON () { 227 toFormattedJSON () {
253 const json = { 228 const actor = this.Actor.toFormattedJSON()
229 const account = {
254 id: this.id, 230 id: this.id,
255 uuid: this.uuid,
256 name: this.name, 231 name: this.name,
257 description: this.description, 232 description: this.description,
258 isLocal: this.isOwned(), 233 isLocal: this.Actor.isOwned(),
259 createdAt: this.createdAt, 234 createdAt: this.createdAt,
260 updatedAt: this.updatedAt 235 updatedAt: this.updatedAt
261 } 236 }
262 237
263 if (this.Account !== undefined) { 238 return Object.assign(actor, account)
264 json[ 'owner' ] = {
265 name: this.Account.name,
266 uuid: this.Account.uuid
267 }
268 }
269
270 if (Array.isArray(this.Videos)) {
271 json[ 'videos' ] = this.Videos.map(v => v.toFormattedJSON())
272 }
273
274 return json
275 } 239 }
276 240
277 toActivityPubObject () { 241 toActivityPubObject (): ActivityPubActor {
278 return this.Actor.toActivityPubObject(this.name, this.uuid, 'VideoChannel') 242 const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel')
243
244 return Object.assign(obj, {
245 summary: this.description,
246 attributedTo: [
247 {
248 type: 'Person' as 'Person',
249 id: this.Account.Actor.url
250 }
251 ]
252 })
279 } 253 }
280} 254}
diff --git a/server/models/video/video-share.ts b/server/models/video/video-share.ts
index e1733b3a7..c252fd646 100644
--- a/server/models/video/video-share.ts
+++ b/server/models/video/video-share.ts
@@ -1,18 +1,18 @@
1import * as Sequelize from 'sequelize' 1import * as Sequelize from 'sequelize'
2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' 2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
3import { AccountModel } from '../account/account' 3import { ActorModel } from '../activitypub/actor'
4import { VideoModel } from './video' 4import { VideoModel } from './video'
5 5
6enum ScopeNames { 6enum ScopeNames {
7 FULL = 'FULL', 7 FULL = 'FULL',
8 WITH_ACCOUNT = 'WITH_ACCOUNT' 8 WITH_ACTOR = 'WITH_ACTOR'
9} 9}
10 10
11@Scopes({ 11@Scopes({
12 [ScopeNames.FULL]: { 12 [ScopeNames.FULL]: {
13 include: [ 13 include: [
14 { 14 {
15 model: () => AccountModel, 15 model: () => ActorModel,
16 required: true 16 required: true
17 }, 17 },
18 { 18 {
@@ -21,10 +21,10 @@ enum ScopeNames {
21 } 21 }
22 ] 22 ]
23 }, 23 },
24 [ScopeNames.WITH_ACCOUNT]: { 24 [ScopeNames.WITH_ACTOR]: {
25 include: [ 25 include: [
26 { 26 {
27 model: () => AccountModel, 27 model: () => ActorModel,
28 required: true 28 required: true
29 } 29 }
30 ] 30 ]
@@ -34,7 +34,7 @@ enum ScopeNames {
34 tableName: 'videoShare', 34 tableName: 'videoShare',
35 indexes: [ 35 indexes: [
36 { 36 {
37 fields: [ 'accountId' ] 37 fields: [ 'actorId' ]
38 }, 38 },
39 { 39 {
40 fields: [ 'videoId' ] 40 fields: [ 'videoId' ]
@@ -48,17 +48,17 @@ export class VideoShareModel extends Model<VideoShareModel> {
48 @UpdatedAt 48 @UpdatedAt
49 updatedAt: Date 49 updatedAt: Date
50 50
51 @ForeignKey(() => AccountModel) 51 @ForeignKey(() => ActorModel)
52 @Column 52 @Column
53 accountId: number 53 actorId: number
54 54
55 @BelongsTo(() => AccountModel, { 55 @BelongsTo(() => ActorModel, {
56 foreignKey: { 56 foreignKey: {
57 allowNull: false 57 allowNull: false
58 }, 58 },
59 onDelete: 'cascade' 59 onDelete: 'cascade'
60 }) 60 })
61 Account: AccountModel 61 Actor: ActorModel
62 62
63 @ForeignKey(() => VideoModel) 63 @ForeignKey(() => VideoModel)
64 @Column 64 @Column
@@ -72,24 +72,24 @@ export class VideoShareModel extends Model<VideoShareModel> {
72 }) 72 })
73 Video: VideoModel 73 Video: VideoModel
74 74
75 static load (accountId: number, videoId: number, t: Sequelize.Transaction) { 75 static load (actorId: number, videoId: number, t: Sequelize.Transaction) {
76 return VideoShareModel.scope(ScopeNames.WITH_ACCOUNT).findOne({ 76 return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({
77 where: { 77 where: {
78 accountId, 78 actorId,
79 videoId 79 videoId
80 }, 80 },
81 transaction: t 81 transaction: t
82 }) 82 })
83 } 83 }
84 84
85 static loadAccountsByShare (videoId: number, t: Sequelize.Transaction) { 85 static loadActorsByShare (videoId: number, t: Sequelize.Transaction) {
86 const query = { 86 const query = {
87 where: { 87 where: {
88 videoId 88 videoId
89 }, 89 },
90 include: [ 90 include: [
91 { 91 {
92 model: AccountModel, 92 model: ActorModel,
93 required: true 93 required: true
94 } 94 }
95 ], 95 ],
@@ -97,6 +97,6 @@ export class VideoShareModel extends Model<VideoShareModel> {
97 } 97 }
98 98
99 return VideoShareModel.scope(ScopeNames.FULL).findAll(query) 99 return VideoShareModel.scope(ScopeNames.FULL).findAll(query)
100 .then(res => res.map(r => r.Account)) 100 .then(res => res.map(r => r.Actor))
101 } 101 }
102} 102}
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 1f940a50d..97fdbc8ef 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -66,9 +66,10 @@ import {
66 VIDEO_PRIVACIES 66 VIDEO_PRIVACIES
67} from '../../initializers' 67} from '../../initializers'
68import { getAnnounceActivityPubUrl } from '../../lib/activitypub' 68import { getAnnounceActivityPubUrl } from '../../lib/activitypub'
69import { sendDeleteVideo } from '../../lib/index' 69import { sendDeleteVideo } from '../../lib/activitypub/send'
70import { AccountModel } from '../account/account' 70import { AccountModel } from '../account/account'
71import { AccountVideoRateModel } from '../account/account-video-rate' 71import { AccountVideoRateModel } from '../account/account-video-rate'
72import { ActorModel } from '../activitypub/actor'
72import { ServerModel } from '../server/server' 73import { ServerModel } from '../server/server'
73import { getSort, throwIfNotValid } from '../utils' 74import { getSort, throwIfNotValid } from '../utils'
74import { TagModel } from './tag' 75import { TagModel } from './tag'
@@ -79,8 +80,7 @@ import { VideoShareModel } from './video-share'
79import { VideoTagModel } from './video-tag' 80import { VideoTagModel } from './video-tag'
80 81
81enum ScopeNames { 82enum ScopeNames {
82 NOT_IN_BLACKLIST = 'NOT_IN_BLACKLIST', 83 AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST',
83 PUBLIC = 'PUBLIC',
84 WITH_ACCOUNT = 'WITH_ACCOUNT', 84 WITH_ACCOUNT = 'WITH_ACCOUNT',
85 WITH_TAGS = 'WITH_TAGS', 85 WITH_TAGS = 'WITH_TAGS',
86 WITH_FILES = 'WITH_FILES', 86 WITH_FILES = 'WITH_FILES',
@@ -89,17 +89,13 @@ enum ScopeNames {
89} 89}
90 90
91@Scopes({ 91@Scopes({
92 [ScopeNames.NOT_IN_BLACKLIST]: { 92 [ScopeNames.AVAILABLE_FOR_LIST]: {
93 where: { 93 where: {
94 id: { 94 id: {
95 [Sequelize.Op.notIn]: Sequelize.literal( 95 [Sequelize.Op.notIn]: Sequelize.literal(
96 '(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")' 96 '(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")'
97 ) 97 )
98 } 98 },
99 }
100 },
101 [ScopeNames.PUBLIC]: {
102 where: {
103 privacy: VideoPrivacy.PUBLIC 99 privacy: VideoPrivacy.PUBLIC
104 } 100 }
105 }, 101 },
@@ -114,8 +110,14 @@ enum ScopeNames {
114 required: true, 110 required: true,
115 include: [ 111 include: [
116 { 112 {
117 model: () => ServerModel, 113 model: () => ActorModel,
118 required: false 114 required: true,
115 include: [
116 {
117 model: () => ServerModel,
118 required: false
119 }
120 ]
119 } 121 }
120 ] 122 ]
121 } 123 }
@@ -138,7 +140,7 @@ enum ScopeNames {
138 include: [ 140 include: [
139 { 141 {
140 model: () => VideoShareModel, 142 model: () => VideoShareModel,
141 include: [ () => AccountModel ] 143 include: [ () => ActorModel ]
142 } 144 }
143 ] 145 ]
144 }, 146 },
@@ -271,7 +273,7 @@ export class VideoModel extends Model<VideoModel> {
271 273
272 @BelongsTo(() => VideoChannelModel, { 274 @BelongsTo(() => VideoChannelModel, {
273 foreignKey: { 275 foreignKey: {
274 allowNull: false 276 allowNull: true
275 }, 277 },
276 onDelete: 'cascade' 278 onDelete: 'cascade'
277 }) 279 })
@@ -351,14 +353,15 @@ export class VideoModel extends Model<VideoModel> {
351 return VideoModel.scope(ScopeNames.WITH_FILES).findAll() 353 return VideoModel.scope(ScopeNames.WITH_FILES).findAll()
352 } 354 }
353 355
354 static listAllAndSharedByAccountForOutbox (accountId: number, start: number, count: number) { 356 static listAllAndSharedByActorForOutbox (actorId: number, start: number, count: number) {
355 function getRawQuery (select: string) { 357 function getRawQuery (select: string) {
356 const queryVideo = 'SELECT ' + select + ' FROM "video" AS "Video" ' + 358 const queryVideo = 'SELECT ' + select + ' FROM "video" AS "Video" ' +
357 'INNER JOIN "videoChannel" AS "VideoChannel" ON "VideoChannel"."id" = "Video"."channelId" ' + 359 'INNER JOIN "videoChannel" AS "VideoChannel" ON "VideoChannel"."id" = "Video"."channelId" ' +
358 'WHERE "VideoChannel"."accountId" = ' + accountId 360 'INNER JOIN "account" AS "Account" ON "Account"."id" = "VideoChannel"."accountId" ' +
361 'WHERE "Account"."actorId" = ' + actorId
359 const queryVideoShare = 'SELECT ' + select + ' FROM "videoShare" AS "VideoShare" ' + 362 const queryVideoShare = 'SELECT ' + select + ' FROM "videoShare" AS "VideoShare" ' +
360 'INNER JOIN "video" AS "Video" ON "Video"."id" = "VideoShare"."videoId" ' + 363 'INNER JOIN "video" AS "Video" ON "Video"."id" = "VideoShare"."videoId" ' +
361 'WHERE "VideoShare"."accountId" = ' + accountId 364 'WHERE "VideoShare"."actorId" = ' + actorId
362 365
363 return `(${queryVideo}) UNION (${queryVideoShare})` 366 return `(${queryVideo}) UNION (${queryVideoShare})`
364 } 367 }
@@ -388,11 +391,16 @@ export class VideoModel extends Model<VideoModel> {
388 } 391 }
389 }, 392 },
390 { 393 {
391 accountId 394 actorId
392 } 395 }
393 ] 396 ]
394 }, 397 },
395 include: [ AccountModel ] 398 include: [
399 {
400 model: ActorModel,
401 required: true
402 }
403 ]
396 }, 404 },
397 { 405 {
398 model: VideoChannelModel, 406 model: VideoChannelModel,
@@ -469,7 +477,7 @@ export class VideoModel extends Model<VideoModel> {
469 order: [ getSort(sort) ] 477 order: [ getSort(sort) ]
470 } 478 }
471 479
472 return VideoModel.scope([ ScopeNames.NOT_IN_BLACKLIST, ScopeNames.PUBLIC, ScopeNames.WITH_ACCOUNT ]) 480 return VideoModel.scope([ ScopeNames.AVAILABLE_FOR_LIST, ScopeNames.WITH_ACCOUNT ])
473 .findAndCountAll(query) 481 .findAndCountAll(query)
474 .then(({ rows, count }) => { 482 .then(({ rows, count }) => {
475 return { 483 return {
@@ -541,7 +549,13 @@ export class VideoModel extends Model<VideoModel> {
541 549
542 const accountInclude: IIncludeOptions = { 550 const accountInclude: IIncludeOptions = {
543 model: AccountModel, 551 model: AccountModel,
544 include: [ serverInclude ] 552 include: [
553 {
554 model: ActorModel,
555 required: true,
556 include: [ serverInclude ]
557 }
558 ]
545 } 559 }
546 560
547 const videoChannelInclude: IIncludeOptions = { 561 const videoChannelInclude: IIncludeOptions = {
@@ -586,7 +600,7 @@ export class VideoModel extends Model<VideoModel> {
586 videoChannelInclude, tagInclude 600 videoChannelInclude, tagInclude
587 ] 601 ]
588 602
589 return VideoModel.scope([ ScopeNames.NOT_IN_BLACKLIST, ScopeNames.PUBLIC ]) 603 return VideoModel.scope([ ScopeNames.AVAILABLE_FOR_LIST ])
590 .findAndCountAll(query).then(({ rows, count }) => { 604 .findAndCountAll(query).then(({ rows, count }) => {
591 return { 605 return {
592 data: rows, 606 data: rows,
@@ -688,8 +702,8 @@ export class VideoModel extends Model<VideoModel> {
688 toFormattedJSON () { 702 toFormattedJSON () {
689 let serverHost 703 let serverHost
690 704
691 if (this.VideoChannel.Account.Server) { 705 if (this.VideoChannel.Account.Actor.Server) {
692 serverHost = this.VideoChannel.Account.Server.host 706 serverHost = this.VideoChannel.Account.Actor.Server.host
693 } else { 707 } else {
694 // It means it's our video 708 // It means it's our video
695 serverHost = CONFIG.WEBSERVER.HOST 709 serverHost = CONFIG.WEBSERVER.HOST
@@ -805,9 +819,9 @@ export class VideoModel extends Model<VideoModel> {
805 819
806 for (const rate of this.AccountVideoRates) { 820 for (const rate of this.AccountVideoRates) {
807 if (rate.type === 'like') { 821 if (rate.type === 'like') {
808 likes.push(rate.Account.url) 822 likes.push(rate.Account.Actor.url)
809 } else if (rate.type === 'dislike') { 823 } else if (rate.type === 'dislike') {
810 dislikes.push(rate.Account.url) 824 dislikes.push(rate.Account.Actor.url)
811 } 825 }
812 } 826 }
813 827
@@ -820,7 +834,7 @@ export class VideoModel extends Model<VideoModel> {
820 const shares: string[] = [] 834 const shares: string[] = []
821 835
822 for (const videoShare of this.VideoShares) { 836 for (const videoShare of this.VideoShares) {
823 const shareUrl = getAnnounceActivityPubUrl(this.url, videoShare.Account) 837 const shareUrl = getAnnounceActivityPubUrl(this.url, videoShare.Actor)
824 shares.push(shareUrl) 838 shares.push(shareUrl)
825 } 839 }
826 840
@@ -886,7 +900,13 @@ export class VideoModel extends Model<VideoModel> {
886 url, 900 url,
887 likes: likesObject, 901 likes: likesObject,
888 dislikes: dislikesObject, 902 dislikes: dislikesObject,
889 shares: sharesObject 903 shares: sharesObject,
904 attributedTo: [
905 {
906 type: 'Group',
907 id: this.VideoChannel.Actor.url
908 }
909 ]
890 } 910 }
891 } 911 }
892 912
@@ -1030,8 +1050,8 @@ export class VideoModel extends Model<VideoModel> {
1030 baseUrlHttp = CONFIG.WEBSERVER.URL 1050 baseUrlHttp = CONFIG.WEBSERVER.URL
1031 baseUrlWs = CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT 1051 baseUrlWs = CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
1032 } else { 1052 } else {
1033 baseUrlHttp = REMOTE_SCHEME.HTTP + '://' + this.VideoChannel.Account.Server.host 1053 baseUrlHttp = REMOTE_SCHEME.HTTP + '://' + this.VideoChannel.Account.Actor.Server.host
1034 baseUrlWs = REMOTE_SCHEME.WS + '://' + this.VideoChannel.Account.Server.host 1054 baseUrlWs = REMOTE_SCHEME.WS + '://' + this.VideoChannel.Account.Actor.Server.host
1035 } 1055 }
1036 1056
1037 return { baseUrlHttp, baseUrlWs } 1057 return { baseUrlHttp, baseUrlWs }