diff options
Diffstat (limited to 'server/models/video')
-rw-r--r-- | server/models/video/video-channel.ts | 145 | ||||
-rw-r--r-- | server/models/video/video-playlist.ts | 60 | ||||
-rw-r--r-- | server/models/video/video-query-builder.ts | 5 | ||||
-rw-r--r-- | server/models/video/video.ts | 25 |
4 files changed, 158 insertions, 77 deletions
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index 178878c55..b7ffbd3b1 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { FindOptions, Includeable, literal, Op, ScopeOptions } from 'sequelize' | 1 | import { FindOptions, Includeable, literal, Op, QueryTypes, ScopeOptions } from 'sequelize' |
2 | import { | 2 | import { |
3 | AllowNull, | 3 | AllowNull, |
4 | BeforeDestroy, | 4 | BeforeDestroy, |
@@ -28,17 +28,16 @@ import { | |||
28 | import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants' | 28 | import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants' |
29 | import { sendDeleteActor } from '../../lib/activitypub/send' | 29 | import { sendDeleteActor } from '../../lib/activitypub/send' |
30 | import { | 30 | import { |
31 | MChannelAccountDefault, | ||
32 | MChannelActor, | 31 | MChannelActor, |
33 | MChannelActorAccountDefaultVideos, | ||
34 | MChannelAP, | 32 | MChannelAP, |
33 | MChannelBannerAccountDefault, | ||
35 | MChannelFormattable, | 34 | MChannelFormattable, |
36 | MChannelSummaryFormattable | 35 | MChannelSummaryFormattable |
37 | } from '../../types/models/video' | 36 | } from '../../types/models/video' |
38 | import { AccountModel, ScopeNames as AccountModelScopeNames, SummaryOptions as AccountSummaryOptions } from '../account/account' | 37 | import { AccountModel, ScopeNames as AccountModelScopeNames, SummaryOptions as AccountSummaryOptions } from '../account/account' |
38 | import { ActorImageModel } from '../account/actor-image' | ||
39 | import { ActorModel, unusedActorAttributesForAPI } from '../activitypub/actor' | 39 | import { ActorModel, unusedActorAttributesForAPI } from '../activitypub/actor' |
40 | import { ActorFollowModel } from '../activitypub/actor-follow' | 40 | import { ActorFollowModel } from '../activitypub/actor-follow' |
41 | import { AvatarModel } from '../avatar/avatar' | ||
42 | import { ServerModel } from '../server/server' | 41 | import { ServerModel } from '../server/server' |
43 | import { buildServerIdsFollowedBy, buildTrigramSearchIndex, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils' | 42 | import { buildServerIdsFollowedBy, buildTrigramSearchIndex, createSimilarityAttribute, getSort, throwIfNotValid } from '../utils' |
44 | import { VideoModel } from './video' | 43 | import { VideoModel } from './video' |
@@ -49,6 +48,7 @@ export enum ScopeNames { | |||
49 | SUMMARY = 'SUMMARY', | 48 | SUMMARY = 'SUMMARY', |
50 | WITH_ACCOUNT = 'WITH_ACCOUNT', | 49 | WITH_ACCOUNT = 'WITH_ACCOUNT', |
51 | WITH_ACTOR = 'WITH_ACTOR', | 50 | WITH_ACTOR = 'WITH_ACTOR', |
51 | WITH_ACTOR_BANNER = 'WITH_ACTOR_BANNER', | ||
52 | WITH_VIDEOS = 'WITH_VIDEOS', | 52 | WITH_VIDEOS = 'WITH_VIDEOS', |
53 | WITH_STATS = 'WITH_STATS' | 53 | WITH_STATS = 'WITH_STATS' |
54 | } | 54 | } |
@@ -99,7 +99,14 @@ export type SummaryOptions = { | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | ] | 101 | ] |
102 | } | 102 | }, |
103 | include: [ | ||
104 | { | ||
105 | model: ActorImageModel, | ||
106 | as: 'Banner', | ||
107 | required: false | ||
108 | } | ||
109 | ] | ||
103 | }, | 110 | }, |
104 | { | 111 | { |
105 | model: AccountModel, | 112 | model: AccountModel, |
@@ -130,7 +137,8 @@ export type SummaryOptions = { | |||
130 | required: false | 137 | required: false |
131 | }, | 138 | }, |
132 | { | 139 | { |
133 | model: AvatarModel.unscoped(), | 140 | model: ActorImageModel.unscoped(), |
141 | as: 'Avatar', | ||
134 | required: false | 142 | required: false |
135 | } | 143 | } |
136 | ] | 144 | ] |
@@ -167,6 +175,20 @@ export type SummaryOptions = { | |||
167 | ActorModel | 175 | ActorModel |
168 | ] | 176 | ] |
169 | }, | 177 | }, |
178 | [ScopeNames.WITH_ACTOR_BANNER]: { | ||
179 | include: [ | ||
180 | { | ||
181 | model: ActorModel, | ||
182 | include: [ | ||
183 | { | ||
184 | model: ActorImageModel, | ||
185 | required: false, | ||
186 | as: 'Banner' | ||
187 | } | ||
188 | ] | ||
189 | } | ||
190 | ] | ||
191 | }, | ||
170 | [ScopeNames.WITH_VIDEOS]: { | 192 | [ScopeNames.WITH_VIDEOS]: { |
171 | include: [ | 193 | include: [ |
172 | VideoModel | 194 | VideoModel |
@@ -316,6 +338,47 @@ export class VideoChannelModel extends Model { | |||
316 | return VideoChannelModel.count(query) | 338 | return VideoChannelModel.count(query) |
317 | } | 339 | } |
318 | 340 | ||
341 | static async getStats () { | ||
342 | |||
343 | function getActiveVideoChannels (days: number) { | ||
344 | const options = { | ||
345 | type: QueryTypes.SELECT as QueryTypes.SELECT, | ||
346 | raw: true | ||
347 | } | ||
348 | |||
349 | const query = ` | ||
350 | SELECT COUNT(DISTINCT("VideoChannelModel"."id")) AS "count" | ||
351 | FROM "videoChannel" AS "VideoChannelModel" | ||
352 | INNER JOIN "video" AS "Videos" | ||
353 | ON "VideoChannelModel"."id" = "Videos"."channelId" | ||
354 | AND ("Videos"."publishedAt" > Now() - interval '${days}d') | ||
355 | INNER JOIN "account" AS "Account" | ||
356 | ON "VideoChannelModel"."accountId" = "Account"."id" | ||
357 | INNER JOIN "actor" AS "Account->Actor" | ||
358 | ON "Account"."actorId" = "Account->Actor"."id" | ||
359 | AND "Account->Actor"."serverId" IS NULL | ||
360 | LEFT OUTER JOIN "server" AS "Account->Actor->Server" | ||
361 | ON "Account->Actor"."serverId" = "Account->Actor->Server"."id"` | ||
362 | |||
363 | return VideoChannelModel.sequelize.query<{ count: string }>(query, options) | ||
364 | .then(r => parseInt(r[0].count, 10)) | ||
365 | } | ||
366 | |||
367 | const totalLocalVideoChannels = await VideoChannelModel.count() | ||
368 | const totalLocalDailyActiveVideoChannels = await getActiveVideoChannels(1) | ||
369 | const totalLocalWeeklyActiveVideoChannels = await getActiveVideoChannels(7) | ||
370 | const totalLocalMonthlyActiveVideoChannels = await getActiveVideoChannels(30) | ||
371 | const totalHalfYearActiveVideoChannels = await getActiveVideoChannels(180) | ||
372 | |||
373 | return { | ||
374 | totalLocalVideoChannels, | ||
375 | totalLocalDailyActiveVideoChannels, | ||
376 | totalLocalWeeklyActiveVideoChannels, | ||
377 | totalLocalMonthlyActiveVideoChannels, | ||
378 | totalHalfYearActiveVideoChannels | ||
379 | } | ||
380 | } | ||
381 | |||
319 | static listForApi (parameters: { | 382 | static listForApi (parameters: { |
320 | actorId: number | 383 | actorId: number |
321 | start: number | 384 | start: number |
@@ -441,7 +504,7 @@ export class VideoChannelModel extends Model { | |||
441 | where | 504 | where |
442 | } | 505 | } |
443 | 506 | ||
444 | const scopes: string | ScopeOptions | (string | ScopeOptions)[] = [ ScopeNames.WITH_ACTOR ] | 507 | const scopes: string | ScopeOptions | (string | ScopeOptions)[] = [ ScopeNames.WITH_ACTOR_BANNER ] |
445 | 508 | ||
446 | if (options.withStats === true) { | 509 | if (options.withStats === true) { |
447 | scopes.push({ | 510 | scopes.push({ |
@@ -457,32 +520,13 @@ export class VideoChannelModel extends Model { | |||
457 | }) | 520 | }) |
458 | } | 521 | } |
459 | 522 | ||
460 | static loadByIdAndPopulateAccount (id: number): Promise<MChannelAccountDefault> { | 523 | static loadAndPopulateAccount (id: number): Promise<MChannelBannerAccountDefault> { |
461 | return VideoChannelModel.unscoped() | 524 | return VideoChannelModel.unscoped() |
462 | .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) | 525 | .scope([ ScopeNames.WITH_ACTOR_BANNER, ScopeNames.WITH_ACCOUNT ]) |
463 | .findByPk(id) | 526 | .findByPk(id) |
464 | } | 527 | } |
465 | 528 | ||
466 | static loadByIdAndAccount (id: number, accountId: number): Promise<MChannelAccountDefault> { | 529 | static loadByUrlAndPopulateAccount (url: string): Promise<MChannelBannerAccountDefault> { |
467 | const query = { | ||
468 | where: { | ||
469 | id, | ||
470 | accountId | ||
471 | } | ||
472 | } | ||
473 | |||
474 | return VideoChannelModel.unscoped() | ||
475 | .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) | ||
476 | .findOne(query) | ||
477 | } | ||
478 | |||
479 | static loadAndPopulateAccount (id: number): Promise<MChannelAccountDefault> { | ||
480 | return VideoChannelModel.unscoped() | ||
481 | .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) | ||
482 | .findByPk(id) | ||
483 | } | ||
484 | |||
485 | static loadByUrlAndPopulateAccount (url: string): Promise<MChannelAccountDefault> { | ||
486 | const query = { | 530 | const query = { |
487 | include: [ | 531 | include: [ |
488 | { | 532 | { |
@@ -490,7 +534,14 @@ export class VideoChannelModel extends Model { | |||
490 | required: true, | 534 | required: true, |
491 | where: { | 535 | where: { |
492 | url | 536 | url |
493 | } | 537 | }, |
538 | include: [ | ||
539 | { | ||
540 | model: ActorImageModel, | ||
541 | required: false, | ||
542 | as: 'Banner' | ||
543 | } | ||
544 | ] | ||
494 | } | 545 | } |
495 | ] | 546 | ] |
496 | } | 547 | } |
@@ -508,7 +559,7 @@ export class VideoChannelModel extends Model { | |||
508 | return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host) | 559 | return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host) |
509 | } | 560 | } |
510 | 561 | ||
511 | static loadLocalByNameAndPopulateAccount (name: string): Promise<MChannelAccountDefault> { | 562 | static loadLocalByNameAndPopulateAccount (name: string): Promise<MChannelBannerAccountDefault> { |
512 | const query = { | 563 | const query = { |
513 | include: [ | 564 | include: [ |
514 | { | 565 | { |
@@ -517,17 +568,24 @@ export class VideoChannelModel extends Model { | |||
517 | where: { | 568 | where: { |
518 | preferredUsername: name, | 569 | preferredUsername: name, |
519 | serverId: null | 570 | serverId: null |
520 | } | 571 | }, |
572 | include: [ | ||
573 | { | ||
574 | model: ActorImageModel, | ||
575 | required: false, | ||
576 | as: 'Banner' | ||
577 | } | ||
578 | ] | ||
521 | } | 579 | } |
522 | ] | 580 | ] |
523 | } | 581 | } |
524 | 582 | ||
525 | return VideoChannelModel.unscoped() | 583 | return VideoChannelModel.unscoped() |
526 | .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) | 584 | .scope([ ScopeNames.WITH_ACCOUNT ]) |
527 | .findOne(query) | 585 | .findOne(query) |
528 | } | 586 | } |
529 | 587 | ||
530 | static loadByNameAndHostAndPopulateAccount (name: string, host: string): Promise<MChannelAccountDefault> { | 588 | static loadByNameAndHostAndPopulateAccount (name: string, host: string): Promise<MChannelBannerAccountDefault> { |
531 | const query = { | 589 | const query = { |
532 | include: [ | 590 | include: [ |
533 | { | 591 | { |
@@ -541,6 +599,11 @@ export class VideoChannelModel extends Model { | |||
541 | model: ServerModel, | 599 | model: ServerModel, |
542 | required: true, | 600 | required: true, |
543 | where: { host } | 601 | where: { host } |
602 | }, | ||
603 | { | ||
604 | model: ActorImageModel, | ||
605 | required: false, | ||
606 | as: 'Banner' | ||
544 | } | 607 | } |
545 | ] | 608 | ] |
546 | } | 609 | } |
@@ -548,22 +611,10 @@ export class VideoChannelModel extends Model { | |||
548 | } | 611 | } |
549 | 612 | ||
550 | return VideoChannelModel.unscoped() | 613 | return VideoChannelModel.unscoped() |
551 | .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) | 614 | .scope([ ScopeNames.WITH_ACCOUNT ]) |
552 | .findOne(query) | 615 | .findOne(query) |
553 | } | 616 | } |
554 | 617 | ||
555 | static loadAndPopulateAccountAndVideos (id: number): Promise<MChannelActorAccountDefaultVideos> { | ||
556 | const options = { | ||
557 | include: [ | ||
558 | VideoModel | ||
559 | ] | ||
560 | } | ||
561 | |||
562 | return VideoChannelModel.unscoped() | ||
563 | .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ]) | ||
564 | .findByPk(id, options) | ||
565 | } | ||
566 | |||
567 | toFormattedSummaryJSON (this: MChannelSummaryFormattable): VideoChannelSummary { | 618 | toFormattedSummaryJSON (this: MChannelSummaryFormattable): VideoChannelSummary { |
568 | const actor = this.Actor.toFormattedSummaryJSON() | 619 | const actor = this.Actor.toFormattedSummaryJSON() |
569 | 620 | ||
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts index 49a406608..efe5be36d 100644 --- a/server/models/video/video-playlist.ts +++ b/server/models/video/video-playlist.ts | |||
@@ -54,6 +54,7 @@ import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getPlaylistSort, isOutdat | |||
54 | import { ThumbnailModel } from './thumbnail' | 54 | import { ThumbnailModel } from './thumbnail' |
55 | import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel' | 55 | import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel' |
56 | import { VideoPlaylistElementModel } from './video-playlist-element' | 56 | import { VideoPlaylistElementModel } from './video-playlist-element' |
57 | import { ActorModel } from '../activitypub/actor' | ||
57 | 58 | ||
58 | enum ScopeNames { | 59 | enum ScopeNames { |
59 | AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST', | 60 | AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST', |
@@ -65,7 +66,7 @@ enum ScopeNames { | |||
65 | } | 66 | } |
66 | 67 | ||
67 | type AvailableForListOptions = { | 68 | type AvailableForListOptions = { |
68 | followerActorId: number | 69 | followerActorId?: number |
69 | type?: VideoPlaylistType | 70 | type?: VideoPlaylistType |
70 | accountId?: number | 71 | accountId?: number |
71 | videoChannelId?: number | 72 | videoChannelId?: number |
@@ -134,20 +135,26 @@ type AvailableForListOptions = { | |||
134 | privacy: VideoPlaylistPrivacy.PUBLIC | 135 | privacy: VideoPlaylistPrivacy.PUBLIC |
135 | }) | 136 | }) |
136 | 137 | ||
137 | // Only list local playlists OR playlists that are on an instance followed by actorId | 138 | // Only list local playlists |
138 | const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId) | 139 | const whereActorOr: WhereOptions[] = [ |
140 | { | ||
141 | serverId: null | ||
142 | } | ||
143 | ] | ||
139 | 144 | ||
140 | whereActor = { | 145 | // … OR playlists that are on an instance followed by actorId |
141 | [Op.or]: [ | 146 | if (options.followerActorId) { |
142 | { | 147 | const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId) |
143 | serverId: null | 148 | |
144 | }, | 149 | whereActorOr.push({ |
145 | { | 150 | serverId: { |
146 | serverId: { | 151 | [Op.in]: literal(inQueryInstanceFollow) |
147 | [Op.in]: literal(inQueryInstanceFollow) | ||
148 | } | ||
149 | } | 152 | } |
150 | ] | 153 | }) |
154 | } | ||
155 | |||
156 | whereActor = { | ||
157 | [Op.or]: whereActorOr | ||
151 | } | 158 | } |
152 | } | 159 | } |
153 | 160 | ||
@@ -495,6 +502,33 @@ export class VideoPlaylistModel extends Model { | |||
495 | return '/video-playlists/embed/' + this.uuid | 502 | return '/video-playlists/embed/' + this.uuid |
496 | } | 503 | } |
497 | 504 | ||
505 | static async getStats () { | ||
506 | const totalLocalPlaylists = await VideoPlaylistModel.count({ | ||
507 | include: [ | ||
508 | { | ||
509 | model: AccountModel, | ||
510 | required: true, | ||
511 | include: [ | ||
512 | { | ||
513 | model: ActorModel, | ||
514 | required: true, | ||
515 | where: { | ||
516 | serverId: null | ||
517 | } | ||
518 | } | ||
519 | ] | ||
520 | } | ||
521 | ], | ||
522 | where: { | ||
523 | privacy: VideoPlaylistPrivacy.PUBLIC | ||
524 | } | ||
525 | }) | ||
526 | |||
527 | return { | ||
528 | totalLocalPlaylists | ||
529 | } | ||
530 | } | ||
531 | |||
498 | setAsRefreshed () { | 532 | setAsRefreshed () { |
499 | this.changed('updatedAt', true) | 533 | this.changed('updatedAt', true) |
500 | 534 | ||
diff --git a/server/models/video/video-query-builder.ts b/server/models/video/video-query-builder.ts index 96df0a7f8..4d95ddee2 100644 --- a/server/models/video/video-query-builder.ts +++ b/server/models/video/video-query-builder.ts | |||
@@ -490,12 +490,13 @@ function wrapForAPIResults (baseQuery: string, replacements: any, options: Build | |||
490 | 'INNER JOIN "actor" AS "VideoChannel->Account->Actor" ON "VideoChannel->Account"."actorId" = "VideoChannel->Account->Actor"."id"', | 490 | 'INNER JOIN "actor" AS "VideoChannel->Account->Actor" ON "VideoChannel->Account"."actorId" = "VideoChannel->Account->Actor"."id"', |
491 | 491 | ||
492 | 'LEFT OUTER JOIN "server" AS "VideoChannel->Actor->Server" ON "VideoChannel->Actor"."serverId" = "VideoChannel->Actor->Server"."id"', | 492 | 'LEFT OUTER JOIN "server" AS "VideoChannel->Actor->Server" ON "VideoChannel->Actor"."serverId" = "VideoChannel->Actor->Server"."id"', |
493 | 'LEFT OUTER JOIN "avatar" AS "VideoChannel->Actor->Avatar" ON "VideoChannel->Actor"."avatarId" = "VideoChannel->Actor->Avatar"."id"', | 493 | 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Actor->Avatar" ' + |
494 | 'ON "VideoChannel->Actor"."avatarId" = "VideoChannel->Actor->Avatar"."id"', | ||
494 | 495 | ||
495 | 'LEFT OUTER JOIN "server" AS "VideoChannel->Account->Actor->Server" ' + | 496 | 'LEFT OUTER JOIN "server" AS "VideoChannel->Account->Actor->Server" ' + |
496 | 'ON "VideoChannel->Account->Actor"."serverId" = "VideoChannel->Account->Actor->Server"."id"', | 497 | 'ON "VideoChannel->Account->Actor"."serverId" = "VideoChannel->Account->Actor->Server"."id"', |
497 | 498 | ||
498 | 'LEFT OUTER JOIN "avatar" AS "VideoChannel->Account->Actor->Avatar" ' + | 499 | 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Account->Actor->Avatar" ' + |
499 | 'ON "VideoChannel->Account->Actor"."avatarId" = "VideoChannel->Account->Actor->Avatar"."id"', | 500 | 'ON "VideoChannel->Account->Actor"."avatarId" = "VideoChannel->Account->Actor->Avatar"."id"', |
500 | 501 | ||
501 | 'LEFT OUTER JOIN "thumbnail" AS "Thumbnails" ON "video"."id" = "Thumbnails"."videoId"' | 502 | 'LEFT OUTER JOIN "thumbnail" AS "Thumbnails" ON "video"."id" = "Thumbnails"."videoId"' |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 3c4f3d3df..422bf6deb 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -24,7 +24,6 @@ import { | |||
24 | Table, | 24 | Table, |
25 | UpdatedAt | 25 | UpdatedAt |
26 | } from 'sequelize-typescript' | 26 | } from 'sequelize-typescript' |
27 | import { v4 as uuidv4 } from 'uuid' | ||
28 | import { buildNSFWFilter } from '@server/helpers/express-utils' | 27 | import { buildNSFWFilter } from '@server/helpers/express-utils' |
29 | import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video' | 28 | import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video' |
30 | import { LiveManager } from '@server/lib/live-manager' | 29 | import { LiveManager } from '@server/lib/live-manager' |
@@ -100,10 +99,10 @@ import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../types/models | |||
100 | import { VideoAbuseModel } from '../abuse/video-abuse' | 99 | import { VideoAbuseModel } from '../abuse/video-abuse' |
101 | import { AccountModel } from '../account/account' | 100 | import { AccountModel } from '../account/account' |
102 | import { AccountVideoRateModel } from '../account/account-video-rate' | 101 | import { AccountVideoRateModel } from '../account/account-video-rate' |
102 | import { ActorImageModel } from '../account/actor-image' | ||
103 | import { UserModel } from '../account/user' | 103 | import { UserModel } from '../account/user' |
104 | import { UserVideoHistoryModel } from '../account/user-video-history' | 104 | import { UserVideoHistoryModel } from '../account/user-video-history' |
105 | import { ActorModel } from '../activitypub/actor' | 105 | import { ActorModel } from '../activitypub/actor' |
106 | import { AvatarModel } from '../avatar/avatar' | ||
107 | import { VideoRedundancyModel } from '../redundancy/video-redundancy' | 106 | import { VideoRedundancyModel } from '../redundancy/video-redundancy' |
108 | import { ServerModel } from '../server/server' | 107 | import { ServerModel } from '../server/server' |
109 | import { TrackerModel } from '../server/tracker' | 108 | import { TrackerModel } from '../server/tracker' |
@@ -286,7 +285,8 @@ export type AvailableForListIDsOptions = { | |||
286 | required: false | 285 | required: false |
287 | }, | 286 | }, |
288 | { | 287 | { |
289 | model: AvatarModel.unscoped(), | 288 | model: ActorImageModel.unscoped(), |
289 | as: 'Avatar', | ||
290 | required: false | 290 | required: false |
291 | } | 291 | } |
292 | ] | 292 | ] |
@@ -308,7 +308,8 @@ export type AvailableForListIDsOptions = { | |||
308 | required: false | 308 | required: false |
309 | }, | 309 | }, |
310 | { | 310 | { |
311 | model: AvatarModel.unscoped(), | 311 | model: ActorImageModel.unscoped(), |
312 | as: 'Avatar', | ||
312 | required: false | 313 | required: false |
313 | } | 314 | } |
314 | ] | 315 | ] |
@@ -1703,7 +1704,7 @@ export class VideoModel extends Model { | |||
1703 | 1704 | ||
1704 | function buildActor (rowActor: any) { | 1705 | function buildActor (rowActor: any) { |
1705 | const avatarModel = rowActor.Avatar.id !== null | 1706 | const avatarModel = rowActor.Avatar.id !== null |
1706 | ? new AvatarModel(pick(rowActor.Avatar, avatarKeys), buildOpts) | 1707 | ? new ActorImageModel(pick(rowActor.Avatar, avatarKeys), buildOpts) |
1707 | : null | 1708 | : null |
1708 | 1709 | ||
1709 | const serverModel = rowActor.Server.id !== null | 1710 | const serverModel = rowActor.Server.id !== null |
@@ -1869,20 +1870,12 @@ export class VideoModel extends Model { | |||
1869 | this.Thumbnails.push(savedThumbnail) | 1870 | this.Thumbnails.push(savedThumbnail) |
1870 | } | 1871 | } |
1871 | 1872 | ||
1872 | generateThumbnailName () { | ||
1873 | return uuidv4() + '.jpg' | ||
1874 | } | ||
1875 | |||
1876 | getMiniature () { | 1873 | getMiniature () { |
1877 | if (Array.isArray(this.Thumbnails) === false) return undefined | 1874 | if (Array.isArray(this.Thumbnails) === false) return undefined |
1878 | 1875 | ||
1879 | return this.Thumbnails.find(t => t.type === ThumbnailType.MINIATURE) | 1876 | return this.Thumbnails.find(t => t.type === ThumbnailType.MINIATURE) |
1880 | } | 1877 | } |
1881 | 1878 | ||
1882 | generatePreviewName () { | ||
1883 | return uuidv4() + '.jpg' | ||
1884 | } | ||
1885 | |||
1886 | hasPreview () { | 1879 | hasPreview () { |
1887 | return !!this.getPreview() | 1880 | return !!this.getPreview() |
1888 | } | 1881 | } |
@@ -2034,9 +2027,11 @@ export class VideoModel extends Model { | |||
2034 | } | 2027 | } |
2035 | 2028 | ||
2036 | setAsRefreshed () { | 2029 | setAsRefreshed () { |
2037 | this.changed('updatedAt', true) | 2030 | const options = { |
2031 | where: { id: this.id } | ||
2032 | } | ||
2038 | 2033 | ||
2039 | return this.save() | 2034 | return VideoModel.update({ updatedAt: new Date() }, options) |
2040 | } | 2035 | } |
2041 | 2036 | ||
2042 | requiresAuth () { | 2037 | requiresAuth () { |