From de6310b2fcbb8a6b79c546b23dfa1920724faaa7 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 17 Sep 2020 13:59:02 +0200 Subject: [PATCH] Handle live federation --- server/controllers/api/videos/index.ts | 1 - .../custom-validators/activitypub/videos.ts | 1 + .../lib/activitypub/process/process-create.ts | 4 ++-- .../lib/activitypub/process/process-update.ts | 4 ++-- server/lib/activitypub/videos.ts | 22 +++++++++---------- server/lib/moderation.ts | 4 ++-- server/models/video/video-format-utils.ts | 5 +++-- server/models/video/video.ts | 4 ++-- shared/models/activitypub/activity.ts | 6 ++--- .../objects/video-torrent-object.ts | 5 ++++- 10 files changed, 30 insertions(+), 26 deletions(-) diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 1539afc35..6357062bc 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -55,7 +55,6 @@ import { videosUpdateValidator } from '../../../middlewares' import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update' -import { TagModel } from '../../../models/video/tag' import { VideoModel } from '../../../models/video/video' import { VideoFileModel } from '../../../models/video/video-file' import { abuseVideoRouter } from './abuse' diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index 876cc7f50..7ff551ecd 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts @@ -62,6 +62,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) { if (!isBooleanValid(video.waitTranscoding)) video.waitTranscoding = false if (!isBooleanValid(video.downloadEnabled)) video.downloadEnabled = true if (!isBooleanValid(video.commentsEnabled)) video.commentsEnabled = false + if (!isBooleanValid(video.isLiveBroadcast)) video.isLiveBroadcast = false return isActivityPubUrlValid(video.id) && isVideoNameValid(video.name) && diff --git a/server/lib/activitypub/process/process-create.ts b/server/lib/activitypub/process/process-create.ts index 74f1032e2..f84992489 100644 --- a/server/lib/activitypub/process/process-create.ts +++ b/server/lib/activitypub/process/process-create.ts @@ -1,5 +1,5 @@ import { isRedundancyAccepted } from '@server/lib/redundancy' -import { ActivityCreate, CacheFileObject, VideoTorrentObject } from '../../../../shared' +import { ActivityCreate, CacheFileObject, VideoObject } from '../../../../shared' import { PlaylistObject } from '../../../../shared/models/activitypub/objects/playlist-object' import { VideoCommentObject } from '../../../../shared/models/activitypub/objects/video-comment-object' import { retryTransactionWrapper } from '../../../helpers/database-utils' @@ -52,7 +52,7 @@ export { // --------------------------------------------------------------------------- async function processCreateVideo (activity: ActivityCreate, notify: boolean) { - const videoToCreateData = activity.object as VideoTorrentObject + const videoToCreateData = activity.object as VideoObject const syncParam = { likes: false, dislikes: false, shares: false, comments: false, thumbnail: true, refreshVideo: false } const { video, created } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoToCreateData, syncParam }) diff --git a/server/lib/activitypub/process/process-update.ts b/server/lib/activitypub/process/process-update.ts index 1bdf23d6f..6d2fff3fe 100644 --- a/server/lib/activitypub/process/process-update.ts +++ b/server/lib/activitypub/process/process-update.ts @@ -1,4 +1,4 @@ -import { ActivityUpdate, CacheFileObject, VideoTorrentObject } from '../../../../shared/models/activitypub' +import { ActivityUpdate, CacheFileObject, VideoObject } from '../../../../shared/models/activitypub' import { ActivityPubActor } from '../../../../shared/models/activitypub/activitypub-actor' import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils' import { logger } from '../../../helpers/logger' @@ -55,7 +55,7 @@ export { // --------------------------------------------------------------------------- async function processUpdateVideo (actor: MActorSignature, activity: ActivityUpdate) { - const videoObject = activity.object as VideoTorrentObject + const videoObject = activity.object as VideoObject if (sanitizeAndCheckVideoTorrentObject(videoObject) === false) { logger.debug('Video sent by update is not valid.', { videoObject }) diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index 096884776..049e06cff 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts @@ -15,7 +15,7 @@ import { ActivityVideoUrlObject, VideoState } from '../../../shared/index' -import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' +import { VideoObject } from '../../../shared/models/activitypub/objects' import { VideoPrivacy } from '../../../shared/models/videos' import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' @@ -38,7 +38,6 @@ import { } from '../../initializers/constants' import { sequelizeTypescript } from '../../initializers/database' import { AccountVideoRateModel } from '../../models/account/account-video-rate' -import { TagModel } from '../../models/video/tag' import { VideoModel } from '../../models/video/video' import { VideoCaptionModel } from '../../models/video/video-caption' import { VideoCommentModel } from '../../models/video/video-comment' @@ -104,7 +103,7 @@ async function federateVideoIfNeeded (videoArg: MVideoAPWithoutCaption, isNewVid } } -async function fetchRemoteVideo (videoUrl: string): Promise<{ response: request.RequestResponse, videoObject: VideoTorrentObject }> { +async function fetchRemoteVideo (videoUrl: string): Promise<{ response: request.RequestResponse, videoObject: VideoObject }> { const options = { uri: videoUrl, method: 'GET', @@ -136,7 +135,7 @@ async function fetchRemoteVideoDescription (video: MVideoAccountLight) { return body.description ? body.description : '' } -function getOrCreateVideoChannelFromVideoObject (videoObject: VideoTorrentObject) { +function getOrCreateVideoChannelFromVideoObject (videoObject: VideoObject) { const channel = videoObject.attributedTo.find(a => a.type === 'Group') if (!channel) throw new Error('Cannot find associated video channel to video ' + videoObject.url) @@ -155,7 +154,7 @@ type SyncParam = { thumbnail: boolean refreshVideo?: boolean } -async function syncVideoExternalAttributes (video: MVideo, fetchedVideo: VideoTorrentObject, syncParam: SyncParam) { +async function syncVideoExternalAttributes (video: MVideo, fetchedVideo: VideoObject, syncParam: SyncParam) { logger.info('Adding likes/dislikes/shares/comments of video %s.', video.uuid) const jobPayloads: ActivitypubHttpFetcherPayload[] = [] @@ -294,7 +293,7 @@ async function getOrCreateVideoAndAccountAndChannel ( async function updateVideoFromAP (options: { video: MVideoAccountLightBlacklistAllFiles - videoObject: VideoTorrentObject + videoObject: VideoObject account: MAccountIdActor channel: MChannelDefault overrideTo?: string[] @@ -538,7 +537,7 @@ function isAPHashTagObject (url: any): url is ActivityHashTagObject { return url && url.type === 'Hashtag' } -async function createVideo (videoObject: VideoTorrentObject, channel: MChannelAccountLight, waitThumbnail = false) { +async function createVideo (videoObject: VideoObject, channel: MChannelAccountLight, waitThumbnail = false) { logger.debug('Adding remote video %s.', videoObject.id) const videoData = await videoActivityObjectToDBAttributes(channel, videoObject, videoObject.to) @@ -632,7 +631,7 @@ async function createVideo (videoObject: VideoTorrentObject, channel: MChannelAc return { autoBlacklisted, videoCreated } } -function videoActivityObjectToDBAttributes (videoChannel: MChannelId, videoObject: VideoTorrentObject, to: string[] = []) { +function videoActivityObjectToDBAttributes (videoChannel: MChannelId, videoObject: VideoObject, to: string[] = []) { const privacy = to.includes(ACTIVITY_PUB.PUBLIC) ? VideoPrivacy.PUBLIC : VideoPrivacy.UNLISTED @@ -664,6 +663,7 @@ function videoActivityObjectToDBAttributes (videoChannel: MChannelId, videoObjec commentsEnabled: videoObject.commentsEnabled, downloadEnabled: videoObject.downloadEnabled, waitTranscoding: videoObject.waitTranscoding, + isLive: videoObject.isLiveBroadcast, state: videoObject.state, channelId: videoChannel.id, duration: parseInt(duration, 10), @@ -732,7 +732,7 @@ function videoFileActivityUrlToDBAttributes ( return attributes } -function streamingPlaylistActivityUrlToDBAttributes (video: MVideoId, videoObject: VideoTorrentObject, videoFiles: MVideoFile[]) { +function streamingPlaylistActivityUrlToDBAttributes (video: MVideoId, videoObject: VideoObject, videoFiles: MVideoFile[]) { const playlistUrls = videoObject.url.filter(u => isAPStreamingPlaylistUrlObject(u)) as ActivityPlaylistUrlObject[] if (playlistUrls.length === 0) return [] @@ -766,7 +766,7 @@ function streamingPlaylistActivityUrlToDBAttributes (video: MVideoId, videoObjec return attributes } -function getThumbnailFromIcons (videoObject: VideoTorrentObject) { +function getThumbnailFromIcons (videoObject: VideoObject) { let validIcons = videoObject.icon.filter(i => i.width > THUMBNAILS_SIZE.minWidth) // Fallback if there are not valid icons if (validIcons.length === 0) validIcons = videoObject.icon @@ -774,7 +774,7 @@ function getThumbnailFromIcons (videoObject: VideoTorrentObject) { return minBy(validIcons, 'width') } -function getPreviewFromIcons (videoObject: VideoTorrentObject) { +function getPreviewFromIcons (videoObject: VideoObject) { const validIcons = videoObject.icon.filter(i => i.width > PREVIEWS_SIZE.minWidth) // FIXME: don't put a fallback here for compatibility with PeerTube <2.2 diff --git a/server/lib/moderation.ts b/server/lib/moderation.ts index b140d5aa9..0ef26d53d 100644 --- a/server/lib/moderation.ts +++ b/server/lib/moderation.ts @@ -18,7 +18,7 @@ import { MVideoAccountLightBlacklistAllFiles } from '@server/types/models' import { ActivityCreate } from '../../shared/models/activitypub' -import { VideoTorrentObject } from '../../shared/models/activitypub/objects' +import { VideoObject } from '../../shared/models/activitypub/objects' import { VideoCommentObject } from '../../shared/models/activitypub/objects/video-comment-object' import { VideoCreate, VideoImportCreate } from '../../shared/models/videos' import { VideoCommentCreate } from '../../shared/models/videos/video-comment.model' @@ -62,7 +62,7 @@ function isLocalVideoCommentReplyAccepted (_object: { function isRemoteVideoAccepted (_object: { activity: ActivityCreate - videoAP: VideoTorrentObject + videoAP: VideoObject byActor: ActorModel }): AcceptResult { return { accepted: true } diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts index 0dbd92a43..92bde7773 100644 --- a/server/models/video/video-format-utils.ts +++ b/server/models/video/video-format-utils.ts @@ -1,6 +1,6 @@ import { Video, VideoDetails } from '../../../shared/models/videos' import { VideoModel } from './video' -import { ActivityTagObject, ActivityUrlObject, VideoTorrentObject } from '../../../shared/models/activitypub/objects' +import { ActivityTagObject, ActivityUrlObject, VideoObject } from '../../../shared/models/activitypub/objects' import { MIMETYPES, WEBSERVER } from '../../initializers/constants' import { VideoCaptionModel } from './video-caption' import { @@ -262,7 +262,7 @@ function addVideoFilesInAPAcc ( } } -function videoModelToActivityPubObject (video: MVideoAP): VideoTorrentObject { +function videoModelToActivityPubObject (video: MVideoAP): VideoObject { const { baseUrlHttp, baseUrlWs } = video.getBaseUrls() if (!video.Tags) video.Tags = [] @@ -351,6 +351,7 @@ function videoModelToActivityPubObject (video: MVideoAP): VideoTorrentObject { views: video.views, sensitive: video.nsfw, waitTranscoding: video.waitTranscoding, + isLiveBroadcast: video.isLive, state: video.state, commentsEnabled: video.commentsEnabled, downloadEnabled: video.downloadEnabled, diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 1037730e3..a3e3b6cfe 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts @@ -31,7 +31,7 @@ import { getServerActor } from '@server/models/application/application' import { ModelCache } from '@server/models/model-cache' import { VideoFile } from '@shared/models/videos/video-file.model' import { ResultList, UserRight, VideoPrivacy, VideoState } from '../../../shared' -import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' +import { VideoObject } from '../../../shared/models/activitypub/objects' import { Video, VideoDetails } from '../../../shared/models/videos' import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' import { VideoFilter } from '../../../shared/models/videos/video-query.type' @@ -1763,7 +1763,7 @@ export class VideoModel extends Model { return videoFilesModelToFormattedJSON(this, baseUrlHttp, baseUrlWs, files) } - toActivityPubObject (this: MVideoAP): VideoTorrentObject { + toActivityPubObject (this: MVideoAP): VideoObject { return videoModelToActivityPubObject(this) } diff --git a/shared/models/activitypub/activity.ts b/shared/models/activitypub/activity.ts index 5b4ce214a..548d8858e 100644 --- a/shared/models/activitypub/activity.ts +++ b/shared/models/activitypub/activity.ts @@ -1,6 +1,6 @@ import { ActivityPubActor } from './activitypub-actor' import { ActivityPubSignature } from './activitypub-signature' -import { ActivityFlagReasonObject, CacheFileObject, VideoTorrentObject } from './objects' +import { ActivityFlagReasonObject, CacheFileObject, VideoObject } from './objects' import { AbuseObject } from './objects/abuse-object' import { DislikeObject } from './objects/dislike-object' import { APObject } from './objects/object.model' @@ -53,12 +53,12 @@ export interface BaseActivity { export interface ActivityCreate extends BaseActivity { type: 'Create' - object: VideoTorrentObject | AbuseObject | ViewObject | DislikeObject | VideoCommentObject | CacheFileObject | PlaylistObject + object: VideoObject | AbuseObject | ViewObject | DislikeObject | VideoCommentObject | CacheFileObject | PlaylistObject } export interface ActivityUpdate extends BaseActivity { type: 'Update' - object: VideoTorrentObject | ActivityPubActor | CacheFileObject | PlaylistObject + object: VideoObject | ActivityPubActor | CacheFileObject | PlaylistObject } export interface ActivityDelete extends BaseActivity { diff --git a/shared/models/activitypub/objects/video-torrent-object.ts b/shared/models/activitypub/objects/video-torrent-object.ts index 11de8fc56..5b035a371 100644 --- a/shared/models/activitypub/objects/video-torrent-object.ts +++ b/shared/models/activitypub/objects/video-torrent-object.ts @@ -7,7 +7,7 @@ import { } from './common-objects' import { VideoState } from '../../videos' -export interface VideoTorrentObject { +export interface VideoObject { type: 'Video' id: string name: string @@ -19,7 +19,10 @@ export interface VideoTorrentObject { language: ActivityIdentifierObject subtitleLanguage: ActivityIdentifierObject[] views: number + sensitive: boolean + isLiveBroadcast: boolean + commentsEnabled: boolean downloadEnabled: boolean waitTranscoding: boolean -- 2.41.0