import { auditLoggerFactory, getAuditIdFromRes, VideoChannelAuditView } from '../../helpers/audit-logger'
import { resetSequelizeInstance } from '../../helpers/database-utils'
import { UserModel } from '../../models/account/user'
+import { JobQueue } from '../../lib/job-queue'
const auditLogger = auditLoggerFactory('channels')
const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })
async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoChannelWithVideos = await VideoChannelModel.loadAndPopulateAccountAndVideos(res.locals.videoChannel.id)
+ if (videoChannelWithVideos.isOutdated()) {
+ JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: videoChannelWithVideos.Actor.url } })
+ .catch(err => logger.error('Cannot create AP refresher job for actor %s.', videoChannelWithVideos.Actor.url, { err }))
+ }
+
return res.json(videoChannelWithVideos.toFormattedJSON())
}
return JobQueue.Instance.createJob({ type: 'activitypub-http-fetcher', payload })
}
+async function refreshActorIfNeeded (
+ actorArg: ActorModel,
+ fetchedType: ActorFetchByUrlType
+): Promise<{ actor: ActorModel, refreshed: boolean }> {
+ if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false }
+
+ // We need more attributes
+ const actor = fetchedType === 'all' ? actorArg : await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorArg.url)
+
+ try {
+ const actorUrl = await getUrlFromWebfinger(actor.preferredUsername + '@' + actor.getHost())
+ const { result, statusCode } = await fetchRemoteActor(actorUrl)
+
+ if (statusCode === 404) {
+ logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url)
+ actor.Account ? actor.Account.destroy() : actor.VideoChannel.destroy()
+ return { actor: undefined, refreshed: false }
+ }
+
+ if (result === undefined) {
+ logger.warn('Cannot fetch remote actor in refresh actor.')
+ return { actor, refreshed: false }
+ }
+
+ return sequelizeTypescript.transaction(async t => {
+ updateInstanceWithAnother(actor, result.actor)
+
+ if (result.avatarName !== undefined) {
+ await updateActorAvatarInstance(actor, result.avatarName, t)
+ }
+
+ // Force update
+ actor.setDataValue('updatedAt', new Date())
+ await actor.save({ transaction: t })
+
+ if (actor.Account) {
+ actor.Account.set('name', result.name)
+ actor.Account.set('description', result.summary)
+
+ await actor.Account.save({ transaction: t })
+ } else if (actor.VideoChannel) {
+ actor.VideoChannel.set('name', result.name)
+ actor.VideoChannel.set('description', result.summary)
+ actor.VideoChannel.set('support', result.support)
+
+ await actor.VideoChannel.save({ transaction: t })
+ }
+
+ return { refreshed: true, actor }
+ })
+ } catch (err) {
+ logger.warn('Cannot refresh actor.', { err })
+ return { actor, refreshed: false }
+ }
+}
+
export {
getOrCreateActorAndServerAndModel,
buildActorInstance,
fetchActorTotalItems,
fetchAvatarIfExists,
updateActorInstance,
+ refreshActorIfNeeded,
updateActorAvatarInstance,
addFetchOutboxJob
}
return videoChannelCreated
}
-async function refreshActorIfNeeded (
- actorArg: ActorModel,
- fetchedType: ActorFetchByUrlType
-): Promise<{ actor: ActorModel, refreshed: boolean }> {
- if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false }
-
- // We need more attributes
- const actor = fetchedType === 'all' ? actorArg : await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorArg.url)
-
- try {
- const actorUrl = await getUrlFromWebfinger(actor.preferredUsername + '@' + actor.getHost())
- const { result, statusCode } = await fetchRemoteActor(actorUrl)
-
- if (statusCode === 404) {
- logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url)
- actor.Account ? actor.Account.destroy() : actor.VideoChannel.destroy()
- return { actor: undefined, refreshed: false }
- }
-
- if (result === undefined) {
- logger.warn('Cannot fetch remote actor in refresh actor.')
- return { actor, refreshed: false }
- }
- return sequelizeTypescript.transaction(async t => {
- updateInstanceWithAnother(actor, result.actor)
-
- if (result.avatarName !== undefined) {
- await updateActorAvatarInstance(actor, result.avatarName, t)
- }
-
- // Force update
- actor.setDataValue('updatedAt', new Date())
- await actor.save({ transaction: t })
-
- if (actor.Account) {
- actor.Account.set('name', result.name)
- actor.Account.set('description', result.summary)
-
- await actor.Account.save({ transaction: t })
- } else if (actor.VideoChannel) {
- actor.VideoChannel.set('name', result.name)
- actor.VideoChannel.set('description', result.summary)
- actor.VideoChannel.set('support', result.support)
-
- await actor.VideoChannel.save({ transaction: t })
- }
-
- return { refreshed: true, actor }
- })
- } catch (err) {
- logger.warn('Cannot refresh actor.', { err })
- return { actor, refreshed: false }
- }
-}
import * as Bull from 'bull'
import { logger } from '../../../helpers/logger'
import { fetchVideoByUrl } from '../../../helpers/video'
-import { refreshVideoIfNeeded } from '../../activitypub'
+import { refreshVideoIfNeeded, refreshActorIfNeeded } from '../../activitypub'
+import { ActorModel } from '../../../models/activitypub/actor'
export type RefreshPayload = {
- videoUrl: string
- type: 'video'
+ type: 'video' | 'actor'
+ url: string
}
async function refreshAPObject (job: Bull.Job) {
const payload = job.data as RefreshPayload
- logger.info('Processing AP refresher in job %d for video %s.', job.id, payload.videoUrl)
+ logger.info('Processing AP refresher in job %d for %s.', job.id, payload.url)
- if (payload.type === 'video') return refreshAPVideo(payload.videoUrl)
+ if (payload.type === 'video') return refreshVideo(payload.url)
+ if (payload.type === 'actor') return refreshActor(payload.url)
}
// ---------------------------------------------------------------------------
export {
+ refreshActor,
refreshAPObject
}
// ---------------------------------------------------------------------------
-async function refreshAPVideo (videoUrl: string) {
+async function refreshVideo (videoUrl: string) {
const fetchType = 'all' as 'all'
const syncParam = { likes: true, dislikes: true, shares: true, comments: true, thumbnail: true }
await refreshVideoIfNeeded(refreshOptions)
}
}
+
+async function refreshActor (actorUrl: string) {
+ const fetchType = 'all' as 'all'
+ const actor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorUrl)
+
+ if (actor) {
+ await refreshActorIfNeeded(actor, fetchType)
+ }
+
+}