X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fcontrollers%2Ffeeds.ts;h=865f5c2a129006c7ca7422bbb499ac2af0a8226f;hb=c756bae079e02873f6433582ca14a092fec0db27;hp=6e9f7e60cfe9bd3c7b0f4aa18ce8434fdf8883f4;hpb=afff310e50f2fa8419bb4242470cbde46ab54463;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/controllers/feeds.ts b/server/controllers/feeds.ts index 6e9f7e60c..865f5c2a1 100644 --- a/server/controllers/feeds.ts +++ b/server/controllers/feeds.ts @@ -1,8 +1,9 @@ import * as express from 'express' import * as Feed from 'pfeed' +import { VideoFilter } from '../../shared/models/videos/video-query.type' import { buildNSFWFilter } from '../helpers/express-utils' import { CONFIG } from '../initializers/config' -import { FEEDS, ROUTE_CACHE_LIFETIME, THUMBNAILS_SIZE, WEBSERVER } from '../initializers/constants' +import { FEEDS, PREVIEWS_SIZE, ROUTE_CACHE_LIFETIME, WEBSERVER } from '../initializers/constants' import { asyncMiddleware, commonVideosFiltersValidator, @@ -12,13 +13,11 @@ import { videoCommentsFeedsValidator, videoFeedsValidator, videosSortValidator, - videoSubscriptonFeedsValidator + videoSubscriptionFeedsValidator } from '../middlewares' import { cacheRoute } from '../middlewares/cache' import { VideoModel } from '../models/video/video' import { VideoCommentModel } from '../models/video/video-comment' -import { VideoFilter } from '../../shared/models/videos/video-query.type' -import { logger } from '../helpers/logger' const feedsRouter = express.Router() @@ -47,10 +46,24 @@ feedsRouter.get('/feeds/videos.:format', })(ROUTE_CACHE_LIFETIME.FEEDS)), commonVideosFiltersValidator, asyncMiddleware(videoFeedsValidator), - asyncMiddleware(videoSubscriptonFeedsValidator), asyncMiddleware(generateVideoFeed) ) +feedsRouter.get('/feeds/subscriptions.:format', + videosSortValidator, + setDefaultVideosSort, + feedsFormatValidator, + setFeedFormatContentType, + asyncMiddleware(cacheRoute({ + headerBlacklist: [ + 'Content-Type' + ] + })(ROUTE_CACHE_LIFETIME.FEEDS)), + commonVideosFiltersValidator, + asyncMiddleware(videoSubscriptionFeedsValidator), + asyncMiddleware(generateVideoFeedForSubscriptions) +) + // --------------------------------------------------------------------------- export { @@ -61,7 +74,6 @@ export { async function generateVideoCommentsFeed (req: express.Request, res: express.Response) { const start = 0 - const video = res.locals.videoAll const account = res.locals.account const videoChannel = res.locals.videoChannel @@ -125,10 +137,8 @@ async function generateVideoCommentsFeed (req: express.Request, res: express.Res async function generateVideoFeed (req: express.Request, res: express.Response) { const start = 0 - const account = res.locals.account const videoChannel = res.locals.videoChannel - const token = req.query.token const nsfw = buildNSFWFilter(res, req.query.nsfw) let name: string @@ -152,23 +162,12 @@ async function generateVideoFeed (req: express.Request, res: express.Response) { queryString: new URL(WEBSERVER.URL + req.url).search }) - /** - * We have two ways to query video results: - * - one with account and token -> get subscription videos - * - one with either account, channel, or nothing: just videos with these filters - */ - const options = token && token !== '' && res.locals.user - ? { - followerActorId: res.locals.user.Account.Actor.id, - user: res.locals.user, - includeLocalVideos: false - } - : { - accountId: account ? account.id : null, - videoChannelId: videoChannel ? videoChannel.id : null - } + const options = { + accountId: account ? account.id : null, + videoChannelId: videoChannel ? videoChannel.id : null + } - const resultList = await VideoModel.listForApi({ + const { data } = await VideoModel.listForApi({ start, count: FEEDS.COUNT, sort: req.query.sort, @@ -176,14 +175,90 @@ async function generateVideoFeed (req: express.Request, res: express.Response) { nsfw, filter: req.query.filter as VideoFilter, withFiles: true, + countVideos: false, ...options }) + addVideosToFeed(feed, data) + + // Now the feed generation is done, let's send it! + return sendFeed(feed, req, res) +} + +async function generateVideoFeedForSubscriptions (req: express.Request, res: express.Response) { + const start = 0 + const account = res.locals.account + const nsfw = buildNSFWFilter(res, req.query.nsfw) + const name = account.getDisplayName() + const description = account.description + + const feed = initFeed({ + name, + description, + resourceType: 'videos', + queryString: new URL(WEBSERVER.URL + req.url).search + }) + + const { data } = await VideoModel.listForApi({ + start, + count: FEEDS.COUNT, + sort: req.query.sort, + includeLocalVideos: false, + nsfw, + filter: req.query.filter as VideoFilter, + + withFiles: true, + countVideos: false, + + followerActorId: res.locals.user.Account.Actor.id, + user: res.locals.user + }) + + addVideosToFeed(feed, data) + + // Now the feed generation is done, let's send it! + return sendFeed(feed, req, res) +} + +function initFeed (parameters: { + name: string + description: string + resourceType?: 'videos' | 'video-comments' + queryString?: string +}) { + const webserverUrl = WEBSERVER.URL + const { name, description, resourceType, queryString } = parameters + + return new Feed({ + title: name, + description, + // updated: TODO: somehowGetLatestUpdate, // optional, default = today + id: webserverUrl, + link: webserverUrl, + image: webserverUrl + '/client/assets/images/icons/icon-96x96.png', + favicon: webserverUrl + '/client/assets/images/favicon.png', + copyright: `All rights reserved, unless otherwise specified in the terms specified at ${webserverUrl}/about` + + ` and potential licenses granted by each content's rightholder.`, + generator: `Toraifōsu`, // ^.~ + feedLinks: { + json: `${webserverUrl}/feeds/${resourceType}.json${queryString}`, + atom: `${webserverUrl}/feeds/${resourceType}.atom${queryString}`, + rss: `${webserverUrl}/feeds/${resourceType}.xml${queryString}` + }, + author: { + name: 'Instance admin of ' + CONFIG.INSTANCE.NAME, + email: CONFIG.ADMIN.EMAIL, + link: `${webserverUrl}/about` + } + }) +} + +function addVideosToFeed (feed, videos: VideoModel[]) { /** * Adding video items to the feed object, one at a time */ - resultList.data.forEach(video => { - const formattedVideoFiles = video.getFormattedVideoFilesJSON() + for (const video of videos) { + const formattedVideoFiles = video.getFormattedVideoFilesJSON(false) const torrents = formattedVideoFiles.map(videoFile => ({ title: video.name, @@ -218,7 +293,7 @@ async function generateVideoFeed (req: express.Request, res: express.Response) { feed.addItem({ title: video.name, id: video.url, - link: WEBSERVER.URL + '/videos/watch/' + video.uuid, + link: WEBSERVER.URL + '/w/' + video.uuid, description: video.getTruncatedDescription(), content: video.description, author: [ @@ -246,49 +321,13 @@ async function generateVideoFeed (req: express.Request, res: express.Response) { }, thumbnail: [ { - url: WEBSERVER.URL + video.getMiniatureStaticPath(), - height: THUMBNAILS_SIZE.height, - width: THUMBNAILS_SIZE.width + url: WEBSERVER.URL + video.getPreviewStaticPath(), + height: PREVIEWS_SIZE.height, + width: PREVIEWS_SIZE.width } ] }) - }) - - // Now the feed generation is done, let's send it! - return sendFeed(feed, req, res) -} - -function initFeed (parameters: { - name: string - description: string - resourceType?: 'videos' | 'video-comments' - queryString?: string -}) { - const webserverUrl = WEBSERVER.URL - const { name, description, resourceType, queryString } = parameters - - return new Feed({ - title: name, - description, - // updated: TODO: somehowGetLatestUpdate, // optional, default = today - id: webserverUrl, - link: webserverUrl, - image: webserverUrl + '/client/assets/images/icons/icon-96x96.png', - favicon: webserverUrl + '/client/assets/images/favicon.png', - copyright: `All rights reserved, unless otherwise specified in the terms specified at ${webserverUrl}/about` + - ` and potential licenses granted by each content's rightholder.`, - generator: `Toraifōsu`, // ^.~ - feedLinks: { - json: `${webserverUrl}/feeds/${resourceType}.json${queryString}`, - atom: `${webserverUrl}/feeds/${resourceType}.atom${queryString}`, - rss: `${webserverUrl}/feeds/${resourceType}.xml${queryString}` - }, - author: { - name: 'Instance admin of ' + CONFIG.INSTANCE.NAME, - email: CONFIG.ADMIN.EMAIL, - link: `${webserverUrl}/about` - } - }) + } } function sendFeed (feed, req: express.Request, res: express.Response) {