Avoir some circular dependencies
authorChocobozzz <me@florianbigard.com>
Thu, 23 Apr 2020 07:32:53 +0000 (09:32 +0200)
committerChocobozzz <chocobozzz@cpy.re>
Mon, 4 May 2020 14:21:39 +0000 (16:21 +0200)
69 files changed:
scripts/create-transcoding-job.ts
server/controllers/activitypub/client.ts
server/controllers/api/accounts.ts
server/controllers/api/search.ts
server/controllers/api/server/follows.ts
server/controllers/api/server/server-blocklist.ts
server/controllers/api/video-channel.ts
server/controllers/api/video-playlist.ts
server/controllers/api/videos/abuse.ts
server/controllers/api/videos/blacklist.ts
server/controllers/api/videos/captions.ts
server/controllers/api/videos/import.ts
server/controllers/api/videos/index.ts
server/controllers/api/videos/ownership.ts
server/controllers/api/videos/rate.ts
server/helpers/peertube-crypto.ts
server/helpers/utils.ts
server/helpers/video.ts
server/helpers/webtorrent.ts
server/initializers/checker-after-init.ts
server/lib/activitypub/actor.ts
server/lib/activitypub/follow.ts
server/lib/activitypub/index.ts [deleted file]
server/lib/activitypub/process/process-follow.ts
server/lib/activitypub/send/send-create.ts
server/lib/activitypub/send/send-delete.ts
server/lib/activitypub/send/send-update.ts
server/lib/activitypub/send/utils.ts
server/lib/activitypub/share.ts
server/lib/activitypub/videos.ts
server/lib/avatar.ts
server/lib/emailer.ts
server/lib/job-queue/handlers/activitypub-follow.ts
server/lib/job-queue/handlers/activitypub-http-broadcast.ts
server/lib/job-queue/handlers/activitypub-http-fetcher.ts
server/lib/job-queue/handlers/activitypub-http-unicast.ts
server/lib/job-queue/handlers/activitypub-refresher.ts
server/lib/job-queue/handlers/email.ts
server/lib/job-queue/handlers/utils/activitypub-http-utils.ts
server/lib/job-queue/handlers/video-file-import.ts
server/lib/job-queue/handlers/video-import.ts
server/lib/job-queue/handlers/video-redundancy.ts
server/lib/job-queue/handlers/video-transcoding.ts
server/lib/job-queue/handlers/video-views.ts
server/lib/job-queue/job-queue.ts
server/lib/notifier.ts
server/lib/redundancy.ts
server/lib/schedulers/auto-follow-index-instances.ts
server/lib/schedulers/update-videos-scheduler.ts
server/lib/schedulers/videos-redundancy-scheduler.ts
server/lib/video-comment.ts
server/lib/video-paths.ts
server/lib/video-playlist.ts
server/lib/videos.ts [deleted file]
server/middlewares/activitypub.ts
server/middlewares/validators/activitypub/activity.ts
server/middlewares/validators/blocklist.ts
server/middlewares/validators/follows.ts
server/middlewares/validators/videos/videos.ts
server/models/activitypub/actor-follow.ts
server/models/application/application.ts
server/models/redundancy/video-redundancy.ts
server/models/video/video-comment.ts
server/models/video/video-format-utils.ts
server/models/video/video.ts
server/tests/api/activitypub/security.ts
shared/models/server/emailer.model.ts [new file with mode: 0644]
shared/models/server/index.ts
shared/models/server/job.model.ts

index fec58da2ee667007c2388af7d275a293011c8911..1312e8952924e93ab14749894c235426af0d77d5 100755 (executable)
@@ -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')
index c3aeeebf55b64994639898e1821d916a17b9f9ad..e44f1c6ab8440ac742c4bb768bcc8be4a2bd1660 100644 (file)
@@ -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())
index f8d2bad8bc79a9ac9363c1f9eeb34cec2ed6ef85..3bbb0a43e943d3d42b3a7182b4ef6ce453df8ccf 100644 (file)
@@ -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()
 
