From: Chocobozzz Date: Thu, 23 Apr 2020 07:32:53 +0000 (+0200) Subject: Avoir some circular dependencies X-Git-Tag: v2.2.0-rc.1~117 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=8dc8a34ee8428e7657414115d1c137592efa174d;p=oweals%2Fpeertube.git Avoir some circular dependencies --- diff --git a/scripts/create-transcoding-job.ts b/scripts/create-transcoding-job.ts index fec58da2e..1312e8952 100755 --- a/scripts/create-transcoding-job.ts +++ b/scripts/create-transcoding-job.ts @@ -5,8 +5,8 @@ import * as program from 'commander' import { VideoModel } from '../server/models/video/video' import { initDatabaseModels } from '../server/initializers' import { JobQueue } from '../server/lib/job-queue' -import { VideoTranscodingPayload } from '../server/lib/job-queue/handlers/video-transcoding' import { computeResolutionsToTranscode } from '@server/helpers/ffmpeg-utils' +import { VideoTranscodingPayload } from '@shared/models' program .option('-v, --video [videoUUID]', 'Video UUID') diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index c3aeeebf5..e44f1c6ab 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts @@ -24,20 +24,20 @@ import { cacheRoute } from '../../middlewares/cache' import { activityPubResponse } from './utils' import { AccountVideoRateModel } from '../../models/account/account-video-rate' import { - getRateUrl, getVideoCommentsActivityPubUrl, getVideoDislikesActivityPubUrl, getVideoLikesActivityPubUrl, getVideoSharesActivityPubUrl -} from '../../lib/activitypub' +} from '../../lib/activitypub/url' import { VideoCaptionModel } from '../../models/video/video-caption' import { videoFileRedundancyGetValidator, videoPlaylistRedundancyGetValidator } from '../../middlewares/validators/redundancy' -import { getServerActor } from '../../helpers/utils' import { buildDislikeActivity } from '../../lib/activitypub/send/send-dislike' import { videoPlaylistElementAPGetValidator, videoPlaylistsGetValidator } from '../../middlewares/validators/videos/video-playlists' import { VideoPlaylistModel } from '../../models/video/video-playlist' import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model' import { MAccountId, MActorId, MVideoAPWithoutCaption, MVideoId } from '@server/typings/models' +import { getServerActor } from '@server/models/application/application' +import { getRateUrl } from '@server/lib/activitypub/video-rates' const activityPubClientRouter = express.Router() activityPubClientRouter.use(cors()) diff --git a/server/controllers/api/accounts.ts b/server/controllers/api/accounts.ts index f8d2bad8b..3bbb0a43e 100644 --- a/server/controllers/api/accounts.ts +++ b/server/controllers/api/accounts.ts @@ -1,5 +1,5 @@ import * as express from 'express' -import { getFormattedObjects, getServerActor } from '../../helpers/utils' +import { getFormattedObjects} from '../../helpers/utils' import { asyncMiddleware, authenticate, @@ -28,6 +28,7 @@ import { VideoChannelModel } from '../../models/video/video-channel' import { JobQueue } from '../../lib/job-queue' import { VideoPlaylistModel } from '../../models/video/video-playlist' import { commonVideoPlaylistFiltersValidator, videoPlaylistsSearchValidator } from '../../middlewares/validators/videos/video-playlists' +import { getServerActor } from '@server/models/application/application' const accountsRouter = express.Router() diff --git a/server/controllers/api/search.ts b/server/controllers/api/search.ts index 16ffbf683..35d94d747 100644 --- a/server/controllers/api/search.ts +++ b/server/controllers/api/search.ts @@ -1,6 +1,6 @@ import * as express from 'express' import { buildNSFWFilter, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' -import { getFormattedObjects, getServerActor } from '../../helpers/utils' +import { getFormattedObjects } from '../../helpers/utils' import { VideoModel } from '../../models/video/video' import { asyncMiddleware, @@ -15,11 +15,13 @@ import { videosSearchValidator } from '../../middlewares' import { VideoChannelsSearchQuery, VideosSearchQuery } from '../../../shared/models/search' -import { getOrCreateActorAndServerAndModel, getOrCreateVideoAndAccountAndChannel } from '../../lib/activitypub' +import { getOrCreateActorAndServerAndModel } from '../../lib/activitypub/actor' import { logger } from '../../helpers/logger' import { VideoChannelModel } from '../../models/video/video-channel' import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger' import { MChannelAccountDefault, MVideoAccountLightBlacklistAllFiles } from '../../typings/models' +import { getServerActor } from '@server/models/application/application' +import { getOrCreateVideoAndAccountAndChannel } from '@server/lib/activitypub/videos' const searchRouter = express.Router() diff --git a/server/controllers/api/server/follows.ts b/server/controllers/api/server/follows.ts index 0bc20bd60..82e9ef898 100644 --- a/server/controllers/api/server/follows.ts +++ b/server/controllers/api/server/follows.ts @@ -1,7 +1,7 @@ import * as express from 'express' import { UserRight } from '../../../../shared/models/users' import { logger } from '../../../helpers/logger' -import { getFormattedObjects, getServerActor } from '../../../helpers/utils' +import { getFormattedObjects} from '../../../helpers/utils' import { SERVER_ACTOR_NAME } from '../../../initializers/constants' import { sendAccept, sendReject, sendUndoFollow } from '../../../lib/activitypub/send' import { @@ -27,6 +27,7 @@ import { JobQueue } from '../../../lib/job-queue' import { removeRedundanciesOfServer } from '../../../lib/redundancy' import { sequelizeTypescript } from '../../../initializers/database' import { autoFollowBackIfNeeded } from '../../../lib/activitypub/follow' +import { getServerActor } from '@server/models/application/application' const serverFollowsRouter = express.Router() serverFollowsRouter.get('/following', diff --git a/server/controllers/api/server/server-blocklist.ts b/server/controllers/api/server/server-blocklist.ts index ffb7814fa..008b8d4ea 100644 --- a/server/controllers/api/server/server-blocklist.ts +++ b/server/controllers/api/server/server-blocklist.ts @@ -1,6 +1,6 @@ import * as express from 'express' import 'multer' -import { getFormattedObjects, getServerActor } from '../../../helpers/utils' +import { getFormattedObjects} from '../../../helpers/utils' import { asyncMiddleware, asyncRetryTransactionMiddleware, @@ -22,6 +22,7 @@ import { AccountBlocklistModel } from '../../../models/account/account-blocklist import { addAccountInBlocklist, addServerInBlocklist, removeAccountFromBlocklist, removeServerFromBlocklist } from '../../../lib/blocklist' import { ServerBlocklistModel } from '../../../models/server/server-blocklist' import { UserRight } from '../../../../shared/models/users' +import { getServerActor } from '@server/models/application/application' const serverBlocklistRouter = express.Router() diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts index a808896ff..faef5ba4b 100644 --- a/server/controllers/api/video-channel.ts +++ b/server/controllers/api/video-channel.ts @@ -1,5 +1,5 @@ import * as express from 'express' -import { getFormattedObjects, getServerActor } from '../../helpers/utils' +import { getFormattedObjects} from '../../helpers/utils' import { asyncMiddleware, asyncRetryTransactionMiddleware, @@ -21,7 +21,7 @@ import { sendUpdateActor } from '../../lib/activitypub/send' import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared' import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' import { buildNSFWFilter, createReqFiles, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' -import { setAsyncActorKeys } from '../../lib/activitypub' +import { setAsyncActorKeys } from '../../lib/activitypub/actor' import { AccountModel } from '../../models/account/account' import { MIMETYPES } from '../../initializers/constants' import { logger } from '../../helpers/logger' @@ -36,6 +36,7 @@ import { commonVideoPlaylistFiltersValidator } from '../../middlewares/validator import { CONFIG } from '../../initializers/config' import { sequelizeTypescript } from '../../initializers/database' import { MChannelAccountDefault } from '@server/typings/models' +import { getServerActor } from '@server/models/application/application' const auditLogger = auditLoggerFactory('channels') const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR }) diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index aa9053372..49ac3c80e 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts @@ -1,5 +1,5 @@ import * as express from 'express' -import { getFormattedObjects, getServerActor } from '../../helpers/utils' +import { getFormattedObjects} from '../../helpers/utils' import { asyncMiddleware, asyncRetryTransactionMiddleware, @@ -41,6 +41,7 @@ import { CONFIG } from '../../initializers/config' import { sequelizeTypescript } from '../../initializers/database' import { createPlaylistMiniatureFromExisting } from '../../lib/thumbnail' import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/typings/models' +import { getServerActor } from '@server/models/application/application' const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR }) diff --git a/server/controllers/api/videos/abuse.ts b/server/controllers/api/videos/abuse.ts index f37d90896..bc7df48c8 100644 --- a/server/controllers/api/videos/abuse.ts +++ b/server/controllers/api/videos/abuse.ts @@ -1,7 +1,7 @@ import * as express from 'express' import { UserRight, VideoAbuseCreate, VideoAbuseState } from '../../../../shared' import { logger } from '../../../helpers/logger' -import { getFormattedObjects, getServerActor } from '../../../helpers/utils' +import { getFormattedObjects } from '../../../helpers/utils' import { sequelizeTypescript } from '../../../initializers' import { asyncMiddleware, @@ -22,6 +22,7 @@ import { auditLoggerFactory, VideoAbuseAuditView } from '../../../helpers/audit- import { Notifier } from '../../../lib/notifier' import { sendVideoAbuse } from '../../../lib/activitypub/send/send-flag' import { MVideoAbuseAccountVideo } from '../../../typings/models/video' +import { getServerActor } from '@server/models/application/application' const auditLogger = auditLoggerFactory('abuse') const abuseVideoRouter = express.Router() diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts index c4aa79cd2..abd09387c 100644 --- a/server/controllers/api/videos/blacklist.ts +++ b/server/controllers/api/videos/blacklist.ts @@ -19,7 +19,7 @@ import { VideoBlacklistModel } from '../../../models/video/video-blacklist' import { sequelizeTypescript } from '../../../initializers' import { Notifier } from '../../../lib/notifier' import { sendDeleteVideo } from '../../../lib/activitypub/send' -import { federateVideoIfNeeded } from '../../../lib/activitypub' +import { federateVideoIfNeeded } from '../../../lib/activitypub/videos' import { MVideoBlacklistVideo } from '@server/typings/models' const blacklistRouter = express.Router() diff --git a/server/controllers/api/videos/captions.ts b/server/controllers/api/videos/captions.ts index fd7b165fb..8c1d12ca8 100644 --- a/server/controllers/api/videos/captions.ts +++ b/server/controllers/api/videos/captions.ts @@ -6,7 +6,7 @@ import { MIMETYPES } from '../../../initializers/constants' import { getFormattedObjects } from '../../../helpers/utils' import { VideoCaptionModel } from '../../../models/video/video-caption' import { logger } from '../../../helpers/logger' -import { federateVideoIfNeeded } from '../../../lib/activitypub' +import { federateVideoIfNeeded } from '../../../lib/activitypub/videos' import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils' import { CONFIG } from '../../../initializers/config' import { sequelizeTypescript } from '../../../initializers/database' diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index be96ef42c..b4f70a086 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts @@ -10,7 +10,7 @@ import { VideoImportCreate, VideoImportState, VideoPrivacy, VideoState } from '. import { VideoModel } from '../../../models/video/video' import { VideoCaptionModel } from '../../../models/video/video-caption' import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils' -import { getVideoActivityPubUrl } from '../../../lib/activitypub' +import { getVideoActivityPubUrl } from '../../../lib/activitypub/url' import { TagModel } from '../../../models/video/tag' import { VideoImportModel } from '../../../models/video/video-import' import { JobQueue } from '../../../lib/job-queue/job-queue' diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 04d775cbf..8048c568c 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -4,7 +4,7 @@ import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../ import { getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' import { logger } from '../../../helpers/logger' import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' -import { getFormattedObjects, getServerActor } from '../../../helpers/utils' +import { getFormattedObjects } from '../../../helpers/utils' import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' import { DEFAULT_AUDIO_RESOLUTION, @@ -14,12 +14,7 @@ import { VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../initializers/constants' -import { - changeVideoChannelShare, - federateVideoIfNeeded, - fetchRemoteVideoDescription, - getVideoActivityPubUrl -} from '../../../lib/activitypub' +import { federateVideoIfNeeded, fetchRemoteVideoDescription } from '../../../lib/activitypub/videos' import { JobQueue } from '../../../lib/job-queue' import { Redis } from '../../../lib/redis' import { @@ -67,7 +62,10 @@ import { MVideoDetails, MVideoFullLight } from '@server/typings/models' import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' import { getVideoFilePath } from '@server/lib/video-paths' import toInt from 'validator/lib/toInt' -import { addOptimizeOrMergeAudioJob } from '@server/lib/videos' +import { addOptimizeOrMergeAudioJob } from '@server/helpers/video' +import { getServerActor } from '@server/models/application/application' +import { changeVideoChannelShare } from '@server/lib/activitypub/share' +import { getVideoActivityPubUrl } from '@server/lib/activitypub/url' const auditLogger = auditLoggerFactory('videos') const videosRouter = express.Router() diff --git a/server/controllers/api/videos/ownership.ts b/server/controllers/api/videos/ownership.ts index 41d7cdc43..190036f85 100644 --- a/server/controllers/api/videos/ownership.ts +++ b/server/controllers/api/videos/ownership.ts @@ -15,7 +15,7 @@ import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ow import { VideoChangeOwnershipStatus, VideoState } from '../../../../shared/models/videos' import { VideoChannelModel } from '../../../models/video/video-channel' import { getFormattedObjects } from '../../../helpers/utils' -import { changeVideoChannelShare } from '../../../lib/activitypub' +import { changeVideoChannelShare } from '../../../lib/activitypub/share' import { sendUpdateVideo } from '../../../lib/activitypub/send' import { VideoModel } from '../../../models/video/video' import { MVideoFullLight } from '@server/typings/models' diff --git a/server/controllers/api/videos/rate.ts b/server/controllers/api/videos/rate.ts index 3d2f3d728..3ee365289 100644 --- a/server/controllers/api/videos/rate.ts +++ b/server/controllers/api/videos/rate.ts @@ -2,7 +2,7 @@ import * as express from 'express' import { UserVideoRateUpdate } from '../../../../shared' import { logger } from '../../../helpers/logger' import { VIDEO_RATE_TYPES } from '../../../initializers/constants' -import { getRateUrl, sendVideoRateChange } from '../../../lib/activitypub' +import { getRateUrl, sendVideoRateChange } from '../../../lib/activitypub/video-rates' import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoUpdateRateValidator } from '../../../middlewares' import { AccountModel } from '../../../models/account/account' import { AccountVideoRateModel } from '../../../models/account/account-video-rate' diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts index 89c0ab151..394e97fd5 100644 --- a/server/helpers/peertube-crypto.ts +++ b/server/helpers/peertube-crypto.ts @@ -5,7 +5,6 @@ import { jsonld } from './custom-jsonld-signature' import { logger } from './logger' import { cloneDeep } from 'lodash' import { createSign, createVerify } from 'crypto' -import { buildDigest } from '../lib/job-queue/handlers/utils/activitypub-http-utils' import * as bcrypt from 'bcrypt' import { MActor } from '../typings/models' @@ -104,12 +103,19 @@ async function signJsonLDObject (byActor: MActor, data: any) { return Object.assign(data, { signature }) } +function buildDigest (body: any) { + const rawBody = typeof body === 'string' ? body : JSON.stringify(body) + + return 'SHA-256=' + sha256(rawBody, 'base64') +} + // --------------------------------------------------------------------------- export { isHTTPSignatureDigestValid, parseHTTPSignature, isHTTPSignatureVerified, + buildDigest, isJsonLDSignatureVerified, comparePassword, createPrivateAndPublicKeys, diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts index 11c118292..ad3b7949e 100644 --- a/server/helpers/utils.ts +++ b/server/helpers/utils.ts @@ -1,11 +1,9 @@ import { ResultList } from '../../shared' -import { ApplicationModel } from '../models/application/application' import { execPromise, execPromise2, randomBytesPromise, sha256 } from './core-utils' import { logger } from './logger' import { join } from 'path' import { Instance as ParseTorrent } from 'parse-torrent' import { remove } from 'fs-extra' -import * as memoizee from 'memoizee' import { CONFIG } from '../initializers/config' import { isVideoFileExtnameValid } from './custom-validators/videos' @@ -33,16 +31,6 @@ function getFormattedObjects> (objects: } as ResultList } -const getServerActor = memoizee(async function () { - const application = await ApplicationModel.load() - if (!application) throw Error('Could not load Application from database.') - - const actor = application.Account.Actor - actor.Account = application.Account - - return actor -}, { promise: true }) - function generateVideoImportTmpPath (target: string | ParseTorrent, extensionArg?: string) { const id = typeof target === 'string' ? target @@ -105,7 +93,6 @@ export { generateRandomString, getFormattedObjects, getSecureTorrentName, - getServerActor, getServerCommit, generateVideoImportTmpPath, getUUIDFromFilename diff --git a/server/helpers/video.ts b/server/helpers/video.ts index 4fe2a60f0..6f76cbdfc 100644 --- a/server/helpers/video.ts +++ b/server/helpers/video.ts @@ -1,14 +1,21 @@ import { VideoModel } from '../models/video/video' import * as Bluebird from 'bluebird' import { + isStreamingPlaylist, + MStreamingPlaylistVideo, + MVideo, MVideoAccountLightBlacklistAllFiles, + MVideoFile, MVideoFullLight, MVideoIdThumbnail, + MVideoImmutable, MVideoThumbnail, - MVideoWithRights, - MVideoImmutable + MVideoWithRights } from '@server/typings/models' import { Response } from 'express' +import { DEFAULT_AUDIO_RESOLUTION } from '@server/initializers/constants' +import { JobQueue } from '@server/lib/job-queue' +import { VideoTranscodingPayload } from '@shared/models' type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none' | 'only-immutable-attributes' @@ -62,10 +69,39 @@ function getVideoWithAttributes (res: Response) { return res.locals.videoAll || res.locals.onlyVideo || res.locals.onlyVideoWithRights } +function addOptimizeOrMergeAudioJob (video: MVideo, videoFile: MVideoFile) { + let dataInput: VideoTranscodingPayload + + if (videoFile.isAudio()) { + dataInput = { + type: 'merge-audio' as 'merge-audio', + resolution: DEFAULT_AUDIO_RESOLUTION, + videoUUID: video.uuid, + isNewVideo: true + } + } else { + dataInput = { + type: 'optimize' as 'optimize', + videoUUID: video.uuid, + isNewVideo: true + } + } + + return JobQueue.Instance.createJobWithPromise({ type: 'video-transcoding', payload: dataInput }) +} + +function extractVideo (videoOrPlaylist: MVideo | MStreamingPlaylistVideo) { + return isStreamingPlaylist(videoOrPlaylist) + ? videoOrPlaylist.Video + : videoOrPlaylist +} + export { VideoFetchType, VideoFetchByUrlType, fetchVideo, getVideoWithAttributes, - fetchVideoByUrl + fetchVideoByUrl, + addOptimizeOrMergeAudioJob, + extractVideo } diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts index b25e44fcd..7cd76d708 100644 --- a/server/helpers/webtorrent.ts +++ b/server/helpers/webtorrent.ts @@ -13,8 +13,8 @@ import { WEBSERVER } from '@server/initializers/constants' import * as parseTorrent from 'parse-torrent' import * as magnetUtil from 'magnet-uri' import { isArray } from '@server/helpers/custom-validators/misc' -import { extractVideo } from '@server/lib/videos' import { getTorrentFileName, getVideoFilePath } from '@server/lib/video-paths' +import { extractVideo } from '@server/helpers/video' const createTorrentPromise = promisify2(createTorrent) diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts index a57d552df..f111be2ae 100644 --- a/server/initializers/checker-after-init.ts +++ b/server/initializers/checker-after-init.ts @@ -1,12 +1,11 @@ import * as config from 'config' import { isProdInstance, isTestInstance } from '../helpers/core-utils' import { UserModel } from '../models/account/user' -import { ApplicationModel } from '../models/application/application' +import { getServerActor, ApplicationModel } from '../models/application/application' import { OAuthClientModel } from '../models/oauth/oauth-client' import { URL } from 'url' import { CONFIG, isEmailEnabled } from './config' import { logger } from '../helpers/logger' -import { getServerActor } from '../helpers/utils' import { RecentlyAddedStrategy } from '../../shared/models/redundancy' import { isArray } from '../helpers/custom-validators/misc' import { uniq } from 'lodash' diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index 8132ac135..c743dcf3f 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts @@ -19,7 +19,6 @@ import { AvatarModel } from '../../models/avatar/avatar' import { ServerModel } from '../../models/server/server' import { VideoChannelModel } from '../../models/video/video-channel' import { JobQueue } from '../job-queue' -import { getServerActor } from '../../helpers/utils' import { ActorFetchByUrlType, fetchActorByUrl } from '../../helpers/actor' import { sequelizeTypescript } from '../../initializers/database' import { @@ -36,6 +35,7 @@ import { MChannel } from '../../typings/models' import { extname } from 'path' +import { getServerActor } from '@server/models/application/application' // Set account keys, this could be long so process after the account creation and do not block the client function setAsyncActorKeys (actor: T) { diff --git a/server/lib/activitypub/follow.ts b/server/lib/activitypub/follow.ts index a1c95504e..3b5ad47c9 100644 --- a/server/lib/activitypub/follow.ts +++ b/server/lib/activitypub/follow.ts @@ -3,8 +3,8 @@ import { CONFIG } from '../../initializers/config' import { SERVER_ACTOR_NAME } from '../../initializers/constants' import { JobQueue } from '../job-queue' import { logger } from '../../helpers/logger' -import { getServerActor } from '../../helpers/utils' import { ServerModel } from '../../models/server/server' +import { getServerActor } from '@server/models/application/application' async function autoFollowBackIfNeeded (actorFollow: MActorFollowActors) { if (!CONFIG.FOLLOWINGS.INSTANCE.AUTO_FOLLOW_BACK.ENABLED) return diff --git a/server/lib/activitypub/index.ts b/server/lib/activitypub/index.ts deleted file mode 100644 index d8c7d83b7..000000000 --- a/server/lib/activitypub/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from './process' -export * from './send' -export * from './actor' -export * from './share' -export * from './playlist' -export * from './videos' -export * from './video-comments' -export * from './video-rates' -export * from './url' diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts index db7fb8568..8f7828e41 100644 --- a/server/lib/activitypub/process/process-follow.ts +++ b/server/lib/activitypub/process/process-follow.ts @@ -7,11 +7,11 @@ import { ActorFollowModel } from '../../../models/activitypub/actor-follow' import { sendAccept, sendReject } from '../send' import { Notifier } from '../../notifier' import { getAPId } from '../../../helpers/activitypub' -import { getServerActor } from '../../../helpers/utils' import { CONFIG } from '../../../initializers/config' import { APProcessorOptions } from '../../../typings/activitypub-processor.model' import { MActorFollowActors, MActorSignature } from '../../../typings/models' import { autoFollowBackIfNeeded } from '../follow' +import { getServerActor } from '@server/models/application/application' async function processFollowActivity (options: APProcessorOptions) { const { activity, byActor } = options diff --git a/server/lib/activitypub/send/send-create.ts b/server/lib/activitypub/send/send-create.ts index e2fa061e8..0635c7b66 100644 --- a/server/lib/activitypub/send/send-create.ts +++ b/server/lib/activitypub/send/send-create.ts @@ -6,7 +6,6 @@ import { broadcastToActors, broadcastToFollowers, sendVideoRelatedActivity, unic import { audiencify, getActorsInvolvedInVideo, getAudience, getAudienceFromFollowersOf, getVideoCommentAudience } from '../audience' import { logger } from '../../../helpers/logger' import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' -import { getServerActor } from '../../../helpers/utils' import { MActorLight, MCommentOwnerVideo, @@ -17,6 +16,7 @@ import { MVideoRedundancyStreamingPlaylistVideo } from '../../../typings/models' import { ContextType } from '@server/helpers/activitypub' +import { getServerActor } from '@server/models/application/application' async function sendCreateVideo (video: MVideoAP, t: Transaction) { if (!video.hasPrivacyForFederation()) return undefined diff --git a/server/lib/activitypub/send/send-delete.ts b/server/lib/activitypub/send/send-delete.ts index 3225ebf32..fd3f06dec 100644 --- a/server/lib/activitypub/send/send-delete.ts +++ b/server/lib/activitypub/send/send-delete.ts @@ -7,9 +7,9 @@ import { getDeleteActivityPubUrl } from '../url' import { broadcastToActors, broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils' import { audiencify, getActorsInvolvedInVideo, getVideoCommentAudience } from '../audience' import { logger } from '../../../helpers/logger' -import { getServerActor } from '../../../helpers/utils' import { MCommentOwnerVideoReply, MVideoAccountLight, MVideoPlaylistFullSummary } from '../../../typings/models/video' import { MActorUrl } from '../../../typings/models' +import { getServerActor } from '@server/models/application/application' async function sendDeleteVideo (video: MVideoAccountLight, transaction: Transaction) { logger.info('Creating job to broadcast delete of video %s.', video.url) diff --git a/server/lib/activitypub/send/send-update.ts b/server/lib/activitypub/send/send-update.ts index 2b01ca5e7..7a4cf3f56 100644 --- a/server/lib/activitypub/send/send-update.ts +++ b/server/lib/activitypub/send/send-update.ts @@ -9,7 +9,6 @@ import { broadcastToFollowers, sendVideoRelatedActivity } from './utils' import { audiencify, getActorsInvolvedInVideo, getAudience } from '../audience' import { logger } from '../../../helpers/logger' import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' -import { getServerActor } from '../../../helpers/utils' import { MAccountDefault, MActor, @@ -20,6 +19,7 @@ import { MVideoPlaylistFull, MVideoRedundancyVideo } from '../../../typings/models' +import { getServerActor } from '@server/models/application/application' async function sendUpdateVideo (videoArg: MVideoAPWithoutCaption, t: Transaction, overrodeByActor?: MActor) { const video = videoArg as MVideoAP diff --git a/server/lib/activitypub/send/utils.ts b/server/lib/activitypub/send/utils.ts index 6fd53d71b..0dfcc51be 100644 --- a/server/lib/activitypub/send/utils.ts +++ b/server/lib/activitypub/send/utils.ts @@ -5,10 +5,10 @@ import { ActorModel } from '../../../models/activitypub/actor' import { ActorFollowModel } from '../../../models/activitypub/actor-follow' import { JobQueue } from '../../job-queue' import { getActorsInvolvedInVideo, getAudienceFromFollowersOf, getRemoteVideoAudience } from '../audience' -import { getServerActor } from '../../../helpers/utils' import { afterCommitIfTransaction } from '../../../helpers/database-utils' import { MActor, MActorId, MActorLight, MActorWithInboxes, MVideoAccountLight, MVideoId, MVideoImmutable } from '../../../typings/models' import { ContextType } from '@server/helpers/activitypub' +import { getServerActor } from '@server/models/application/application' async function sendVideoRelatedActivity (activityBuilder: (audience: ActivityAudience) => Activity, options: { byActor: MActorLight diff --git a/server/lib/activitypub/share.ts b/server/lib/activitypub/share.ts index a7c645062..d2cbc59a8 100644 --- a/server/lib/activitypub/share.ts +++ b/server/lib/activitypub/share.ts @@ -1,5 +1,4 @@ import { Transaction } from 'sequelize' -import { getServerActor } from '../../helpers/utils' import { VideoShareModel } from '../../models/video/video-share' import { sendUndoAnnounce, sendVideoAnnounce } from './send' import { getVideoAnnounceActivityPubUrl } from './url' @@ -10,6 +9,7 @@ import { logger } from '../../helpers/logger' import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants' import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub' import { MChannelActorLight, MVideo, MVideoAccountLight, MVideoId } from '../../typings/models/video' +import { getServerActor } from '@server/models/application/application' async function shareVideoByServerAndChannel (video: MVideoAccountLight, t: Transaction) { if (!video.hasPrivacyForFederation()) return undefined diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index 62f589272..7d16bd390 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts @@ -6,7 +6,7 @@ import { ActivityHashTagObject, ActivityMagnetUrlObject, ActivityPlaylistSegmentHashesObject, - ActivityPlaylistUrlObject, + ActivityPlaylistUrlObject, ActivitypubHttpFetcherPayload, ActivityTagObject, ActivityUrlObject, ActivityVideoUrlObject, @@ -38,7 +38,6 @@ import { sendCreateVideo, sendUpdateVideo } from './send' import { isArray } from '../../helpers/custom-validators/misc' import { VideoCaptionModel } from '../../models/video/video-caption' import { JobQueue } from '../job-queue' -import { ActivitypubHttpFetcherPayload } from '../job-queue/handlers/activitypub-http-fetcher' import { createRates } from './video-rates' import { addVideoShares, shareVideoByServerAndChannel } from './share' import { fetchVideoByUrl, VideoFetchByUrlType } from '../../helpers/video' diff --git a/server/lib/avatar.ts b/server/lib/avatar.ts index 3de45dd19..282d834a2 100644 --- a/server/lib/avatar.ts +++ b/server/lib/avatar.ts @@ -1,7 +1,7 @@ import 'multer' import { sendUpdateActor } from './activitypub/send' import { AVATARS_SIZE, LRU_CACHE, QUEUE_CONCURRENCY } from '../initializers/constants' -import { updateActorAvatarInstance } from './activitypub' +import { updateActorAvatarInstance } from './activitypub/actor' import { processImage } from '../helpers/image-utils' import { extname, join } from 'path' import { retryTransactionWrapper } from '../helpers/database-utils' diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts index 5a99edc7f..45d57fd28 100644 --- a/server/lib/emailer.ts +++ b/server/lib/emailer.ts @@ -3,7 +3,6 @@ import { isTestInstance } from '../helpers/core-utils' import { bunyanLogger, logger } from '../helpers/logger' import { CONFIG, isEmailEnabled } from '../initializers/config' import { JobQueue } from './job-queue' -import { EmailPayload } from './job-queue/handlers/email' import { readFileSync } from 'fs-extra' import { WEBSERVER } from '../initializers/constants' import { @@ -16,15 +15,7 @@ import { } from '../typings/models/video' import { MActorFollowActors, MActorFollowFull, MUser } from '../typings/models' import { MVideoImport, MVideoImportVideo } from '@server/typings/models/video/video-import' - -type SendEmailOptions = { - to: string[] - subject: string - text: string - - fromDisplayName?: string - replyTo?: string -} +import { EmailPayload } from '@shared/models' class Emailer { @@ -507,6 +498,5 @@ class Emailer { // --------------------------------------------------------------------------- export { - Emailer, - SendEmailOptions + Emailer } diff --git a/server/lib/job-queue/handlers/activitypub-follow.ts b/server/lib/job-queue/handlers/activitypub-follow.ts index e467c5b1b..7034c10d0 100644 --- a/server/lib/job-queue/handlers/activitypub-follow.ts +++ b/server/lib/job-queue/handlers/activitypub-follow.ts @@ -11,14 +11,7 @@ import { ActorModel } from '../../../models/activitypub/actor' import { Notifier } from '../../notifier' import { sequelizeTypescript } from '../../../initializers/database' import { MActor, MActorFollowActors, MActorFull } from '../../../typings/models' - -export type ActivitypubFollowPayload = { - followerActorId: number - name: string - host: string - isAutoFollow?: boolean - assertIsChannel?: boolean -} +import { ActivitypubFollowPayload } from '@shared/models' async function processActivityPubFollow (job: Bull.Job) { const payload = job.data as ActivitypubFollowPayload diff --git a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts index 7d9dd61e9..e4d3dbbff 100644 --- a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts +++ b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts @@ -5,14 +5,7 @@ import { doRequest } from '../../../helpers/requests' import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils' import { BROADCAST_CONCURRENCY, JOB_REQUEST_TIMEOUT } from '../../../initializers/constants' import { ActorFollowScoreCache } from '../../files-cache' -import { ContextType } from '@server/helpers/activitypub' - -export type ActivitypubHttpBroadcastPayload = { - uris: string[] - signatureActorId?: number - body: any - contextType?: ContextType -} +import { ActivitypubHttpBroadcastPayload } from '@shared/models' async function processActivityPubHttpBroadcast (job: Bull.Job) { logger.info('Processing ActivityPub broadcast in job %d.', job.id) diff --git a/server/lib/job-queue/handlers/activitypub-http-fetcher.ts b/server/lib/job-queue/handlers/activitypub-http-fetcher.ts index 0182c5169..524aadc27 100644 --- a/server/lib/job-queue/handlers/activitypub-http-fetcher.ts +++ b/server/lib/job-queue/handlers/activitypub-http-fetcher.ts @@ -5,22 +5,15 @@ import { processActivities } from '../../activitypub/process' import { addVideoComments } from '../../activitypub/video-comments' import { crawlCollectionPage } from '../../activitypub/crawl' import { VideoModel } from '../../../models/video/video' -import { addVideoShares, createRates } from '../../activitypub' +import { addVideoShares } from '../../activitypub/share' +import { createRates } from '../../activitypub/video-rates' import { createAccountPlaylists } from '../../activitypub/playlist' import { AccountModel } from '../../../models/account/account' import { AccountVideoRateModel } from '../../../models/account/account-video-rate' import { VideoShareModel } from '../../../models/video/video-share' import { VideoCommentModel } from '../../../models/video/video-comment' import { MAccountDefault, MVideoFullLight } from '../../../typings/models' - -type FetchType = 'activity' | 'video-likes' | 'video-dislikes' | 'video-shares' | 'video-comments' | 'account-playlists' - -export type ActivitypubHttpFetcherPayload = { - uri: string - type: FetchType - videoId?: number - accountId?: number -} +import { ActivitypubHttpFetcherPayload, FetchType } from '@shared/models' async function processActivityPubHttpFetcher (job: Bull.Job) { logger.info('Processing ActivityPub fetcher in job %d.', job.id) diff --git a/server/lib/job-queue/handlers/activitypub-http-unicast.ts b/server/lib/job-queue/handlers/activitypub-http-unicast.ts index 6b71e2891..b65eeb677 100644 --- a/server/lib/job-queue/handlers/activitypub-http-unicast.ts +++ b/server/lib/job-queue/handlers/activitypub-http-unicast.ts @@ -4,14 +4,7 @@ import { doRequest } from '../../../helpers/requests' import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils' import { JOB_REQUEST_TIMEOUT } from '../../../initializers/constants' import { ActorFollowScoreCache } from '../../files-cache' -import { ContextType } from '@server/helpers/activitypub' - -export type ActivitypubHttpUnicastPayload = { - uri: string - signatureActorId?: number - body: any - contextType?: ContextType -} +import { ActivitypubHttpUnicastPayload } from '@shared/models' async function processActivityPubHttpUnicast (job: Bull.Job) { logger.info('Processing ActivityPub unicast in job %d.', job.id) diff --git a/server/lib/job-queue/handlers/activitypub-refresher.ts b/server/lib/job-queue/handlers/activitypub-refresher.ts index 4d6c38cfa..666e56868 100644 --- a/server/lib/job-queue/handlers/activitypub-refresher.ts +++ b/server/lib/job-queue/handlers/activitypub-refresher.ts @@ -1,14 +1,12 @@ import * as Bull from 'bull' import { logger } from '../../../helpers/logger' import { fetchVideoByUrl } from '../../../helpers/video' -import { refreshActorIfNeeded, refreshVideoIfNeeded, refreshVideoPlaylistIfNeeded } from '../../activitypub' +import { refreshActorIfNeeded } from '../../activitypub/actor' +import { refreshVideoIfNeeded } from '../../activitypub/videos' import { ActorModel } from '../../../models/activitypub/actor' import { VideoPlaylistModel } from '../../../models/video/video-playlist' - -export type RefreshPayload = { - type: 'video' | 'video-playlist' | 'actor' - url: string -} +import { RefreshPayload } from '@shared/models' +import { refreshVideoPlaylistIfNeeded } from '@server/lib/activitypub/playlist' async function refreshAPObject (job: Bull.Job) { const payload = job.data as RefreshPayload diff --git a/server/lib/job-queue/handlers/email.ts b/server/lib/job-queue/handlers/email.ts index 62701222c..3157731e2 100644 --- a/server/lib/job-queue/handlers/email.ts +++ b/server/lib/job-queue/handlers/email.ts @@ -1,8 +1,7 @@ import * as Bull from 'bull' import { logger } from '../../../helpers/logger' -import { Emailer, SendEmailOptions } from '../../emailer' - -export type EmailPayload = SendEmailOptions +import { Emailer } from '../../emailer' +import { EmailPayload } from '@shared/models' async function processEmail (job: Bull.Job) { const payload = job.data as EmailPayload diff --git a/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts b/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts index 258ffabee..437ea06fc 100644 --- a/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts +++ b/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts @@ -1,9 +1,9 @@ import { buildSignedActivity, ContextType } from '../../../../helpers/activitypub' -import { getServerActor } from '../../../../helpers/utils' import { ActorModel } from '../../../../models/activitypub/actor' -import { sha256 } from '../../../../helpers/core-utils' import { ACTIVITY_PUB, HTTP_SIGNATURE } from '../../../../initializers/constants' import { MActor } from '../../../../typings/models' +import { getServerActor } from '@server/models/application/application' +import { buildDigest } from '@server/helpers/peertube-crypto' type Payload = { body: any, contextType?: ContextType, signatureActorId?: number } @@ -48,14 +48,7 @@ function buildGlobalHeaders (body: any) { } } -function buildDigest (body: any) { - const rawBody = typeof body === 'string' ? body : JSON.stringify(body) - - return 'SHA-256=' + sha256(rawBody, 'base64') -} - export { - buildDigest, buildGlobalHeaders, computeBody, buildSignedRequestOptions diff --git a/server/lib/job-queue/handlers/video-file-import.ts b/server/lib/job-queue/handlers/video-file-import.ts index be9e7d181..ae11f1de3 100644 --- a/server/lib/job-queue/handlers/video-file-import.ts +++ b/server/lib/job-queue/handlers/video-file-import.ts @@ -9,11 +9,7 @@ import { extname } from 'path' import { MVideoFile, MVideoWithFile } from '@server/typings/models' import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' import { getVideoFilePath } from '@server/lib/video-paths' - -export type VideoFileImportPayload = { - videoUUID: string - filePath: string -} +import { VideoFileImportPayload } from '@shared/models' async function processVideoFileImport (job: Bull.Job) { const payload = job.data as VideoFileImportPayload diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts index 6cdae5b03..ad549c6fc 100644 --- a/server/lib/job-queue/handlers/video-import.ts +++ b/server/lib/job-queue/handlers/video-import.ts @@ -7,8 +7,8 @@ import { getDurationFromVideoFile, getVideoFileFPS, getVideoFileResolution } fro import { extname } from 'path' import { VideoFileModel } from '../../../models/video/video-file' import { VIDEO_IMPORT_TIMEOUT } from '../../../initializers/constants' -import { VideoState } from '../../../../shared' -import { federateVideoIfNeeded } from '../../activitypub' +import { VideoImportPayload, VideoImportTorrentPayload, VideoImportYoutubeDLPayload, VideoState } from '../../../../shared' +import { federateVideoIfNeeded } from '../../activitypub/videos' import { VideoModel } from '../../../models/video/video' import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent' import { getSecureTorrentName } from '../../../helpers/utils' @@ -21,24 +21,7 @@ import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' import { MThumbnail } from '../../../typings/models/video/thumbnail' import { MVideoImportDefault, MVideoImportDefaultFiles, MVideoImportVideo } from '@server/typings/models/video/video-import' import { getVideoFilePath } from '@server/lib/video-paths' -import { addOptimizeOrMergeAudioJob } from '@server/lib/videos' - -type VideoImportYoutubeDLPayload = { - type: 'youtube-dl' - videoImportId: number - - generateThumbnail: boolean - generatePreview: boolean - - fileExt?: string -} - -type VideoImportTorrentPayload = { - type: 'magnet-uri' | 'torrent-file' - videoImportId: number -} - -export type VideoImportPayload = VideoImportYoutubeDLPayload | VideoImportTorrentPayload +import { addOptimizeOrMergeAudioJob } from '@server/helpers/video' async function processVideoImport (job: Bull.Job) { const payload = job.data as VideoImportPayload diff --git a/server/lib/job-queue/handlers/video-redundancy.ts b/server/lib/job-queue/handlers/video-redundancy.ts index 319d7090e..6296dab05 100644 --- a/server/lib/job-queue/handlers/video-redundancy.ts +++ b/server/lib/job-queue/handlers/video-redundancy.ts @@ -1,10 +1,7 @@ import * as Bull from 'bull' import { logger } from '../../../helpers/logger' import { VideosRedundancyScheduler } from '@server/lib/schedulers/videos-redundancy-scheduler' - -export type VideoRedundancyPayload = { - videoId: number -} +import { VideoRedundancyPayload } from '@shared/models' async function processVideoRedundancy (job: Bull.Job) { const payload = job.data as VideoRedundancyPayload diff --git a/server/lib/job-queue/handlers/video-transcoding.ts b/server/lib/job-queue/handlers/video-transcoding.ts index c020057c9..46add57d4 100644 --- a/server/lib/job-queue/handlers/video-transcoding.ts +++ b/server/lib/job-queue/handlers/video-transcoding.ts @@ -1,9 +1,14 @@ import * as Bull from 'bull' -import { VideoResolution } from '../../../../shared' +import { + MergeAudioTranscodingPayload, + NewResolutionTranscodingPayload, + OptimizeTranscodingPayload, + VideoTranscodingPayload +} from '../../../../shared' import { logger } from '../../../helpers/logger' import { VideoModel } from '../../../models/video/video' import { JobQueue } from '../job-queue' -import { federateVideoIfNeeded } from '../../activitypub' +import { federateVideoIfNeeded } from '../../activitypub/videos' import { retryTransactionWrapper } from '../../../helpers/database-utils' import { sequelizeTypescript } from '../../../initializers' import { computeResolutionsToTranscode } from '../../../helpers/ffmpeg-utils' @@ -12,39 +17,6 @@ import { Notifier } from '../../notifier' import { CONFIG } from '../../../initializers/config' import { MVideoFullLight, MVideoUUID, MVideoWithFile } from '@server/typings/models' -interface BaseTranscodingPayload { - videoUUID: string - isNewVideo?: boolean -} - -interface HLSTranscodingPayload extends BaseTranscodingPayload { - type: 'hls' - isPortraitMode?: boolean - resolution: VideoResolution - copyCodecs: boolean -} - -interface NewResolutionTranscodingPayload extends BaseTranscodingPayload { - type: 'new-resolution' - isPortraitMode?: boolean - resolution: VideoResolution -} - -interface MergeAudioTranscodingPayload extends BaseTranscodingPayload { - type: 'merge-audio' - resolution: VideoResolution -} - -interface OptimizeTranscodingPayload extends BaseTranscodingPayload { - type: 'optimize' -} - -export type VideoTranscodingPayload = - HLSTranscodingPayload - | NewResolutionTranscodingPayload - | OptimizeTranscodingPayload - | MergeAudioTranscodingPayload - async function processVideoTranscoding (job: Bull.Job) { const payload = job.data as VideoTranscodingPayload logger.info('Processing video file in job %d.', job.id) diff --git a/server/lib/job-queue/handlers/video-views.ts b/server/lib/job-queue/handlers/video-views.ts index 2258cd029..7211df237 100644 --- a/server/lib/job-queue/handlers/video-views.ts +++ b/server/lib/job-queue/handlers/video-views.ts @@ -3,7 +3,7 @@ import { logger } from '../../../helpers/logger' import { VideoModel } from '../../../models/video/video' import { VideoViewModel } from '../../../models/video/video-views' import { isTestInstance } from '../../../helpers/core-utils' -import { federateVideoIfNeeded } from '../../activitypub' +import { federateVideoIfNeeded } from '../../activitypub/videos' async function processVideosViews () { const lastHour = new Date() diff --git a/server/lib/job-queue/job-queue.ts b/server/lib/job-queue/job-queue.ts index 14acace7d..d8d64caaf 100644 --- a/server/lib/job-queue/job-queue.ts +++ b/server/lib/job-queue/job-queue.ts @@ -1,19 +1,25 @@ import * as Bull from 'bull' -import { JobState, JobType } from '../../../shared/models' +import { + ActivitypubFollowPayload, + ActivitypubHttpBroadcastPayload, + ActivitypubHttpFetcherPayload, ActivitypubHttpUnicastPayload, EmailPayload, + JobState, + JobType, RefreshPayload, VideoFileImportPayload, VideoImportPayload, VideoRedundancyPayload, VideoTranscodingPayload +} from '../../../shared/models' import { logger } from '../../helpers/logger' import { Redis } from '../redis' import { JOB_ATTEMPTS, JOB_COMPLETED_LIFETIME, JOB_CONCURRENCY, JOB_TTL, REPEAT_JOBS, WEBSERVER } from '../../initializers/constants' -import { ActivitypubHttpBroadcastPayload, processActivityPubHttpBroadcast } from './handlers/activitypub-http-broadcast' -import { ActivitypubHttpFetcherPayload, processActivityPubHttpFetcher } from './handlers/activitypub-http-fetcher' -import { ActivitypubHttpUnicastPayload, processActivityPubHttpUnicast } from './handlers/activitypub-http-unicast' -import { EmailPayload, processEmail } from './handlers/email' -import { processVideoTranscoding, VideoTranscodingPayload } from './handlers/video-transcoding' -import { ActivitypubFollowPayload, processActivityPubFollow } from './handlers/activitypub-follow' -import { processVideoImport, VideoImportPayload } from './handlers/video-import' +import { processActivityPubHttpBroadcast } from './handlers/activitypub-http-broadcast' +import { processActivityPubHttpFetcher } from './handlers/activitypub-http-fetcher' +import { processActivityPubHttpUnicast } from './handlers/activitypub-http-unicast' +import { processEmail } from './handlers/email' +import { processVideoTranscoding} from './handlers/video-transcoding' +import { processActivityPubFollow } from './handlers/activitypub-follow' +import { processVideoImport} from './handlers/video-import' import { processVideosViews } from './handlers/video-views' -import { refreshAPObject, RefreshPayload } from './handlers/activitypub-refresher' -import { processVideoFileImport, VideoFileImportPayload } from './handlers/video-file-import' -import { processVideoRedundancy, VideoRedundancyPayload } from '@server/lib/job-queue/handlers/video-redundancy' +import { refreshAPObject} from './handlers/activitypub-refresher' +import { processVideoFileImport} from './handlers/video-file-import' +import { processVideoRedundancy} from '@server/lib/job-queue/handlers/video-redundancy' type CreateJobArgument = { type: 'activitypub-http-broadcast', payload: ActivitypubHttpBroadcastPayload } | diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts index 63197eee1..710c2d30f 100644 --- a/server/lib/notifier.ts +++ b/server/lib/notifier.ts @@ -26,7 +26,7 @@ import { import { MAccountDefault, MActorFollowFull } from '../typings/models' import { MVideoImportVideo } from '@server/typings/models/video/video-import' import { ServerBlocklistModel } from '@server/models/server/server-blocklist' -import { getServerActor } from '@server/helpers/utils' +import { getServerActor } from '@server/models/application/application' class Notifier { diff --git a/server/lib/redundancy.ts b/server/lib/redundancy.ts index aa0e37478..361b401a5 100644 --- a/server/lib/redundancy.ts +++ b/server/lib/redundancy.ts @@ -1,12 +1,12 @@ import { VideoRedundancyModel } from '../models/redundancy/video-redundancy' import { sendUndoCacheFile } from './activitypub/send' import { Transaction } from 'sequelize' -import { getServerActor } from '../helpers/utils' import { MActorSignature, MVideoRedundancyVideo } from '@server/typings/models' import { CONFIG } from '@server/initializers/config' import { logger } from '@server/helpers/logger' import { ActorFollowModel } from '@server/models/activitypub/actor-follow' import { Activity } from '@shared/models' +import { getServerActor } from '@server/models/application/application' async function removeVideoRedundancy (videoRedundancy: MVideoRedundancyVideo, t?: Transaction) { const serverActor = await getServerActor() diff --git a/server/lib/schedulers/auto-follow-index-instances.ts b/server/lib/schedulers/auto-follow-index-instances.ts index a1f5e4a91..e852c7fc6 100644 --- a/server/lib/schedulers/auto-follow-index-instances.ts +++ b/server/lib/schedulers/auto-follow-index-instances.ts @@ -6,7 +6,7 @@ import { chunk } from 'lodash' import { doRequest } from '@server/helpers/requests' import { ActorFollowModel } from '@server/models/activitypub/actor-follow' import { JobQueue } from '@server/lib/job-queue' -import { getServerActor } from '@server/helpers/utils' +import { getServerActor } from '@server/models/application/application' export class AutoFollowIndexInstances extends AbstractScheduler { diff --git a/server/lib/schedulers/update-videos-scheduler.ts b/server/lib/schedulers/update-videos-scheduler.ts index 956780a77..d32c1c068 100644 --- a/server/lib/schedulers/update-videos-scheduler.ts +++ b/server/lib/schedulers/update-videos-scheduler.ts @@ -2,7 +2,7 @@ import { logger } from '../../helpers/logger' import { AbstractScheduler } from './abstract-scheduler' import { ScheduleVideoUpdateModel } from '../../models/video/schedule-video-update' import { retryTransactionWrapper } from '../../helpers/database-utils' -import { federateVideoIfNeeded } from '../activitypub' +import { federateVideoIfNeeded } from '../activitypub/videos' import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants' import { Notifier } from '../notifier' import { sequelizeTypescript } from '../../initializers/database' diff --git a/server/lib/schedulers/videos-redundancy-scheduler.ts b/server/lib/schedulers/videos-redundancy-scheduler.ts index e33a4133a..8da9d52b5 100644 --- a/server/lib/schedulers/videos-redundancy-scheduler.ts +++ b/server/lib/schedulers/videos-redundancy-scheduler.ts @@ -6,11 +6,10 @@ import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy' import { downloadWebTorrentVideo, generateMagnetUri } from '../../helpers/webtorrent' import { join } from 'path' import { move } from 'fs-extra' -import { getServerActor } from '../../helpers/utils' import { sendCreateCacheFile, sendUpdateCacheFile } from '../activitypub/send' import { getVideoCacheFileActivityPubUrl, getVideoCacheStreamingPlaylistActivityPubUrl } from '../activitypub/url' import { removeVideoRedundancy } from '../redundancy' -import { getOrCreateVideoAndAccountAndChannel } from '../activitypub' +import { getOrCreateVideoAndAccountAndChannel } from '../activitypub/videos' import { downloadPlaylistSegments } from '../hls' import { CONFIG } from '../../initializers/config' import { @@ -26,6 +25,7 @@ import { } from '@server/typings/models' import { getVideoFilename } from '../video-paths' import { VideoModel } from '@server/models/video/video' +import { getServerActor } from '@server/models/application/application' type CandidateToDuplicate = { redundancy: VideosRedundancyStrategy diff --git a/server/lib/video-comment.ts b/server/lib/video-comment.ts index fe83d23e7..516c912a9 100644 --- a/server/lib/video-comment.ts +++ b/server/lib/video-comment.ts @@ -2,7 +2,7 @@ import * as Sequelize from 'sequelize' import { ResultList } from '../../shared/models' import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model' import { VideoCommentModel } from '../models/video/video-comment' -import { getVideoCommentActivityPubUrl } from './activitypub' +import { getVideoCommentActivityPubUrl } from './activitypub/url' import { sendCreateVideoComment } from './activitypub/send' import { MAccountDefault, MComment, MCommentOwnerVideoReply, MVideoFullLight } from '../typings/models' diff --git a/server/lib/video-paths.ts b/server/lib/video-paths.ts index fe0a004e4..05aaca8af 100644 --- a/server/lib/video-paths.ts +++ b/server/lib/video-paths.ts @@ -1,8 +1,8 @@ import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoFile, MVideoUUID } from '@server/typings/models' -import { extractVideo } from './videos' import { join } from 'path' import { CONFIG } from '@server/initializers/config' import { HLS_REDUNDANCY_DIRECTORY, HLS_STREAMING_PLAYLIST_DIRECTORY } from '@server/initializers/constants' +import { extractVideo } from '@server/helpers/video' // ################## Video file name ################## diff --git a/server/lib/video-playlist.ts b/server/lib/video-playlist.ts index 29b70cfda..75fbd6896 100644 --- a/server/lib/video-playlist.ts +++ b/server/lib/video-playlist.ts @@ -1,7 +1,7 @@ import * as Sequelize from 'sequelize' import { VideoPlaylistModel } from '../models/video/video-playlist' import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model' -import { getVideoPlaylistActivityPubUrl } from './activitypub' +import { getVideoPlaylistActivityPubUrl } from './activitypub/url' import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model' import { MAccount } from '../typings/models' import { MVideoPlaylistOwner } from '../typings/models/video/video-playlist' diff --git a/server/lib/videos.ts b/server/lib/videos.ts deleted file mode 100644 index 96bdd42e9..000000000 --- a/server/lib/videos.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoFile } from '@server/typings/models' -import { VideoTranscodingPayload } from '@server/lib/job-queue/handlers/video-transcoding' -import { DEFAULT_AUDIO_RESOLUTION } from '@server/initializers/constants' -import { JobQueue } from '@server/lib/job-queue' - -function extractVideo (videoOrPlaylist: MVideo | MStreamingPlaylistVideo) { - return isStreamingPlaylist(videoOrPlaylist) - ? videoOrPlaylist.Video - : videoOrPlaylist -} - -function addOptimizeOrMergeAudioJob (video: MVideo, videoFile: MVideoFile) { - let dataInput: VideoTranscodingPayload - - if (videoFile.isAudio()) { - dataInput = { - type: 'merge-audio' as 'merge-audio', - resolution: DEFAULT_AUDIO_RESOLUTION, - videoUUID: video.uuid, - isNewVideo: true - } - } else { - dataInput = { - type: 'optimize' as 'optimize', - videoUUID: video.uuid, - isNewVideo: true - } - } - - return JobQueue.Instance.createJobWithPromise({ type: 'video-transcoding', payload: dataInput }) -} - -export { - addOptimizeOrMergeAudioJob, - extractVideo -} diff --git a/server/middlewares/activitypub.ts b/server/middlewares/activitypub.ts index 45899818e..580606a68 100644 --- a/server/middlewares/activitypub.ts +++ b/server/middlewares/activitypub.ts @@ -3,7 +3,7 @@ import { ActivityDelete, ActivityPubSignature } from '../../shared' import { logger } from '../helpers/logger' import { isHTTPSignatureVerified, isJsonLDSignatureVerified, parseHTTPSignature } from '../helpers/peertube-crypto' import { ACCEPT_HEADERS, ACTIVITY_PUB, HTTP_SIGNATURE } from '../initializers/constants' -import { getOrCreateActorAndServerAndModel } from '../lib/activitypub' +import { getOrCreateActorAndServerAndModel } from '../lib/activitypub/actor' import { loadActorUrlOrGetFromWebfinger } from '../helpers/webfinger' import { isActorDeleteActivityValid } from '@server/helpers/custom-validators/activitypub/actor' import { getAPId } from '@server/helpers/activitypub' diff --git a/server/middlewares/validators/activitypub/activity.ts b/server/middlewares/validators/activitypub/activity.ts index 7582f65e7..7350be5d5 100644 --- a/server/middlewares/validators/activitypub/activity.ts +++ b/server/middlewares/validators/activitypub/activity.ts @@ -1,7 +1,7 @@ import * as express from 'express' import { isRootActivityValid } from '../../../helpers/custom-validators/activitypub/activity' import { logger } from '../../../helpers/logger' -import { getServerActor } from '../../../helpers/utils' +import { getServerActor } from '@server/models/application/application' async function activityPubValidator (req: express.Request, res: express.Response, next: express.NextFunction) { logger.debug('Checking activity pub parameters') diff --git a/server/middlewares/validators/blocklist.ts b/server/middlewares/validators/blocklist.ts index b2183437c..c00a7e4df 100644 --- a/server/middlewares/validators/blocklist.ts +++ b/server/middlewares/validators/blocklist.ts @@ -6,9 +6,9 @@ import { AccountBlocklistModel } from '../../models/account/account-blocklist' import { isHostValid } from '../../helpers/custom-validators/servers' import { ServerBlocklistModel } from '../../models/server/server-blocklist' import { ServerModel } from '../../models/server/server' -import { getServerActor } from '../../helpers/utils' import { WEBSERVER } from '../../initializers/constants' import { doesAccountNameWithHostExist } from '../../helpers/middlewares' +import { getServerActor } from '@server/models/application/application' const blockAccountValidator = [ body('accountName').exists().withMessage('Should have an account name with host'), diff --git a/server/middlewares/validators/follows.ts b/server/middlewares/validators/follows.ts index a98d32d86..7808135f7 100644 --- a/server/middlewares/validators/follows.ts +++ b/server/middlewares/validators/follows.ts @@ -3,7 +3,6 @@ import { body, param, query } from 'express-validator' import { isTestInstance } from '../../helpers/core-utils' import { isEachUniqueHostValid, isHostValid } from '../../helpers/custom-validators/servers' import { logger } from '../../helpers/logger' -import { getServerActor } from '../../helpers/utils' import { SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants' import { ActorFollowModel } from '../../models/activitypub/actor-follow' import { areValidationErrors } from './utils' @@ -12,6 +11,7 @@ import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger' import { isActorTypeValid, isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' import { MActorFollowActorsDefault } from '@server/typings/models' import { isFollowStateValid } from '@server/helpers/custom-validators/follows' +import { getServerActor } from '@server/models/application/application' const listFollowsValidator = [ query('state') diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index 3a7869354..867c05fc1 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts @@ -38,7 +38,6 @@ import { checkUserCanTerminateOwnershipChange, doesChangeVideoOwnershipExist } f import { VideoChangeOwnershipAccept } from '../../../../shared/models/videos/video-change-ownership-accept.model' import { AccountModel } from '../../../models/account/account' import { isNSFWQueryValid, isNumberArray, isStringArray } from '../../../helpers/custom-validators/search' -import { getServerActor } from '../../../helpers/utils' import { CONFIG } from '../../../initializers/config' import { isLocalVideoAccepted } from '../../../lib/moderation' import { Hooks } from '../../../lib/plugins/hooks' @@ -50,6 +49,7 @@ import { } from '../../../helpers/middlewares' import { MVideoFullLight } from '@server/typings/models' import { getVideoWithAttributes } from '../../../helpers/video' +import { getServerActor } from '@server/models/application/application' const videosAddValidator = getCommonVideoEditAttributes().concat([ body('videofile') diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts index 5a8e450a5..85a371026 100644 --- a/server/models/activitypub/actor-follow.ts +++ b/server/models/activitypub/actor-follow.ts @@ -20,7 +20,6 @@ import { import { FollowState } from '../../../shared/models/actors' import { ActorFollow } from '../../../shared/models/actors/follow.model' import { logger } from '../../helpers/logger' -import { getServerActor } from '../../helpers/utils' import { ACTOR_FOLLOW_SCORE, FOLLOW_STATES, SERVER_ACTOR_NAME } from '../../initializers/constants' import { ServerModel } from '../server/server' import { createSafeIn, getFollowsSort, getSort } from '../utils' @@ -37,6 +36,7 @@ import { } from '@server/typings/models' import { ActivityPubActorType } from '@shared/models' import { VideoModel } from '@server/models/video/video' +import { getServerActor } from '@server/models/application/application' @Table({ tableName: 'actorFollow', diff --git a/server/models/application/application.ts b/server/models/application/application.ts index 81320b9af..3bba2c70e 100644 --- a/server/models/application/application.ts +++ b/server/models/application/application.ts @@ -1,5 +1,16 @@ import { AllowNull, Column, Default, DefaultScope, HasOne, IsInt, Model, Table } from 'sequelize-typescript' import { AccountModel } from '../account/account' +import * as memoizee from 'memoizee' + +export const getServerActor = memoizee(async function () { + const application = await ApplicationModel.load() + if (!application) throw Error('Could not load Application from database.') + + const actor = application.Account.Actor + actor.Account = application.Account + + return actor +}, { promise: true }) @DefaultScope(() => ({ include: [ diff --git a/server/models/redundancy/video-redundancy.ts b/server/models/redundancy/video-redundancy.ts index 857b9eca6..6021408bf 100644 --- a/server/models/redundancy/video-redundancy.ts +++ b/server/models/redundancy/video-redundancy.ts @@ -17,7 +17,6 @@ import { getSort, getVideoSort, parseAggregateResult, throwIfNotValid } from '.. import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../initializers/constants' import { VideoFileModel } from '../video/video-file' -import { getServerActor } from '../../helpers/utils' import { VideoModel } from '../video/video' import { VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../shared/models/redundancy' import { logger } from '../../helpers/logger' @@ -37,6 +36,7 @@ import { StreamingPlaylistRedundancyInformation, VideoRedundancy } from '@shared/models/redundancy/video-redundancy.model' +import { getServerActor } from '@server/models/application/application' export enum ScopeNames { WITH_VIDEO = 'WITH_VIDEO' diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index 7cdff8c2c..b7ed6240e 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts @@ -9,7 +9,6 @@ import { ActorModel } from '../activitypub/actor' import { buildBlockedAccountSQL, buildLocalAccountIdsIn, getCommentSort, throwIfNotValid } from '../utils' import { VideoModel } from './video' import { VideoChannelModel } from './video-channel' -import { getServerActor } from '../../helpers/utils' import { actorNameAlphabet } from '../../helpers/custom-validators/activitypub/actor' import { regexpCapture } from '../../helpers/regexp' import { uniq } from 'lodash' @@ -28,6 +27,7 @@ import { } from '../../typings/models/video' import { MUserAccountId } from '@server/typings/models' import { VideoPrivacy } from '@shared/models' +import { getServerActor } from '@server/models/application/application' enum ScopeNames { WITH_ACCOUNT = 'WITH_ACCOUNT', diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts index 365c9581e..0d3c5a8ac 100644 --- a/server/models/video/video-format-utils.ts +++ b/server/models/video/video-format-utils.ts @@ -8,7 +8,7 @@ import { getVideoDislikesActivityPubUrl, getVideoLikesActivityPubUrl, getVideoSharesActivityPubUrl -} from '../../lib/activitypub' +} from '../../lib/activitypub/url' import { isArray } from '../../helpers/custom-validators/misc' import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model' import { @@ -23,7 +23,7 @@ import { import { MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file' import { VideoFile } from '@shared/models/videos/video-file.model' import { generateMagnetUri } from '@server/helpers/webtorrent' -import { extractVideo } from '@server/lib/videos' +import { extractVideo } from '@server/helpers/video' export type VideoFormattingJSONOptions = { completeDescription?: boolean diff --git a/server/models/video/video.ts b/server/models/video/video.ts index ccb9d64ca..96b96e5ac 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts @@ -43,7 +43,6 @@ import { } from '../../helpers/custom-validators/videos' import { getVideoFileResolution } from '../../helpers/ffmpeg-utils' import { logger } from '../../helpers/logger' -import { getServerActor } from '../../helpers/utils' import { ACTIVITY_PUB, API_VERSION, @@ -126,6 +125,7 @@ import { getHLSDirectory, getTorrentFileName, getTorrentFilePath, getVideoFilena import { ModelCache } from '@server/models/model-cache' import { buildListQuery, BuildVideosQueryOptions, wrapForAPIResults } from './video-query-builder' import { buildNSFWFilter } from '@server/helpers/express-utils' +import { getServerActor } from '@server/models/application/application' export enum ScopeNames { AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS', diff --git a/server/tests/api/activitypub/security.ts b/server/tests/api/activitypub/security.ts index 7e58bf065..ac4bc7c6a 100644 --- a/server/tests/api/activitypub/security.ts +++ b/server/tests/api/activitypub/security.ts @@ -4,10 +4,11 @@ import 'mocha' import { cleanupTests, closeAllSequelize, flushAndRunMultipleServers, ServerInfo, setActorField } from '../../../../shared/extra-utils' import { HTTP_SIGNATURE } from '../../../initializers/constants' -import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils' +import { buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils' import * as chai from 'chai' import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub' import { makeFollowRequest, makePOSTAPRequest } from '../../../../shared/extra-utils/requests/activitypub' +import { buildDigest } from '@server/helpers/peertube-crypto' const expect = chai.expect diff --git a/shared/models/server/emailer.model.ts b/shared/models/server/emailer.model.ts new file mode 100644 index 000000000..2d8feda81 --- /dev/null +++ b/shared/models/server/emailer.model.ts @@ -0,0 +1,8 @@ +export type SendEmailOptions = { + to: string[] + subject: string + text: string + + fromDisplayName?: string + replyTo?: string +} diff --git a/shared/models/server/index.ts b/shared/models/server/index.ts index bf61ab270..b0afb2c66 100644 --- a/shared/models/server/index.ts +++ b/shared/models/server/index.ts @@ -2,6 +2,7 @@ export * from './about.model' export * from './contact-form.model' export * from './custom-config.model' export * from './debug.model' +export * from './emailer.model' export * from './job.model' export * from './server-config.model' export * from './server-stats.model' diff --git a/shared/models/server/job.model.ts b/shared/models/server/job.model.ts index cf29d20d4..694361276 100644 --- a/shared/models/server/job.model.ts +++ b/shared/models/server/job.model.ts @@ -1,3 +1,7 @@ +import { ContextType } from '@server/helpers/activitypub' +import { SendEmailOptions } from './emailer.model' +import { VideoResolution } from '@shared/models' + export type JobState = 'active' | 'completed' | 'failed' | 'waiting' | 'delayed' export type JobType = @@ -23,3 +27,99 @@ export interface Job { finishedOn: Date | string processedOn: Date | string } + +export type ActivitypubHttpBroadcastPayload = { + uris: string[] + signatureActorId?: number + body: any + contextType?: ContextType +} + +export type ActivitypubFollowPayload = { + followerActorId: number + name: string + host: string + isAutoFollow?: boolean + assertIsChannel?: boolean +} + +export type FetchType = 'activity' | 'video-likes' | 'video-dislikes' | 'video-shares' | 'video-comments' | 'account-playlists' +export type ActivitypubHttpFetcherPayload = { + uri: string + type: FetchType + videoId?: number + accountId?: number +} + +export type ActivitypubHttpUnicastPayload = { + uri: string + signatureActorId?: number + body: any + contextType?: ContextType +} + +export type RefreshPayload = { + type: 'video' | 'video-playlist' | 'actor' + url: string +} + +export type EmailPayload = SendEmailOptions + +export type VideoFileImportPayload = { + videoUUID: string + filePath: string +} + +export type VideoImportYoutubeDLPayload = { + type: 'youtube-dl' + videoImportId: number + + generateThumbnail: boolean + generatePreview: boolean + + fileExt?: string +} +export type VideoImportTorrentPayload = { + type: 'magnet-uri' | 'torrent-file' + videoImportId: number +} +export type VideoImportPayload = VideoImportYoutubeDLPayload | VideoImportTorrentPayload + +export type VideoRedundancyPayload = { + videoId: number +} + +// Video transcoding payloads + +interface BaseTranscodingPayload { + videoUUID: string + isNewVideo?: boolean +} + +interface HLSTranscodingPayload extends BaseTranscodingPayload { + type: 'hls' + isPortraitMode?: boolean + resolution: VideoResolution + copyCodecs: boolean +} + +export interface NewResolutionTranscodingPayload extends BaseTranscodingPayload { + type: 'new-resolution' + isPortraitMode?: boolean + resolution: VideoResolution +} + +export interface MergeAudioTranscodingPayload extends BaseTranscodingPayload { + type: 'merge-audio' + resolution: VideoResolution +} + +export interface OptimizeTranscodingPayload extends BaseTranscodingPayload { + type: 'optimize' +} + +export type VideoTranscodingPayload = + HLSTranscodingPayload + | NewResolutionTranscodingPayload + | OptimizeTranscodingPayload + | MergeAudioTranscodingPayload