diff options
author | Chocobozzz <me@florianbigard.com> | 2018-02-15 14:46:26 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-02-15 15:29:07 +0100 |
commit | 2422c46b27790d94fd29a7092170cee5a1b56008 (patch) | |
tree | d5c1942ce20cadb27a551d87c789edfe92f5b105 /server/models | |
parent | 34cbef8c6cc912143a421413bdd832c4adcc556a (diff) | |
download | PeerTube-2422c46b27790d94fd29a7092170cee5a1b56008.tar.gz PeerTube-2422c46b27790d94fd29a7092170cee5a1b56008.tar.zst PeerTube-2422c46b27790d94fd29a7092170cee5a1b56008.zip |
Implement support field in video and video channel
Diffstat (limited to 'server/models')
-rw-r--r-- | server/models/account/account.ts | 29 | ||||
-rw-r--r-- | server/models/activitypub/actor.ts | 23 | ||||
-rw-r--r-- | server/models/video/video-channel.ts | 19 | ||||
-rw-r--r-- | server/models/video/video-share.ts | 28 | ||||
-rw-r--r-- | server/models/video/video.ts | 29 |
5 files changed, 102 insertions, 26 deletions
diff --git a/server/models/account/account.ts b/server/models/account/account.ts index 20724ae0c..d8f305c37 100644 --- a/server/models/account/account.ts +++ b/server/models/account/account.ts | |||
@@ -1,16 +1,28 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import { | 2 | import { |
3 | AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Model, Table, | 3 | AllowNull, |
4 | BeforeDestroy, | ||
5 | BelongsTo, | ||
6 | Column, | ||
7 | CreatedAt, | ||
8 | Default, | ||
9 | DefaultScope, | ||
10 | ForeignKey, | ||
11 | HasMany, | ||
12 | Is, | ||
13 | Model, | ||
14 | Table, | ||
4 | UpdatedAt | 15 | UpdatedAt |
5 | } from 'sequelize-typescript' | 16 | } from 'sequelize-typescript' |
6 | import { Account } from '../../../shared/models/actors' | 17 | import { Account } from '../../../shared/models/actors' |
18 | import { isAccountDescriptionValid } from '../../helpers/custom-validators/accounts' | ||
7 | import { logger } from '../../helpers/logger' | 19 | import { logger } from '../../helpers/logger' |
8 | import { sendDeleteActor } from '../../lib/activitypub/send' | 20 | import { sendDeleteActor } from '../../lib/activitypub/send' |
9 | import { ActorModel } from '../activitypub/actor' | 21 | import { ActorModel } from '../activitypub/actor' |
10 | import { ApplicationModel } from '../application/application' | 22 | import { ApplicationModel } from '../application/application' |
11 | import { AvatarModel } from '../avatar/avatar' | 23 | import { AvatarModel } from '../avatar/avatar' |
12 | import { ServerModel } from '../server/server' | 24 | import { ServerModel } from '../server/server' |
13 | import { getSort } from '../utils' | 25 | import { getSort, throwIfNotValid } from '../utils' |
14 | import { VideoChannelModel } from '../video/video-channel' | 26 | import { VideoChannelModel } from '../video/video-channel' |
15 | import { VideoCommentModel } from '../video/video-comment' | 27 | import { VideoCommentModel } from '../video/video-comment' |
16 | import { UserModel } from './user' | 28 | import { UserModel } from './user' |
@@ -42,6 +54,12 @@ export class AccountModel extends Model<AccountModel> { | |||
42 | @Column | 54 | @Column |
43 | name: string | 55 | name: string |
44 | 56 | ||
57 | @AllowNull(true) | ||
58 | @Default(null) | ||
59 | @Is('AccountDescription', value => throwIfNotValid(value, isAccountDescriptionValid, 'description')) | ||
60 | @Column | ||
61 | description: string | ||
62 | |||
45 | @CreatedAt | 63 | @CreatedAt |
46 | createdAt: Date | 64 | createdAt: Date |
47 | 65 | ||
@@ -196,6 +214,7 @@ export class AccountModel extends Model<AccountModel> { | |||
196 | const account = { | 214 | const account = { |
197 | id: this.id, | 215 | id: this.id, |
198 | displayName: this.name, | 216 | displayName: this.name, |
217 | description: this.description, | ||
199 | createdAt: this.createdAt, | 218 | createdAt: this.createdAt, |
200 | updatedAt: this.updatedAt | 219 | updatedAt: this.updatedAt |
201 | } | 220 | } |
@@ -204,7 +223,11 @@ export class AccountModel extends Model<AccountModel> { | |||
204 | } | 223 | } |
205 | 224 | ||
206 | toActivityPubObject () { | 225 | toActivityPubObject () { |
207 | return this.Actor.toActivityPubObject(this.name, 'Account') | 226 | const obj = this.Actor.toActivityPubObject(this.name, 'Account') |
227 | |||
228 | return Object.assign(obj, { | ||
229 | summary: this.description | ||
230 | }) | ||
208 | } | 231 | } |
209 | 232 | ||
210 | isOwned () { | 233 | isOwned () { |
diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts index c79bba96b..1d0e54ee3 100644 --- a/server/models/activitypub/actor.ts +++ b/server/models/activitypub/actor.ts | |||
@@ -2,14 +2,31 @@ import { values } from 'lodash' | |||
2 | import { extname } from 'path' | 2 | import { extname } from 'path' |
3 | import * as Sequelize from 'sequelize' | 3 | import * as Sequelize from 'sequelize' |
4 | import { | 4 | import { |
5 | AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, DefaultScope, ForeignKey, HasMany, HasOne, Is, IsUUID, Model, Scopes, | 5 | AllowNull, |
6 | Table, UpdatedAt | 6 | BelongsTo, |
7 | Column, | ||
8 | CreatedAt, | ||
9 | DataType, | ||
10 | Default, | ||
11 | DefaultScope, | ||
12 | ForeignKey, | ||
13 | HasMany, | ||
14 | HasOne, | ||
15 | Is, | ||
16 | IsUUID, | ||
17 | Model, | ||
18 | Scopes, | ||
19 | Table, | ||
20 | UpdatedAt | ||
7 | } from 'sequelize-typescript' | 21 | } from 'sequelize-typescript' |
8 | import { ActivityPubActorType } from '../../../shared/models/activitypub' | 22 | import { ActivityPubActorType } from '../../../shared/models/activitypub' |
9 | import { Avatar } from '../../../shared/models/avatars/avatar.model' | 23 | import { Avatar } from '../../../shared/models/avatars/avatar.model' |
10 | import { activityPubContextify } from '../../helpers/activitypub' | 24 | import { activityPubContextify } from '../../helpers/activitypub' |
11 | import { | 25 | import { |
12 | isActorFollowersCountValid, isActorFollowingCountValid, isActorPreferredUsernameValid, isActorPrivateKeyValid, | 26 | isActorFollowersCountValid, |
27 | isActorFollowingCountValid, | ||
28 | isActorPreferredUsernameValid, | ||
29 | isActorPrivateKeyValid, | ||
13 | isActorPublicKeyValid | 30 | isActorPublicKeyValid |
14 | } from '../../helpers/custom-validators/activitypub/actor' | 31 | } from '../../helpers/custom-validators/activitypub/actor' |
15 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' | 32 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' |
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index 7c161c864..289775a0f 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts | |||
@@ -1,9 +1,13 @@ | |||
1 | import { | 1 | import { |
2 | AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Is, Model, Scopes, Table, | 2 | AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Is, Model, Scopes, Table, |
3 | UpdatedAt | 3 | UpdatedAt, Default |
4 | } from 'sequelize-typescript' | 4 | } from 'sequelize-typescript' |
5 | import { ActivityPubActor } from '../../../shared/models/activitypub' | 5 | import { ActivityPubActor } from '../../../shared/models/activitypub' |
6 | import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels' | 6 | import { VideoChannel } from '../../../shared/models/videos' |
7 | import { | ||
8 | isVideoChannelDescriptionValid, isVideoChannelNameValid, | ||
9 | isVideoChannelSupportValid | ||
10 | } from '../../helpers/custom-validators/video-channels' | ||
7 | import { logger } from '../../helpers/logger' | 11 | import { logger } from '../../helpers/logger' |
8 | import { sendDeleteActor } from '../../lib/activitypub/send' | 12 | import { sendDeleteActor } from '../../lib/activitypub/send' |
9 | import { AccountModel } from '../account/account' | 13 | import { AccountModel } from '../account/account' |
@@ -67,10 +71,17 @@ export class VideoChannelModel extends Model<VideoChannelModel> { | |||
67 | name: string | 71 | name: string |
68 | 72 | ||
69 | @AllowNull(true) | 73 | @AllowNull(true) |
74 | @Default(null) | ||
70 | @Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description')) | 75 | @Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description')) |
71 | @Column | 76 | @Column |
72 | description: string | 77 | description: string |
73 | 78 | ||
79 | @AllowNull(true) | ||
80 | @Default(null) | ||
81 | @Is('VideoChannelSupport', value => throwIfNotValid(value, isVideoChannelSupportValid, 'support')) | ||
82 | @Column | ||
83 | support: string | ||
84 | |||
74 | @CreatedAt | 85 | @CreatedAt |
75 | createdAt: Date | 86 | createdAt: Date |
76 | 87 | ||
@@ -221,12 +232,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> { | |||
221 | .findById(id, options) | 232 | .findById(id, options) |
222 | } | 233 | } |
223 | 234 | ||
224 | toFormattedJSON () { | 235 | toFormattedJSON (): VideoChannel { |
225 | const actor = this.Actor.toFormattedJSON() | 236 | const actor = this.Actor.toFormattedJSON() |
226 | const account = { | 237 | const account = { |
227 | id: this.id, | 238 | id: this.id, |
228 | displayName: this.name, | 239 | displayName: this.name, |
229 | description: this.description, | 240 | description: this.description, |
241 | support: this.support, | ||
230 | isLocal: this.Actor.isOwned(), | 242 | isLocal: this.Actor.isOwned(), |
231 | createdAt: this.createdAt, | 243 | createdAt: this.createdAt, |
232 | updatedAt: this.updatedAt | 244 | updatedAt: this.updatedAt |
@@ -240,6 +252,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> { | |||
240 | 252 | ||
241 | return Object.assign(obj, { | 253 | return Object.assign(obj, { |
242 | summary: this.description, | 254 | summary: this.description, |
255 | support: this.support, | ||
243 | attributedTo: [ | 256 | attributedTo: [ |
244 | { | 257 | { |
245 | type: 'Person' as 'Person', | 258 | type: 'Person' as 'Person', |
diff --git a/server/models/video/video-share.ts b/server/models/video/video-share.ts index 48ba68a4a..6f770957f 100644 --- a/server/models/video/video-share.ts +++ b/server/models/video/video-share.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Bluebird from 'bluebird' | ||
2 | import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' | 3 | import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' |
3 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' | 4 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' |
4 | import { CONSTRAINTS_FIELDS } from '../../initializers' | 5 | import { CONSTRAINTS_FIELDS } from '../../initializers' |
@@ -115,7 +116,7 @@ export class VideoShareModel extends Model<VideoShareModel> { | |||
115 | .then(res => res.map(r => r.Actor)) | 116 | .then(res => res.map(r => r.Actor)) |
116 | } | 117 | } |
117 | 118 | ||
118 | static loadActorsByVideoOwner (actorOwnerId: number, t: Sequelize.Transaction) { | 119 | static loadActorsByVideoOwner (actorOwnerId: number, t: Sequelize.Transaction): Bluebird<ActorModel[]> { |
119 | const query = { | 120 | const query = { |
120 | attributes: [], | 121 | attributes: [], |
121 | include: [ | 122 | include: [ |
@@ -152,4 +153,29 @@ export class VideoShareModel extends Model<VideoShareModel> { | |||
152 | return VideoShareModel.scope(ScopeNames.FULL).findAll(query) | 153 | return VideoShareModel.scope(ScopeNames.FULL).findAll(query) |
153 | .then(res => res.map(r => r.Actor)) | 154 | .then(res => res.map(r => r.Actor)) |
154 | } | 155 | } |
156 | |||
157 | static loadActorsByVideoChannel (videoChannelId: number, t: Sequelize.Transaction): Bluebird<ActorModel[]> { | ||
158 | const query = { | ||
159 | attributes: [], | ||
160 | include: [ | ||
161 | { | ||
162 | model: ActorModel, | ||
163 | required: true | ||
164 | }, | ||
165 | { | ||
166 | attributes: [], | ||
167 | model: VideoModel, | ||
168 | required: true, | ||
169 | where: { | ||
170 | channelId: videoChannelId | ||
171 | } | ||
172 | } | ||
173 | ], | ||
174 | transaction: t | ||
175 | } | ||
176 | |||
177 | return VideoShareModel.scope(ScopeNames.FULL) | ||
178 | .findAll(query) | ||
179 | .then(res => res.map(r => r.Actor)) | ||
180 | } | ||
155 | } | 181 | } |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index ff82fb3b2..d748e81bd 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -40,7 +40,7 @@ import { | |||
40 | isVideoLanguageValid, | 40 | isVideoLanguageValid, |
41 | isVideoLicenceValid, | 41 | isVideoLicenceValid, |
42 | isVideoNameValid, | 42 | isVideoNameValid, |
43 | isVideoPrivacyValid | 43 | isVideoPrivacyValid, isVideoSupportValid |
44 | } from '../../helpers/custom-validators/videos' | 44 | } from '../../helpers/custom-validators/videos' |
45 | import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils' | 45 | import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils' |
46 | import { logger } from '../../helpers/logger' | 46 | import { logger } from '../../helpers/logger' |
@@ -299,6 +299,12 @@ export class VideoModel extends Model<VideoModel> { | |||
299 | @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max)) | 299 | @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max)) |
300 | description: string | 300 | description: string |
301 | 301 | ||
302 | @AllowNull(true) | ||
303 | @Default(null) | ||
304 | @Is('VideoSupport', value => throwIfNotValid(value, isVideoSupportValid, 'support')) | ||
305 | @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.SUPPORT.max)) | ||
306 | support: string | ||
307 | |||
302 | @AllowNull(false) | 308 | @AllowNull(false) |
303 | @Is('VideoDuration', value => throwIfNotValid(value, isVideoDurationValid, 'duration')) | 309 | @Is('VideoDuration', value => throwIfNotValid(value, isVideoDurationValid, 'duration')) |
304 | @Column | 310 | @Column |
@@ -841,7 +847,7 @@ export class VideoModel extends Model<VideoModel> { | |||
841 | return join(STATIC_PATHS.PREVIEWS, this.getPreviewName()) | 847 | return join(STATIC_PATHS.PREVIEWS, this.getPreviewName()) |
842 | } | 848 | } |
843 | 849 | ||
844 | toFormattedJSON () { | 850 | toFormattedJSON (): Video { |
845 | let serverHost | 851 | let serverHost |
846 | 852 | ||
847 | if (this.VideoChannel.Account.Actor.Server) { | 853 | if (this.VideoChannel.Account.Actor.Server) { |
@@ -875,10 +881,10 @@ export class VideoModel extends Model<VideoModel> { | |||
875 | embedPath: this.getEmbedPath(), | 881 | embedPath: this.getEmbedPath(), |
876 | createdAt: this.createdAt, | 882 | createdAt: this.createdAt, |
877 | updatedAt: this.updatedAt | 883 | updatedAt: this.updatedAt |
878 | } as Video | 884 | } |
879 | } | 885 | } |
880 | 886 | ||
881 | toFormattedDetailsJSON () { | 887 | toFormattedDetailsJSON (): VideoDetails { |
882 | const formattedJson = this.toFormattedJSON() | 888 | const formattedJson = this.toFormattedJSON() |
883 | 889 | ||
884 | // Maybe our server is not up to date and there are new privacy settings since our version | 890 | // Maybe our server is not up to date and there are new privacy settings since our version |
@@ -888,6 +894,7 @@ export class VideoModel extends Model<VideoModel> { | |||
888 | const detailsJson = { | 894 | const detailsJson = { |
889 | privacyLabel, | 895 | privacyLabel, |
890 | privacy: this.privacy, | 896 | privacy: this.privacy, |
897 | support: this.support, | ||
891 | descriptionPath: this.getDescriptionPath(), | 898 | descriptionPath: this.getDescriptionPath(), |
892 | channel: this.VideoChannel.toFormattedJSON(), | 899 | channel: this.VideoChannel.toFormattedJSON(), |
893 | account: this.VideoChannel.Account.toFormattedJSON(), | 900 | account: this.VideoChannel.Account.toFormattedJSON(), |
@@ -917,7 +924,7 @@ export class VideoModel extends Model<VideoModel> { | |||
917 | return -1 | 924 | return -1 |
918 | }) | 925 | }) |
919 | 926 | ||
920 | return Object.assign(formattedJson, detailsJson) as VideoDetails | 927 | return Object.assign(formattedJson, detailsJson) |
921 | } | 928 | } |
922 | 929 | ||
923 | toActivityPubObject (): VideoTorrentObject { | 930 | toActivityPubObject (): VideoTorrentObject { |
@@ -957,17 +964,6 @@ export class VideoModel extends Model<VideoModel> { | |||
957 | let dislikesObject | 964 | let dislikesObject |
958 | 965 | ||
959 | if (Array.isArray(this.AccountVideoRates)) { | 966 | if (Array.isArray(this.AccountVideoRates)) { |
960 | const likes: string[] = [] | ||
961 | const dislikes: string[] = [] | ||
962 | |||
963 | for (const rate of this.AccountVideoRates) { | ||
964 | if (rate.type === 'like') { | ||
965 | likes.push(rate.Account.Actor.url) | ||
966 | } else if (rate.type === 'dislike') { | ||
967 | dislikes.push(rate.Account.Actor.url) | ||
968 | } | ||
969 | } | ||
970 | |||
971 | const res = this.toRatesActivityPubObjects() | 967 | const res = this.toRatesActivityPubObjects() |
972 | likesObject = res.likesObject | 968 | likesObject = res.likesObject |
973 | dislikesObject = res.dislikesObject | 969 | dislikesObject = res.dislikesObject |
@@ -1032,6 +1028,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1032 | updated: this.updatedAt.toISOString(), | 1028 | updated: this.updatedAt.toISOString(), |
1033 | mediaType: 'text/markdown', | 1029 | mediaType: 'text/markdown', |
1034 | content: this.getTruncatedDescription(), | 1030 | content: this.getTruncatedDescription(), |
1031 | support: this.support, | ||
1035 | icon: { | 1032 | icon: { |
1036 | type: 'Image', | 1033 | type: 'Image', |
1037 | url: this.getThumbnailUrl(baseUrlHttp), | 1034 | url: this.getThumbnailUrl(baseUrlHttp), |