index 16ffbf683991eba6841ccafdeac4117225e29bf9..35d94d747e4a2c3164cb2e558b50f0d2077fe6e7 100644 (file)
@@ -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()
 
index 0bc20bd605fecd774a50641393e5ef317348f1d6..82e9ef898c329aa8aaa8a605c08c55c334832398 100644 (file)
@@ -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',
index ffb7814fa1d128d97d3ddef92d32fce97108a430..008b8d4ea0d70f33b8343efd8ba2bcdc070b1949 100644 (file)
@@ -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()
 
index a808896ffd0053a1eef373a4e19f95b6eede129a..faef5ba4b0309bfe7f92d7ee6dee6e21cae54987 100644 (file)
@@ -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 })
index aa9053372cf00ef7e070f447cccd460436662dc0..49ac3c80e410a2f1e5b635333699383420b610e7 100644 (file)
@@ -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 })
 
index f37d908969f0daf678315f7629982efa9903fb6c..bc7df48c85b33cfcab095330ae161bc3d0ca823d 100644 (file)
@@ -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()
index c4aa79cd21c20708a8931dbff17cb681c7ce369b..abd09387cf45b44cde1d71101541ba14b65f6efd 100644 (file)
@@ -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()
index fd7b165fb9ca45f735214f3c8336c2ccb75f89d9..8c1d12ca86e66dcc73ab7bb7b6cffb55c8f44d9b 100644 (file)
@@ -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'
index be96ef42c9129f1965b5db4dbdea2fa3e633e3ff..b4f70a086e1493d4ca6ad3cab3fcb6c05b420204 100644 (file)
@@ -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'
index 04d775cbfe79c23853cea491f48feb93f8ad8e86..8048c568c78b69f179fe88ac0d1cd4dbb3e23c27 100644 (file)
@@ -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()
index 41d7cdc43b50b77b62e5f32a590f1848bd2caec6..190036f85ee60a3002633281666e0da98e4da338 100644 (file)
@@ -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'
index 3d2f3d7281bef752ac12b193574be68dcac5fb04..3ee365289466d9f45240b824814ea208ca57c090 100644 (file)
@@ -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'
index 89c0ab1515b24d962dca7ddbe21b47100733e3d6..394e97fd57fafb07aac0fc25e49c6c5a565d85fa 100644 (file)
@@ -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,
index 11c11829285954db39224a0e53c7945d87119acd..ad3b7949e586d6baeba36569b9f40a0faf9c9c72 100644 (file)
@@ -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<U, V, T extends FormattableToJSON<U, V>> (objects:
   } as ResultList<V>
 }
 
-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
index 4fe2a60f0d57ca925bbee339c373cc063919f0a4..6f76cbdfc755a23f14f882600b86a7366e93747d 100644 (file)
@@ -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
 }
index b25e44fcd512bf8cc4aec3191bf8eedff20ceb62..7cd76d7085378e913f66d3cc8dc5794ec3911be3 100644 (file)
@@ -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<string, any, any>(createTorrent)
 
