import { VideoModel } from '../models/video/video'
import { VideoChannelModel } from '../models/video/video-channel'
import { VideoPlaylistModel } from '../models/video/video-playlist'
-import { MAccountActor, MChannelActor } from '../types/models'
+import { MAccountActor, MChannelActor, MVideo, MVideoPlaylist } from '../types/models'
import { getActivityStreamDuration } from './activitypub/activity'
import { getBiggestActorImage } from './actor-image'
+import { Hooks } from './plugins/hooks'
import { ServerConfigManager } from './server-config-manager'
type Tags = {
}
}
+type HookContext = {
+ video?: MVideo
+ playlist?: MVideoPlaylist
+}
+
class ClientHtml {
private static htmlCache: { [path: string]: string } = {}
const twitterCard = CONFIG.SERVICES.TWITTER.WHITELISTED ? 'player' : 'summary_large_image'
const schemaType = 'VideoObject'
- customHtml = ClientHtml.addTags(customHtml, {
+ customHtml = await ClientHtml.addTags(customHtml, {
url,
originUrl,
escapedSiteName: escapeHTML(siteName),
ogType,
twitterCard,
schemaType
- })
+ }, { video })
return customHtml
}
const twitterCard = CONFIG.SERVICES.TWITTER.WHITELISTED ? 'player' : 'summary'
const schemaType = 'ItemList'
- customHtml = ClientHtml.addTags(customHtml, {
+ customHtml = await ClientHtml.addTags(customHtml, {
url,
originUrl,
escapedSiteName: escapeHTML(siteName),
ogType,
twitterCard,
schemaType
- })
+ }, { playlist: videoPlaylist })
return customHtml
}
const twitterCard = 'summary'
const schemaType = 'ProfilePage'
- customHtml = ClientHtml.addTags(customHtml, {
+ customHtml = await ClientHtml.addTags(customHtml, {
url,
originUrl,
escapedTitle: escapeHTML(title),
twitterCard,
schemaType,
disallowIndexation: !entity.Actor.isOwned()
- })
+ }, {})
return customHtml
}
return metaTags
}
- private static generateSchemaTags (tags: Tags) {
+ private static async generateSchemaTags (tags: Tags, context: HookContext) {
const schema = {
'@context': 'http://schema.org',
'@type': tags.schemaType,
schema['contentUrl'] = tags.url
}
- return schema
+ return Hooks.wrapObject(schema, 'filter:html.client.json-ld.result', context)
}
- private static addTags (htmlStringPage: string, tagsValues: Tags) {
+ private static async addTags (htmlStringPage: string, tagsValues: Tags, context: HookContext) {
const openGraphMetaTags = this.generateOpenGraphMetaTags(tagsValues)
const standardMetaTags = this.generateStandardMetaTags(tagsValues)
const twitterCardMetaTags = this.generateTwitterCardMetaTags(tagsValues)
- const schemaTags = this.generateSchemaTags(tagsValues)
+ const schemaTags = await this.generateSchemaTags(tagsValues, context)
const { url, escapedTitle, embed, originUrl, disallowIndexation } = tagsValues
}
})
+ // ---------------------------------------------------------------------------
+
registerHook({
target: 'filter:html.embed.video.allowed.result',
handler: (result, params) => {
}
})
+ // ---------------------------------------------------------------------------
+
+ registerHook({
+ target: 'filter:html.client.json-ld.result',
+ handler: (jsonld, context) => {
+ if (!context || !context.video) return jsonld
+
+ return Object.assign(jsonld, { recordedAt: 'http://example.com/recordedAt' })
+ }
+ })
+
+ // ---------------------------------------------------------------------------
+
registerHook({
target: 'filter:api.server.stats.get.result',
handler: (result) => {
})
})
+ describe('Client HTML filters', function () {
+ let videoUUID: string
+
+ before(async function () {
+ this.timeout(60000)
+
+ const { uuid } = await servers[0].videos.quickUpload({ name: 'html video' })
+ videoUUID = uuid
+ })
+
+ it('Should run filter:html.client.json-ld.result', async function () {
+ const res = await makeGetRequest({ url: servers[0].url, path: '/w/' + videoUUID, expectedStatus: HttpStatusCode.OK_200 })
+ expect(res.text).to.contain('"recordedAt":"http://example.com/recordedAt"')
+ })
+
+ it('Should not run filter:html.client.json-ld.result with an account', async function () {
+ const res = await makeGetRequest({ url: servers[0].url, path: '/a/root', expectedStatus: HttpStatusCode.OK_200 })
+ expect(res.text).not.to.contain('"recordedAt":"http://example.com/recordedAt"')
+ })
+ })
+
describe('Search filters', function () {
before(async function () {