X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fcontrollers%2Fservices.ts;h=7c7ca1ff3668d8446a993f24dab35c041f289afa;hb=bd09dfaf8dcb0ca4cd5dac9f13e3117486f3bcce;hp=99a33a716a158cb70060dfada8c76e4bdc96a1b0;hpb=72c7248b6fdcdb2175e726ff51b42e7555f2bd84;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/controllers/services.ts b/server/controllers/services.ts index 99a33a716..7c7ca1ff3 100644 --- a/server/controllers/services.ts +++ b/server/controllers/services.ts @@ -1,12 +1,21 @@ -import * as express from 'express' - -import { CONFIG, PREVIEWS_SIZE, EMBED_SIZE } from '../initializers' -import { oembedValidator } from '../middlewares' -import { VideoInstance } from '../models' +import express from 'express' +import { MChannelSummary } from '@server/types/models' +import { escapeHTML } from '@shared/core-utils/renderer' +import { EMBED_SIZE, PREVIEWS_SIZE, THUMBNAILS_SIZE, WEBSERVER } from '../initializers/constants' +import { asyncMiddleware, oembedValidator } from '../middlewares' +import { accountNameWithHostGetValidator } from '../middlewares/validators' +import { forceNumber } from '@shared/core-utils' const servicesRouter = express.Router() -servicesRouter.use('/oembed', oembedValidator, generateOEmbed) +servicesRouter.use('/oembed', + asyncMiddleware(oembedValidator), + generateOEmbed +) +servicesRouter.use('/redirect/accounts/:accountName', + asyncMiddleware(accountNameWithHostGetValidator), + redirectToAccountUrl +) // --------------------------------------------------------------------------- @@ -16,29 +25,116 @@ export { // --------------------------------------------------------------------------- -function generateOEmbed (req: express.Request, res: express.Response, next: express.NextFunction) { - const video = res.locals.video as VideoInstance - const webserverUrl = CONFIG.WEBSERVER.URL - const maxHeight = parseInt(req.query.maxheight, 10) - const maxWidth = parseInt(req.query.maxwidth, 10) +function generateOEmbed (req: express.Request, res: express.Response) { + if (res.locals.videoAll) return generateVideoOEmbed(req, res) + + return generatePlaylistOEmbed(req, res) +} + +function generatePlaylistOEmbed (req: express.Request, res: express.Response) { + const playlist = res.locals.videoPlaylistSummary + + const json = buildOEmbed({ + channel: playlist.VideoChannel, + title: playlist.name, + embedPath: playlist.getEmbedStaticPath() + buildPlayerURLQuery(req.query.url), + previewPath: playlist.getThumbnailStaticPath(), + previewSize: THUMBNAILS_SIZE, + req + }) + + return res.json(json) +} + +function generateVideoOEmbed (req: express.Request, res: express.Response) { + const video = res.locals.videoAll + + const json = buildOEmbed({ + channel: video.VideoChannel, + title: video.name, + embedPath: video.getEmbedStaticPath() + buildPlayerURLQuery(req.query.url), + previewPath: video.getPreviewStaticPath(), + previewSize: PREVIEWS_SIZE, + req + }) + + return res.json(json) +} + +function buildPlayerURLQuery (inputQueryUrl: string) { + const allowedParameters = new Set([ + 'start', + 'stop', + 'loop', + 'autoplay', + 'muted', + 'controls', + 'controlBar', + 'title', + 'api', + 'warningTitle', + 'peertubeLink', + 'p2p', + 'subtitle', + 'bigPlayBackgroundColor', + 'mode', + 'foregroundColor' + ]) + + const params = new URLSearchParams() + + new URL(inputQueryUrl).searchParams.forEach((v, k) => { + if (allowedParameters.has(k)) { + params.append(k, v) + } + }) + + const stringQuery = params.toString() + if (!stringQuery) return '' + + return '?' + stringQuery +} + +function buildOEmbed (options: { + req: express.Request + title: string + channel: MChannelSummary + previewPath: string | null + embedPath: string + previewSize: { + height: number + width: number + } +}) { + const { req, previewSize, previewPath, title, channel, embedPath } = options + + const webserverUrl = WEBSERVER.URL + const maxHeight = forceNumber(req.query.maxheight) + const maxWidth = forceNumber(req.query.maxwidth) + + const embedUrl = webserverUrl + embedPath + const embedTitle = escapeHTML(title) + + let thumbnailUrl = previewPath + ? webserverUrl + previewPath + : undefined - const embedUrl = webserverUrl + video.getEmbedPath() - let thumbnailUrl = webserverUrl + video.getPreviewPath() let embedWidth = EMBED_SIZE.width - let embedHeight = EMBED_SIZE.height + if (maxWidth < embedWidth) embedWidth = maxWidth + let embedHeight = EMBED_SIZE.height if (maxHeight < embedHeight) embedHeight = maxHeight - if (maxWidth < embedWidth) embedWidth = maxWidth // Our thumbnail is too big for the consumer if ( - (maxHeight !== undefined && maxHeight < PREVIEWS_SIZE.height) || - (maxWidth !== undefined && maxWidth < PREVIEWS_SIZE.width) + (maxHeight !== undefined && maxHeight < previewSize.height) || + (maxWidth !== undefined && maxWidth < previewSize.width) ) { thumbnailUrl = undefined } - const html = `` + const html = `` const json: any = { type: 'video', @@ -46,17 +142,22 @@ function generateOEmbed (req: express.Request, res: express.Response, next: expr html, width: embedWidth, height: embedHeight, - title: video.name, - author_name: video.VideoChannel.Author.name, + title, + author_name: channel.name, + author_url: channel.Actor.url, provider_name: 'PeerTube', provider_url: webserverUrl } if (thumbnailUrl !== undefined) { json.thumbnail_url = thumbnailUrl - json.thumbnail_width = PREVIEWS_SIZE.width - json.thumbnail_height = PREVIEWS_SIZE.height + json.thumbnail_width = previewSize.width + json.thumbnail_height = previewSize.height } - return res.json(json) + return json +} + +function redirectToAccountUrl (req: express.Request, res: express.Response, next: express.NextFunction) { + return res.redirect(res.locals.account.Actor.url) }