index a57d552df1f8e02396d4f4532970705885ae6b7a..f111be2ae6fccee3319f063c3f734ccf35aa1ca9 100644 (file)
@@ -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'
index 8132ac135ca8e374506c3086b590bbe18e4bb0d2..c743dcf3f4a2117aa85da6a28398ac56350b2e31 100644 (file)
@@ -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 <T extends MActor> (actor: T) {
index a1c95504e3d7d6af694598bc5b8c8b306592d99a..3b5ad47c93ba8491ab76789afb7452461450560f 100644 (file)
@@ -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 (file)
index d8c7d83..0000000
+++ /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'
index db7fb85684fb22d03676d6516149ab95a198e0c8..8f7828e417ec78f76aa1c6853b91b33b229ab09b 100644 (file)
@@ -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<ActivityFollow>) {
   const { activity, byActor } = options
index e2fa061e882f033dd4abc7306221d0af63a63825..0635c7b661198a8989084855aae4528549d505aa 100644 (file)
@@ -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
index 3225ebf32e64e9f7ff2ed8800abdd58003ab0100..fd3f06dec36383033cfc4d0d14a662441ac47119 100644 (file)
@@ -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)
index 2b01ca5e7130ace36eeab61e49ef5d4817e9bc1f..7a4cf3f569e2da11ab61c66044ef21b36ad1095a 100644 (file)
@@ -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
index 6fd53d71b6058558937e20d8c79a6d998b5bd158..0dfcc51be37eb7936f1afe03705e57aa700455c5 100644 (file)
@@ -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
index a7c6450627a26a8fbdbef22dfd0dcb8983e9b476..d2cbc59a86554ae5c1b0d60a60f8a95ad56a12e8 100644 (file)
@@ -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
index 62f589272e8fdfdfbdda3767bbe9e74a5753d1ad..7d16bd3908fd42f1cc78567f486154e8aefaa8d0 100644 (file)
@@ -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'
index 3de45dd1926e7eead75e07b2f352d67ec260ba89..282d834a2ba79fab1e841387df996e5de41392ef 100644 (file)
@@ -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'
index 5a99edc7f68bd196ed8e32de6254c0800b7db30a..45d57fd28a7a7b3479c20fc90587f851466f8149 100644 (file)
@@ -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
 }
