1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-05 02:39:33 +02:00

Check video rights before providing AP information

This commit is contained in:
Chocobozzz 2024-04-26 08:58:35 +02:00
parent b8635c2606
commit afb28272f5
No known key found for this signature in database
GPG key ID: 583A612D890159BE
31 changed files with 254 additions and 233 deletions

View file

@ -145,7 +145,7 @@ async function buildElementsDBAttributes (elementUrls: string[], playlist: MVide
try {
const { elementObject } = await fetchRemotePlaylistElement(elementUrl)
const { video } = await getOrCreateAPVideo({ videoObject: { id: elementObject.url }, fetchType: 'only-video' })
const { video } = await getOrCreateAPVideo({ videoObject: { id: elementObject.url }, fetchType: 'only-video-and-blacklist' })
elementsToCreate.push(playlistElementObjectToDBAttributes(elementObject, playlist, video))
} catch (err) {

View file

@ -24,7 +24,7 @@ import { createOrUpdateLocalVideoViewer } from '../local-video-viewer.js'
import { createOrUpdateVideoPlaylist } from '../playlists/index.js'
import { forwardVideoRelatedActivity } from '../send/shared/send-utils.js'
import { resolveThread } from '../video-comments.js'
import { getOrCreateAPVideo } from '../videos/index.js'
import { canVideoBeFederated, getOrCreateAPVideo } from '../videos/index.js'
async function processCreateActivity (options: APProcessorOptions<ActivityCreate<ActivityCreateObject>>) {
const { activity, byActor } = options
@ -87,6 +87,11 @@ async function processCreateCacheFile (
const { video } = await getOrCreateAPVideo({ videoObject: cacheFile.object })
if (video.isOwned() && !canVideoBeFederated(video)) {
logger.warn(`Do not process create cache file ${cacheFile.object} on a video that cannot be federated`)
return
}
await sequelizeTypescript.transaction(async t => {
return createOrUpdateCacheFile(cacheFile, video, byActor, t)
})

View file

@ -1,11 +1,12 @@
import { VideoModel } from '@server/models/video/video.js'
import { ActivityDislike } from '@peertube/peertube-models'
import { logger } from '@server/helpers/logger.js'
import { VideoModel } from '@server/models/video/video.js'
import { retryTransactionWrapper } from '../../../helpers/database-utils.js'
import { sequelizeTypescript } from '../../../initializers/database.js'
import { AccountVideoRateModel } from '../../../models/account/account-video-rate.js'
import { APProcessorOptions } from '../../../types/activitypub-processor.model.js'
import { MActorSignature } from '../../../types/models/index.js'
import { federateVideoIfNeeded, maybeGetOrCreateAPVideo } from '../videos/index.js'
import { canVideoBeFederated, federateVideoIfNeeded, maybeGetOrCreateAPVideo } from '../videos/index.js'
async function processDislikeActivity (options: APProcessorOptions<ActivityDislike>) {
const { activity, byActor } = options
@ -21,14 +22,19 @@ export {
// ---------------------------------------------------------------------------
async function processDislike (activity: ActivityDislike, byActor: MActorSignature) {
const dislikeObject = activity.object
const videoUrl = activity.object
const byAccount = byActor.Account
if (!byAccount) throw new Error('Cannot create dislike with the non account actor ' + byActor.url)
const { video: onlyVideo } = await maybeGetOrCreateAPVideo({ videoObject: dislikeObject, fetchType: 'only-video' })
const { video: onlyVideo } = await maybeGetOrCreateAPVideo({ videoObject: videoUrl, fetchType: 'only-video-and-blacklist' })
if (!onlyVideo?.isOwned()) return
if (!canVideoBeFederated(onlyVideo)) {
logger.warn(`Do not process dislike on video ${videoUrl} that cannot be federated`)
return
}
return sequelizeTypescript.transaction(async t => {
const video = await VideoModel.loadFull(onlyVideo.id, t)

View file

@ -1,4 +1,5 @@
import { ActivityLike } from '@peertube/peertube-models'
import { logger } from '@server/helpers/logger.js'
import { VideoModel } from '@server/models/video/video.js'
import { retryTransactionWrapper } from '../../../helpers/database-utils.js'
import { sequelizeTypescript } from '../../../initializers/database.js'
@ -6,7 +7,7 @@ import { getAPId } from '../../../lib/activitypub/activity.js'
import { AccountVideoRateModel } from '../../../models/account/account-video-rate.js'
import { APProcessorOptions } from '../../../types/activitypub-processor.model.js'
import { MActorSignature } from '../../../types/models/index.js'
import { federateVideoIfNeeded, maybeGetOrCreateAPVideo } from '../videos/index.js'
import { canVideoBeFederated, federateVideoIfNeeded, maybeGetOrCreateAPVideo } from '../videos/index.js'
async function processLikeActivity (options: APProcessorOptions<ActivityLike>) {
const { activity, byActor } = options
@ -28,9 +29,14 @@ async function processLikeVideo (byActor: MActorSignature, activity: ActivityLik
const byAccount = byActor.Account
if (!byAccount) throw new Error('Cannot create like with the non account actor ' + byActor.url)
const { video: onlyVideo } = await maybeGetOrCreateAPVideo({ videoObject: videoUrl, fetchType: 'only-video' })
const { video: onlyVideo } = await maybeGetOrCreateAPVideo({ videoObject: videoUrl, fetchType: 'only-video-and-blacklist' })
if (!onlyVideo?.isOwned()) return
if (!canVideoBeFederated(onlyVideo)) {
logger.warn(`Do not process like on video ${videoUrl} that cannot be federated`)
return
}
return sequelizeTypescript.transaction(async t => {
const video = await VideoModel.loadFull(onlyVideo.id, t)

View file

@ -20,7 +20,7 @@ import { APActorUpdater } from '../actors/updater.js'
import { createOrUpdateCacheFile } from '../cache-file.js'
import { createOrUpdateVideoPlaylist } from '../playlists/index.js'
import { forwardVideoRelatedActivity } from '../send/shared/send-utils.js'
import { APVideoUpdater, getOrCreateAPVideo } from '../videos/index.js'
import { APVideoUpdater, canVideoBeFederated, getOrCreateAPVideo } from '../videos/index.js'
async function processUpdateActivity (options: APProcessorOptions<ActivityUpdate<ActivityUpdateObject>>) {
const { activity, byActor } = options
@ -93,6 +93,11 @@ async function processUpdateCacheFile (
const { video } = await getOrCreateAPVideo({ videoObject: cacheFileObject.object })
if (video.isOwned() && !canVideoBeFederated(video)) {
logger.warn(`Do not process update cache file on video ${activity.object} that cannot be federated`)
return
}
await sequelizeTypescript.transaction(async t => {
await createOrUpdateCacheFile(cacheFileObject, video, byActor, t)
})

View file

@ -24,7 +24,7 @@ async function processCreateView (activity: ActivityView, byActor: MActorSignatu
const { video } = await getOrCreateAPVideo({
videoObject,
fetchType: 'only-video',
fetchType: 'only-video-and-blacklist',
allowRefresh: false
})

View file

@ -1,5 +1,3 @@
import { Transaction } from 'sequelize'
import { getServerActor } from '@server/models/application/application.js'
import {
ActivityAudience,
ActivityCreate,
@ -9,19 +7,24 @@ import {
VideoPlaylistPrivacy,
VideoPrivacy
} from '@peertube/peertube-models'
import { AccountModel } from '@server/models/account/account.js'
import { getServerActor } from '@server/models/application/application.js'
import { VideoModel } from '@server/models/video/video.js'
import { Transaction } from 'sequelize'
import { logger, loggerTagsFactory } from '../../../helpers/logger.js'
import { VideoCommentModel } from '../../../models/video/video-comment.js'
import {
MActorLight,
MCommentOwnerVideo,
MLocalVideoViewerWithWatchSections,
MVideoAccountLight,
MVideoAP,
MVideoAccountLight,
MVideoPlaylistFull,
MVideoRedundancyFileVideo,
MVideoRedundancyStreamingPlaylistVideo
} from '../../../types/models/index.js'
import { audiencify, getAudience } from '../audience.js'
import { canVideoBeFederated } from '../videos/federate.js'
import {
broadcastToActors,
broadcastToFollowers,
@ -32,12 +35,11 @@ import {
sendVideoRelatedActivity,
unicastTo
} from './shared/index.js'
import { AccountModel } from '@server/models/account/account.js'
const lTags = loggerTagsFactory('ap', 'create')
async function sendCreateVideo (video: MVideoAP, transaction: Transaction) {
if (!video.hasPrivacyForFederation()) return undefined
export async function sendCreateVideo (video: MVideoAP, transaction: Transaction) {
if (!canVideoBeFederated(video)) return undefined
logger.info('Creating job to send video creation of %s.', video.url, lTags(video.uuid))
@ -56,7 +58,7 @@ async function sendCreateVideo (video: MVideoAP, transaction: Transaction) {
})
}
async function sendCreateCacheFile (
export async function sendCreateCacheFile (
byActor: MActorLight,
video: MVideoAccountLight,
fileRedundancy: MVideoRedundancyStreamingPlaylistVideo | MVideoRedundancyFileVideo
@ -72,7 +74,7 @@ async function sendCreateCacheFile (
})
}
async function sendCreateWatchAction (stats: MLocalVideoViewerWithWatchSections, transaction: Transaction) {
export async function sendCreateWatchAction (stats: MLocalVideoViewerWithWatchSections, transaction: Transaction) {
logger.info('Creating job to send create watch action %s.', stats.url, lTags(stats.uuid))
const byActor = await getServerActor()
@ -84,7 +86,7 @@ async function sendCreateWatchAction (stats: MLocalVideoViewerWithWatchSections,
return sendVideoActivityToOrigin(activityBuilder, { byActor, video: stats.Video, transaction, contextType: 'WatchAction' })
}
async function sendCreateVideoPlaylist (playlist: MVideoPlaylistFull, transaction: Transaction) {
export async function sendCreateVideoPlaylist (playlist: MVideoPlaylistFull, transaction: Transaction) {
if (playlist.privacy === VideoPlaylistPrivacy.PRIVATE) return undefined
logger.info('Creating job to send create video playlist of %s.', playlist.url, lTags(playlist.uuid))
@ -109,11 +111,20 @@ async function sendCreateVideoPlaylist (playlist: MVideoPlaylistFull, transactio
})
}
async function sendCreateVideoComment (comment: MCommentOwnerVideo, transaction: Transaction) {
logger.info('Creating job to send comment %s.', comment.url)
export async function sendCreateVideoComment (comment: MCommentOwnerVideo, transaction: Transaction) {
const isOrigin = comment.Video.isOwned()
if (isOrigin) {
const videoWithBlacklist = await VideoModel.loadWithBlacklist(comment.Video.id)
if (!canVideoBeFederated(videoWithBlacklist)) {
logger.debug(`Do not send comment ${comment.url} on a video that cannot be federated`)
return undefined
}
}
logger.info('Creating job to send comment %s.', comment.url)
const byActor = comment.Account.Actor
const videoAccount = await AccountModel.load(comment.Video.VideoChannel.Account.id, transaction)
@ -179,7 +190,7 @@ async function sendCreateVideoComment (comment: MCommentOwnerVideo, transaction:
})
}
function buildCreateActivity <T extends ActivityCreateObject> (
export function buildCreateActivity <T extends ActivityCreateObject> (
url: string,
byActor: MActorLight,
object: T,
@ -201,16 +212,7 @@ function buildCreateActivity <T extends ActivityCreateObject> (
}
// ---------------------------------------------------------------------------
export {
sendCreateVideo,
buildCreateActivity,
sendCreateVideoComment,
sendCreateVideoPlaylist,
sendCreateCacheFile,
sendCreateWatchAction
}
// Private
// ---------------------------------------------------------------------------
async function sendVideoRelatedCreateActivity (options: {

View file

@ -1,10 +1,10 @@
import { Transaction } from 'sequelize'
import { getServerActor } from '@server/models/application/application.js'
import { ActivityAudience, ActivityUpdate, ActivityUpdateObject, VideoPlaylistPrivacy, VideoPrivacy } from '@peertube/peertube-models'
import { getServerActor } from '@server/models/application/application.js'
import { Transaction } from 'sequelize'
import { logger } from '../../../helpers/logger.js'
import { AccountModel } from '../../../models/account/account.js'
import { VideoModel } from '../../../models/video/video.js'
import { VideoShareModel } from '../../../models/video/video-share.js'
import { VideoModel } from '../../../models/video/video.js'
import {
MAccountDefault,
MActor,
@ -16,11 +16,12 @@ import {
} from '../../../types/models/index.js'
import { audiencify, getAudience } from '../audience.js'
import { getUpdateActivityPubUrl } from '../url.js'
import { canVideoBeFederated } from '../videos/federate.js'
import { getActorsInvolvedInVideo } from './shared/index.js'
import { broadcastToFollowers, sendVideoRelatedActivity } from './shared/send-utils.js'
async function sendUpdateVideo (videoArg: MVideoAPLight, transaction: Transaction, overriddenByActor?: MActor) {
if (!videoArg.hasPrivacyForFederation()) return undefined
export async function sendUpdateVideo (videoArg: MVideoAPLight, transaction: Transaction, overriddenByActor?: MActor) {
if (!canVideoBeFederated(videoArg)) return undefined
const video = await videoArg.lightAPToFullAP(transaction)
@ -47,7 +48,7 @@ async function sendUpdateVideo (videoArg: MVideoAPLight, transaction: Transactio
})
}
async function sendUpdateActor (accountOrChannel: MChannelDefault | MAccountDefault, transaction: Transaction) {
export async function sendUpdateActor (accountOrChannel: MChannelDefault | MAccountDefault, transaction: Transaction) {
const byActor = accountOrChannel.Actor
logger.info('Creating job to update actor %s.', byActor.url)
@ -77,7 +78,7 @@ async function sendUpdateActor (accountOrChannel: MChannelDefault | MAccountDefa
})
}
async function sendUpdateCacheFile (byActor: MActorLight, redundancyModel: MVideoRedundancyVideo) {
export async function sendUpdateCacheFile (byActor: MActorLight, redundancyModel: MVideoRedundancyVideo) {
logger.info('Creating job to update cache file %s.', redundancyModel.url)
const associatedVideo = redundancyModel.getVideo()
@ -98,7 +99,7 @@ async function sendUpdateCacheFile (byActor: MActorLight, redundancyModel: MVide
return sendVideoRelatedActivity(activityBuilder, { byActor, video, contextType: 'CacheFile' })
}
async function sendUpdateVideoPlaylist (videoPlaylist: MVideoPlaylistFull, transaction: Transaction) {
export async function sendUpdateVideoPlaylist (videoPlaylist: MVideoPlaylistFull, transaction: Transaction) {
if (videoPlaylist.privacy === VideoPlaylistPrivacy.PRIVATE) return undefined
const byActor = videoPlaylist.OwnerAccount.Actor
@ -127,14 +128,7 @@ async function sendUpdateVideoPlaylist (videoPlaylist: MVideoPlaylistFull, trans
}
// ---------------------------------------------------------------------------
export {
sendUpdateActor,
sendUpdateVideo,
sendUpdateCacheFile,
sendUpdateVideoPlaylist
}
// Private
// ---------------------------------------------------------------------------
function buildUpdateActivity (

View file

@ -1,6 +1,6 @@
import { getServerActor } from '@server/models/application/application.js'
import Bluebird from 'bluebird'
import { Transaction } from 'sequelize'
import { getServerActor } from '@server/models/application/application.js'
import { logger, loggerTagsFactory } from '../../helpers/logger.js'
import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants.js'
import { VideoShareModel } from '../../models/video/video-share.js'
@ -12,16 +12,7 @@ import { checkUrlsSameHost, getLocalVideoAnnounceActivityPubUrl } from './url.js
const lTags = loggerTagsFactory('share')
async function shareVideoByServerAndChannel (video: MVideoAccountLight, t: Transaction) {
if (!video.hasPrivacyForFederation()) return undefined
return Promise.all([
shareByServer(video, t),
shareByVideoChannel(video, t)
])
}
async function changeVideoChannelShare (
export async function changeVideoChannelShare (
video: MVideoAccountLight,
oldVideoChannel: MChannelActorLight,
t: Transaction
@ -36,7 +27,7 @@ async function changeVideoChannelShare (
await shareByVideoChannel(video, t)
}
async function addVideoShares (shareUrls: string[], video: MVideoId) {
export async function addVideoShares (shareUrls: string[], video: MVideoId) {
await Bluebird.map(shareUrls, async shareUrl => {
try {
await addVideoShare(shareUrl, video)
@ -46,12 +37,44 @@ async function addVideoShares (shareUrls: string[], video: MVideoId) {
}, { concurrency: CRAWL_REQUEST_CONCURRENCY })
}
export {
changeVideoChannelShare,
addVideoShares,
shareVideoByServerAndChannel
export async function shareByServer (video: MVideo, t: Transaction) {
const serverActor = await getServerActor()
const serverShareUrl = getLocalVideoAnnounceActivityPubUrl(serverActor, video)
const [ serverShare ] = await VideoShareModel.findOrCreate({
defaults: {
actorId: serverActor.id,
videoId: video.id,
url: serverShareUrl
},
where: {
url: serverShareUrl
},
transaction: t
})
return sendVideoAnnounce(serverActor, serverShare, video, t)
}
export async function shareByVideoChannel (video: MVideoAccountLight, t: Transaction) {
const videoChannelShareUrl = getLocalVideoAnnounceActivityPubUrl(video.VideoChannel.Actor, video)
const [ videoChannelShare ] = await VideoShareModel.findOrCreate({
defaults: {
actorId: video.VideoChannel.actorId,
videoId: video.id,
url: videoChannelShareUrl
},
where: {
url: videoChannelShareUrl
},
transaction: t
})
return sendVideoAnnounce(video.VideoChannel.Actor, videoChannelShare, video, t)
}
// ---------------------------------------------------------------------------
// Private
// ---------------------------------------------------------------------------
async function addVideoShare (shareUrl: string, video: MVideoId) {
@ -74,42 +97,6 @@ async function addVideoShare (shareUrl: string, video: MVideoId) {
await VideoShareModel.upsert(entry)
}
async function shareByServer (video: MVideo, t: Transaction) {
const serverActor = await getServerActor()
const serverShareUrl = getLocalVideoAnnounceActivityPubUrl(serverActor, video)
const [ serverShare ] = await VideoShareModel.findOrCreate({
defaults: {
actorId: serverActor.id,
videoId: video.id,
url: serverShareUrl
},
where: {
url: serverShareUrl
},
transaction: t
})
return sendVideoAnnounce(serverActor, serverShare, video, t)
}
async function shareByVideoChannel (video: MVideoAccountLight, t: Transaction) {
const videoChannelShareUrl = getLocalVideoAnnounceActivityPubUrl(video.VideoChannel.Actor, video)
const [ videoChannelShare ] = await VideoShareModel.findOrCreate({
defaults: {
actorId: video.VideoChannel.actorId,
videoId: video.id,
url: videoChannelShareUrl
},
where: {
url: videoChannelShareUrl
},
transaction: t
})
return sendVideoAnnounce(video.VideoChannel.Actor, videoChannelShare, video, t)
}
async function undoShareByVideoChannel (video: MVideo, oldVideoChannel: MChannelActorLight, t: Transaction) {
// Load old share
const oldShare = await VideoShareModel.load(oldVideoChannel.actorId, video.id, t)

View file

@ -9,7 +9,7 @@ import { Hooks } from '../plugins/hooks.js'
import { fetchAP } from './activity.js'
import { getOrCreateAPActor } from './actors/index.js'
import { checkUrlsSameHost } from './url.js'
import { getOrCreateAPVideo } from './videos/index.js'
import { canVideoBeFederated, getOrCreateAPVideo } from './videos/index.js'
type ResolveThreadParams = {
url: string
@ -92,8 +92,8 @@ async function tryToResolveThreadFromVideo (params: ResolveThreadParams) {
const syncParam = { rates: true, shares: true, comments: false, refreshVideo: false }
const { video } = await getOrCreateAPVideo({ videoObject: url, syncParam })
if (video.isOwned() && !video.hasPrivacyForFederation()) {
throw new Error('Cannot resolve thread of video with privacy that is not compatible with federation')
if (video.isOwned() && !canVideoBeFederated(video)) {
throw new Error('Cannot resolve thread of video that is not compatible with federation')
}
let resultComment: MCommentOwnerVideo

View file

@ -1,29 +1,53 @@
import { forceNumber } from '@peertube/peertube-core-utils'
import { VideoPrivacy, VideoPrivacyType, VideoState, VideoStateType } from '@peertube/peertube-models'
import { CONFIG } from '@server/initializers/config.js'
import { MVideoAPLight, MVideoWithBlacklistRights } from '@server/types/models/index.js'
import { Transaction } from 'sequelize'
import { MVideoAP, MVideoAPLight } from '@server/types/models/index.js'
import { sendCreateVideo, sendUpdateVideo } from '../send/index.js'
import { shareVideoByServerAndChannel } from '../share.js'
import { shareByServer, shareByVideoChannel } from '../share.js'
async function federateVideoIfNeeded (videoArg: MVideoAPLight, isNewVideo: boolean, transaction?: Transaction) {
const video = videoArg as MVideoAP
export async function federateVideoIfNeeded (videoArg: MVideoAPLight, isNewVideo: boolean, transaction?: Transaction) {
if (!canVideoBeFederated(videoArg, isNewVideo)) return
if (
// Check this is not a blacklisted video, or unfederated blacklisted video
(video.isBlacklisted() === false || (isNewVideo === false && video.VideoBlacklist.unfederated === false)) &&
// Check the video is public/unlisted and published
video.hasPrivacyForFederation() && video.hasStateForFederation()
) {
const video = await videoArg.lightAPToFullAP(transaction)
const video = await videoArg.lightAPToFullAP(transaction)
if (isNewVideo) {
// Now we'll add the video's meta data to our followers
await sendCreateVideo(video, transaction)
await shareVideoByServerAndChannel(video, transaction)
} else {
await sendUpdateVideo(video, transaction)
}
if (isNewVideo) {
// Now we'll add the video's meta data to our followers
await sendCreateVideo(video, transaction)
await Promise.all([
shareByServer(video, transaction),
shareByVideoChannel(video, transaction)
])
} else {
await sendUpdateVideo(video, transaction)
}
}
export {
federateVideoIfNeeded
export function canVideoBeFederated (video: MVideoWithBlacklistRights, isNewVideo = false) {
// Check this is not a blacklisted video
if (video.isBlacklisted() === true) {
if (isNewVideo === false) return false
if (video.VideoBlacklist.unfederated === true) return false
}
// Check the video is public/unlisted and published
return isPrivacyForFederation(video.privacy) && isStateForFederation(video.state)
}
export function isNewVideoPrivacyForFederation (currentPrivacy: VideoPrivacyType, newPrivacy: VideoPrivacyType) {
return !isPrivacyForFederation(currentPrivacy) && isPrivacyForFederation(newPrivacy)
}
export function isPrivacyForFederation (privacy: VideoPrivacyType) {
const castedPrivacy = forceNumber(privacy)
return castedPrivacy === VideoPrivacy.PUBLIC ||
(CONFIG.FEDERATION.VIDEOS.FEDERATE_UNLISTED === true && castedPrivacy === VideoPrivacy.UNLISTED)
}
export function isStateForFederation (state: VideoStateType) {
const castedState = forceNumber(state)
return castedState === VideoState.PUBLISHED || castedState === VideoState.WAITING_FOR_LIVE || castedState === VideoState.LIVE_ENDED
}

View file

@ -1,9 +1,14 @@
import { APObjectId } from '@peertube/peertube-models'
import { retryTransactionWrapper } from '@server/helpers/database-utils.js'
import { logger } from '@server/helpers/logger.js'
import { JobQueue } from '@server/lib/job-queue/index.js'
import { loadVideoByUrl, VideoLoadByUrlType } from '@server/lib/model-loaders/index.js'
import { MVideoAccountLightBlacklistAllFiles, MVideoImmutable, MVideoThumbnail } from '@server/types/models/index.js'
import { APObjectId } from '@peertube/peertube-models'
import {
MVideoAccountLightBlacklistAllFiles,
MVideoImmutable,
MVideoThumbnail,
MVideoThumbnailBlacklist
} from '@server/types/models/index.js'
import { getAPId } from '../activity.js'
import { refreshVideoIfNeeded } from './refresh.js'
import { APVideoCreator, fetchRemoteVideo, SyncParam, syncVideoExternalAttributes } from './shared/index.js'
@ -24,23 +29,25 @@ type GetVideoParamAll = {
type GetVideoParamImmutable = {
videoObject: APObjectId
syncParam?: SyncParam
fetchType: 'only-immutable-attributes'
fetchType: 'unsafe-only-immutable-attributes'
allowRefresh: false
}
type GetVideoParamOther = {
videoObject: APObjectId
syncParam?: SyncParam
fetchType?: 'all' | 'only-video'
fetchType?: 'all' | 'only-video-and-blacklist'
allowRefresh?: boolean
}
export function getOrCreateAPVideo (options: GetVideoParamAll): GetVideoResult<MVideoAccountLightBlacklistAllFiles>
export function getOrCreateAPVideo (options: GetVideoParamImmutable): GetVideoResult<MVideoImmutable>
export function getOrCreateAPVideo (options: GetVideoParamOther): GetVideoResult<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail>
export function getOrCreateAPVideo (
options: GetVideoParamOther
): GetVideoResult<MVideoAccountLightBlacklistAllFiles | MVideoThumbnailBlacklist>
export async function getOrCreateAPVideo (
options: GetVideoParamAll | GetVideoParamImmutable | GetVideoParamOther
): GetVideoResult<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> {
): GetVideoResult<MVideoAccountLightBlacklistAllFiles | MVideoThumbnailBlacklist | MVideoImmutable> {
// Default params
const syncParam = options.syncParam || { rates: true, shares: true, comments: true, refreshVideo: false }
const fetchType = options.fetchType || 'all'
@ -52,7 +59,7 @@ export async function getOrCreateAPVideo (
if (videoFromDatabase) {
if (allowRefresh === true) {
// Typings ensure allowRefresh === false in only-immutable-attributes fetch type
// Typings ensure allowRefresh === false in unsafe-only-immutable-attributes fetch type
videoFromDatabase = await scheduleRefresh(videoFromDatabase as MVideoThumbnail, fetchType, syncParam)
}
@ -87,7 +94,9 @@ export async function getOrCreateAPVideo (
export function maybeGetOrCreateAPVideo (options: GetVideoParamAll): GetVideoResult<MVideoAccountLightBlacklistAllFiles>
export function maybeGetOrCreateAPVideo (options: GetVideoParamImmutable): GetVideoResult<MVideoImmutable>
export function maybeGetOrCreateAPVideo (options: GetVideoParamOther): GetVideoResult<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail>
export function maybeGetOrCreateAPVideo (
options: GetVideoParamOther
): GetVideoResult<MVideoAccountLightBlacklistAllFiles | MVideoThumbnailBlacklist>
export async function maybeGetOrCreateAPVideo (options: GetVideoParamAll | GetVideoParamImmutable | GetVideoParamOther) {
try {
const result = await getOrCreateAPVideo(options as any)