aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models
diff options
context:
space:
mode:
Diffstat (limited to 'server/models')
-rw-r--r--server/models/activitypub/actor-follow.ts7
-rw-r--r--server/models/activitypub/actor.ts47
-rw-r--r--server/models/video/video-channel.ts88
3 files changed, 87 insertions, 55 deletions
diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts
index ce6a4e267..4c5f37620 100644
--- a/server/models/activitypub/actor-follow.ts
+++ b/server/models/activitypub/actor-follow.ts
@@ -248,13 +248,6 @@ export class ActorFollowModel extends Model {
248 } 248 }
249 249
250 return ActorFollowModel.findOne(query) 250 return ActorFollowModel.findOne(query)
251 .then(result => {
252 if (result?.ActorFollowing.VideoChannel) {
253 result.ActorFollowing.VideoChannel.Actor = result.ActorFollowing
254 }
255
256 return result
257 })
258 } 251 }
259 252
260 static listSubscribedIn (actorId: number, targets: { name: string, host?: string }[]): Promise<MActorFollowFollowingHost[]> { 253 static listSubscribedIn (actorId: number, targets: { name: string, host?: string }[]): Promise<MActorFollowFollowingHost[]> {
diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts
index 09d96b24d..6595f11e2 100644
--- a/server/models/activitypub/actor.ts
+++ b/server/models/activitypub/actor.ts
@@ -29,11 +29,19 @@ import {
29 isActorPublicKeyValid 29 isActorPublicKeyValid
30} from '../../helpers/custom-validators/activitypub/actor' 30} from '../../helpers/custom-validators/activitypub/actor'
31import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 31import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
32import { ACTIVITY_PUB, ACTIVITY_PUB_ACTOR_TYPES, CONSTRAINTS_FIELDS, SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants' 32import {
33 ACTIVITY_PUB,
34 ACTIVITY_PUB_ACTOR_TYPES,
35 CONSTRAINTS_FIELDS,
36 MIMETYPES,
37 SERVER_ACTOR_NAME,
38 WEBSERVER
39} from '../../initializers/constants'
33import { 40import {
34 MActor, 41 MActor,
35 MActorAccountChannelId, 42 MActorAccountChannelId,
36 MActorAP, 43 MActorAPAccount,
44 MActorAPChannel,
37 MActorFormattable, 45 MActorFormattable,
38 MActorFull, 46 MActorFull,
39 MActorHost, 47 MActorHost,
@@ -104,6 +112,11 @@ export const unusedActorAttributesForAPI = [
104 model: ActorImageModel, 112 model: ActorImageModel,
105 as: 'Avatar', 113 as: 'Avatar',
106 required: false 114 required: false
115 },
116 {
117 model: ActorImageModel,
118 as: 'Banner',
119 required: false
107 } 120 }
108 ] 121 ]
109 } 122 }
@@ -531,29 +544,46 @@ export class ActorModel extends Model {
531 toFormattedJSON (this: MActorFormattable) { 544 toFormattedJSON (this: MActorFormattable) {
532 const base = this.toFormattedSummaryJSON() 545 const base = this.toFormattedSummaryJSON()
533 546
547 let banner: ActorImage = null
548 if (this.bannerId) {
549 banner = this.Banner.toFormattedJSON()
550 }
551
534 return Object.assign(base, { 552 return Object.assign(base, {
535 id: this.id, 553 id: this.id,
536 hostRedundancyAllowed: this.getRedundancyAllowed(), 554 hostRedundancyAllowed: this.getRedundancyAllowed(),
537 followingCount: this.followingCount, 555 followingCount: this.followingCount,
538 followersCount: this.followersCount, 556 followersCount: this.followersCount,
557 banner,
539 createdAt: this.createdAt, 558 createdAt: this.createdAt,
540 updatedAt: this.updatedAt 559 updatedAt: this.updatedAt
541 }) 560 })
542 } 561 }
543 562
544 toActivityPubObject (this: MActorAP, name: string) { 563 toActivityPubObject (this: MActorAPChannel | MActorAPAccount, name: string) {
545 let icon: ActivityIconObject 564 let icon: ActivityIconObject
565 let image: ActivityIconObject
546 566
547 if (this.avatarId) { 567 if (this.avatarId) {
548 const extension = extname(this.Avatar.filename) 568 const extension = extname(this.Avatar.filename)
549 569
550 icon = { 570 icon = {
551 type: 'Image', 571 type: 'Image',
552 mediaType: extension === '.png' ? 'image/png' : 'image/jpeg', 572 mediaType: MIMETYPES.IMAGE.EXT_MIMETYPE[extension],
553 url: this.getAvatarUrl() 573 url: this.getAvatarUrl()
554 } 574 }
555 } 575 }
556 576
577 if (this.bannerId) {
578 const extension = extname((this as MActorAPChannel).Banner.filename)
579
580 image = {
581 type: 'Image',
582 mediaType: MIMETYPES.IMAGE.EXT_MIMETYPE[extension],
583 url: this.getBannerUrl()
584 }
585 }
586
557 const json = { 587 const json = {
558 type: this.type, 588 type: this.type,
559 id: this.url, 589 id: this.url,
@@ -573,7 +603,8 @@ export class ActorModel extends Model {
573 owner: this.url, 603 owner: this.url,
574 publicKeyPem: this.publicKey 604 publicKeyPem: this.publicKey
575 }, 605 },
576 icon 606 icon,
607 image
577 } 608 }
578 609
579 return activityPubContextify(json) 610 return activityPubContextify(json)
@@ -643,6 +674,12 @@ export class ActorModel extends Model {
643 return WEBSERVER.URL + this.Avatar.getStaticPath() 674 return WEBSERVER.URL + this.Avatar.getStaticPath()
644 } 675 }
645 676
677 getBannerUrl () {
678 if (!this.bannerId) return undefined
679
680 return WEBSERVER.URL + this.Banner.getStaticPath()
681 }
682
646 isOutdated () { 683 isOutdated () {
647 if (this.isOwned()) return false 684 if (this.isOwned()) return false
648 685
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index 815fb16c0..74885edfb 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -28,10 +28,9 @@ import {
28import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants' 28import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants'
29import { sendDeleteActor } from '../../lib/activitypub/send' 29import { sendDeleteActor } from '../../lib/activitypub/send'
30import { 30import {
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'
@@ -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}
@@ -168,6 +168,20 @@ export type SummaryOptions = {
168 ActorModel 168 ActorModel
169 ] 169 ]
170 }, 170 },
171 [ScopeNames.WITH_ACTOR_BANNER]: {
172 include: [
173 {
174 model: ActorModel,
175 include: [
176 {
177 model: ActorImageModel,
178 required: false,
179 as: 'Banner'
180 }
181 ]
182 }
183 ]
184 },
171 [ScopeNames.WITH_VIDEOS]: { 185 [ScopeNames.WITH_VIDEOS]: {
172 include: [ 186 include: [
173 VideoModel 187 VideoModel
@@ -442,7 +456,7 @@ export class VideoChannelModel extends Model {
442 where 456 where
443 } 457 }
444 458
445 const scopes: string | ScopeOptions | (string | ScopeOptions)[] = [ ScopeNames.WITH_ACTOR ] 459 const scopes: string | ScopeOptions | (string | ScopeOptions)[] = [ ScopeNames.WITH_ACTOR_BANNER ]
446 460
447 if (options.withStats === true) { 461 if (options.withStats === true) {
448 scopes.push({ 462 scopes.push({
@@ -458,32 +472,13 @@ export class VideoChannelModel extends Model {
458 }) 472 })
459 } 473 }
460 474
461 static loadByIdAndPopulateAccount (id: number): Promise<MChannelAccountDefault> { 475 static loadAndPopulateAccount (id: number): Promise<MChannelBannerAccountDefault> {
462 return VideoChannelModel.unscoped()
463 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
464 .findByPk(id)
465 }
466
467 static loadByIdAndAccount (id: number, accountId: number): Promise<MChannelAccountDefault> {
468 const query = {
469 where: {
470 id,
471 accountId
472 }
473 }
474
475 return VideoChannelModel.unscoped()
476 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
477 .findOne(query)
478 }
479
480 static loadAndPopulateAccount (id: number): Promise<MChannelAccountDefault> {
481 return VideoChannelModel.unscoped() 476 return VideoChannelModel.unscoped()
482 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) 477 .scope([ ScopeNames.WITH_ACTOR_BANNER, ScopeNames.WITH_ACCOUNT ])
483 .findByPk(id) 478 .findByPk(id)
484 } 479 }
485 480
486 static loadByUrlAndPopulateAccount (url: string): Promise<MChannelAccountDefault> { 481 static loadByUrlAndPopulateAccount (url: string): Promise<MChannelBannerAccountDefault> {
487 const query = { 482 const query = {
488 include: [ 483 include: [
489 { 484 {
@@ -491,7 +486,14 @@ export class VideoChannelModel extends Model {
491 required: true, 486 required: true,
492 where: { 487 where: {
493 url 488 url
494 } 489 },
490 include: [
491 {
492 model: ActorImageModel,
493 required: false,
494 as: 'Banner'
495 }
496 ]
495 } 497 }
496 ] 498 ]
497 } 499 }
@@ -509,7 +511,7 @@ export class VideoChannelModel extends Model {
509 return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host) 511 return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host)
510 } 512 }
511 513
512 static loadLocalByNameAndPopulateAccount (name: string): Promise<MChannelAccountDefault> { 514 static loadLocalByNameAndPopulateAccount (name: string): Promise<MChannelBannerAccountDefault> {
513 const query = { 515 const query = {
514 include: [ 516 include: [
515 { 517 {
@@ -518,17 +520,24 @@ export class VideoChannelModel extends Model {
518 where: { 520 where: {
519 preferredUsername: name, 521 preferredUsername: name,
520 serverId: null 522 serverId: null
521 } 523 },
524 include: [
525 {
526 model: ActorImageModel,
527 required: false,
528 as: 'Banner'
529 }
530 ]
522 } 531 }
523 ] 532 ]
524 } 533 }
525 534
526 return VideoChannelModel.unscoped() 535 return VideoChannelModel.unscoped()
527 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) 536 .scope([ ScopeNames.WITH_ACCOUNT ])
528 .findOne(query) 537 .findOne(query)
529 } 538 }
530 539
531 static loadByNameAndHostAndPopulateAccount (name: string, host: string): Promise<MChannelAccountDefault> { 540 static loadByNameAndHostAndPopulateAccount (name: string, host: string): Promise<MChannelBannerAccountDefault> {
532 const query = { 541 const query = {
533 include: [ 542 include: [
534 { 543 {
@@ -542,6 +551,11 @@ export class VideoChannelModel extends Model {
542 model: ServerModel, 551 model: ServerModel,
543 required: true, 552 required: true,
544 where: { host } 553 where: { host }
554 },
555 {
556 model: ActorImageModel,
557 required: false,
558 as: 'Banner'
545 } 559 }
546 ] 560 ]
547 } 561 }
@@ -549,22 +563,10 @@ export class VideoChannelModel extends Model {
549 } 563 }
550 564
551 return VideoChannelModel.unscoped() 565 return VideoChannelModel.unscoped()
552 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) 566 .scope([ ScopeNames.WITH_ACCOUNT ])
553 .findOne(query) 567 .findOne(query)
554 } 568 }
555 569
556 static loadAndPopulateAccountAndVideos (id: number): Promise<MChannelActorAccountDefaultVideos> {
557 const options = {
558 include: [
559 VideoModel
560 ]
561 }
562
563 return VideoChannelModel.unscoped()
564 .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ])
565 .findByPk(id, options)
566 }
567
568 toFormattedSummaryJSON (this: MChannelSummaryFormattable): VideoChannelSummary { 570 toFormattedSummaryJSON (this: MChannelSummaryFormattable): VideoChannelSummary {
569 const actor = this.Actor.toFormattedSummaryJSON() 571 const actor = this.Actor.toFormattedSummaryJSON()
570 572