index e467c5b1b12a1f0f7f1cf8cb469440e1a6445ce8..7034c10d09b3f11a1bea501fb1f0eddc5d50e2b3 100644 (file)
@@ -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
index 7d9dd61e9475f2e0a53e42c8f13c6b27026d40e9..e4d3dbbff23d31ba104ead3049cc89b3219160c8 100644 (file)
@@ -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)
index 0182c5169f17ac0c2be83afdee3337499f64fea0..524aadc27af33365d26d4225323bbcdbd573ce9b 100644 (file)
@@ -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)
index 6b71e28916c82aa8dd2fa6d0b8a07dfc496458b2..b65eeb677cd7f4fd380472a3a7be9ccde887a96a 100644 (file)
@@ -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)
index 4d6c38cfa0136ee122af6dc839c49fb6e4861362..666e568684edbf3d3d80c17724c5adfa46949d8f 100644 (file)
@@ -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
index 62701222cb2b872a578738e614684565a5c24801..3157731e2ea5e5afe4474f301b45c5e597c96059 100644 (file)
@@ -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
index 258ffabeefc47f83135213e65fdd103dbeabaede..437ea06fc1779fb952a0cbf07e7d9ac5d5ac901c 100644 (file)
@@ -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
index be9e7d181b0e65aa91ab29176a0edc8c69302bba..ae11f1de3c88dd20350a86c881d58cf1e7c9f7e0 100644 (file)
@@ -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
index 6cdae5b03a3729e3e9d2ddda71c1c67c73bb1f84..ad549c6fca15d62b19d115595ea6359fdc4c0052 100644 (file)
@@ -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
index 319d7090e755581a44325419866cc38c2689bcfd..6296dab052beb04ce321c16cc967a45ced986a3b 100644 (file)
@@ -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
index c020057c932052113ba0f437216dc3f3e2d3fe9b..46add57d492bce13b55af7e0aacd3c9f57805c6a 100644 (file)
@@ -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)
index 2258cd02989304c3216d094939e3528ee4622767..7211df237d36de81dd66d741d7f17d6c76885ff8 100644 (file)
@@ -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()
index 14acace7da80a35f0d10338a6f73aa4c9c961e47..d8d64caaf348bae8e464cfb58bbd1d53f26e46dd 100644 (file)
@@ -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 } |
index 63197eee13deaa67e1594f6898824bffd2592b19..710c2d30f488989db7d5cbd2cda4289be4358f48 100644 (file)
@@ -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 {
 
index aa0e37478b3169ba36e3fc754d64df1462ef5d15..361b401a50db342618160af53880dd87fe4f695b 100644 (file)
@@ -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()
index a1f5e4a916800d5cf34e065705e53dbc7f133793..e852c7fc6889f2340ea11ccf88e33b2122de7c72 100644 (file)
@@ -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 {
 
index 956780a776529ba1b77967f39e577e496d99d9eb..d32c1c06897573cdc0e83b1c867634da72503d40 100644 (file)
@@ -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'
index e33a4133aeba7490bc4fa2c40c8ac6b9fb9bec25..8da9d52b50b5ad85af628ba912a8594c3a47a656 100644 (file)
@@ -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
index fe83d23e7b1c766646a0dbc2a4909024f72b56e2..516c912a90a30f0f3e679e65e37384ee6a3c3542 100644 (file)
@@ -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'
 
index fe0a004e455b765d84724a25c1a0f1017b62ef3e..05aaca8afd64ddc104df02be39fcca27dd08cf2a 100644 (file)
@@ -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 ##################
 
index 29b70cfda0b4bd3507769c6012326d7cc0a73d1c..75fbd68966c5070693ad92c777c43d9d55c84ed6 100644 (file)
@@ -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 (file)
index 96bdd42..0000000
+++ /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
-}
index 45899818e57d243615255adad470868b0eba5075..580606a68387067186565384432261e91d3f8f5d 100644 (file)
@@ -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'
index 7582f65e76f4c4d41004f41e33a99aa4334b20f1..7350be5d5edbb1d160e63af2fc81b4d5c1314d17 100644 (file)
@@ -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')
index b2183437c8bf60cf90aa14b7aa508f95dd11f382..c00a7e4df5e22c204f7d958e106bd8c7992bf0e4 100644 (file)
@@ -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'),
index a98d32d8664dc938b04c8548f1f252050d23358e..7808135f73c18298205129ef65dc59ef35e310a5 100644 (file)
@@ -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')
index 3a7869354606d5e152519728879dc58a6964283a..867c05fc13f8152dca39732973f07adb3e9882ab 100644 (file)
@@ -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')
index 5a8e450a5ccc4ed9618157cd74e34749471a3cf9..85a371026676cea9bfbc9bafaaf72faa407183f3 100644 (file)
@@ -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',
index 81320b9afeafae058c72947b2c3b1accca5b06b0..3bba2c70e3600476dc7d22693e3f0f9e747eb20b 100644 (file)
@@ -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: [
index 857b9eca6b8c45cc7fb1a5554c1dc277153e1974..6021408bfeedc30300cd781baeb1dc56dfc39612 100644 (file)
@@ -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'
index 7cdff8c2cbefb6ba6d162d4b89cf83d6c1be8e31..b7ed6240e25f5c22018676f7535de4bd112b5624 100644 (file)
@@ -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',
index 365c9581e60ff25aa687a7d11d97e1d92db3cd1f..0d3c5a8acc439d2b3d5aa4514625c3b6ab900fb6 100644 (file)
@@ -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
index ccb9d64ca4ad24a583429d58f75e23a5b647596e..96b96e5ac3a893f461182a9780e02e287f00d551 100644 (file)
@@ -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',
index 7e58bf0652fe834cd951d4a6000c175be6ba22de..ac4bc7c6a384f73d7193d7801f0e838b053b780e 100644 (file)
@@ -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 (file)
index 0000000..2d8feda
--- /dev/null
@@ -0,0 +1,8 @@
+export type SendEmailOptions = {
+  to: string[]
+  subject: string
+  text: string
+
+  fromDisplayName?: string
+  replyTo?: string
+}
index bf61ab270607af8593bb3aad87880dfd71e80514..b0afb2c667fb925955441c542660e6e0087d2ea6 100644 (file)
@@ -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'
index cf29d20d40098d05d828017df950512aafa78b5b..694361276c23c8bc051dfe9ad2046c4219b26226 100644 (file)
@@ -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