]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
server: use account/channel avatar in RSS feeds (#5325)
authorAlberto Mardegan <mardy@users.sourceforge.net>
Tue, 11 Oct 2022 15:02:47 +0000 (18:02 +0300)
committerGitHub <noreply@github.com>
Tue, 11 Oct 2022 15:02:47 +0000 (17:02 +0200)
* server: use account/channel avatar in RSS feeds

Fixes: #5320
* Styling

Co-authored-by: Chocobozzz <me@florianbigard.com>
server/controllers/feeds.ts
server/tests/feeds/feeds.ts

index 241715fb90858d4c8bfff900e0fc9669ec92ceb0..772fe734deda1ebcfb8b7639ab45cf23695010ba 100644 (file)
@@ -4,7 +4,8 @@ import { Feed } from '@peertube/feed'
 import { mdToOneLinePlainText, toSafeHtml } from '@server/helpers/markdown'
 import { getServerActor } from '@server/models/application/application'
 import { getCategoryLabel } from '@server/models/video/formatter/video-format-utils'
-import { VideoInclude } from '@shared/models'
+import { MAccountDefault, MChannelBannerAccountDefault, MVideoFullLight } from '@server/types/models'
+import { ActorImageType, VideoInclude } from '@shared/models'
 import { buildNSFWFilter } from '../helpers/express-utils'
 import { CONFIG } from '../initializers/config'
 import { MIMETYPES, PREVIEWS_SIZE, ROUTE_CACHE_LIFETIME, WEBSERVER } from '../initializers/constants'
@@ -82,22 +83,12 @@ async function generateVideoCommentsFeed (req: express.Request, res: express.Res
     videoChannelId: videoChannel ? videoChannel.id : undefined
   })
 
-  let name: string
-  let description: string
+  const { name, description, imageUrl } = buildFeedMetadata({ video, account, videoChannel })
 
-  if (videoChannel) {
-    name = videoChannel.getDisplayName()
-    description = videoChannel.description
-  } else if (account) {
-    name = account.getDisplayName()
-    description = account.description
-  } else {
-    name = video ? video.name : CONFIG.INSTANCE.NAME
-    description = video ? video.description : CONFIG.INSTANCE.DESCRIPTION
-  }
   const feed = initFeed({
     name,
     description,
+    imageUrl,
     resourceType: 'video-comments',
     queryString: new URL(WEBSERVER.URL + req.originalUrl).search
   })
@@ -137,23 +128,12 @@ async function generateVideoFeed (req: express.Request, res: express.Response) {
   const videoChannel = res.locals.videoChannel
   const nsfw = buildNSFWFilter(res, req.query.nsfw)
 
-  let name: string
-  let description: string
-
-  if (videoChannel) {
-    name = videoChannel.getDisplayName()
-    description = videoChannel.description
-  } else if (account) {
-    name = account.getDisplayName()
-    description = account.description
-  } else {
-    name = CONFIG.INSTANCE.NAME
-    description = CONFIG.INSTANCE.DESCRIPTION
-  }
+  const { name, description, imageUrl } = buildFeedMetadata({ videoChannel, account })
 
   const feed = initFeed({
     name,
     description,
+    imageUrl,
     resourceType: 'videos',
     queryString: new URL(WEBSERVER.URL + req.url).search
   })
@@ -190,12 +170,13 @@ async function generateVideoFeedForSubscriptions (req: express.Request, res: exp
   const start = 0
   const account = res.locals.account
   const nsfw = buildNSFWFilter(res, req.query.nsfw)
-  const name = account.getDisplayName()
-  const description = account.description
+
+  const { name, description, imageUrl } = buildFeedMetadata({ account })
 
   const feed = initFeed({
     name,
     description,
+    imageUrl,
     resourceType: 'videos',
     queryString: new URL(WEBSERVER.URL + req.url).search
   })
@@ -229,11 +210,12 @@ async function generateVideoFeedForSubscriptions (req: express.Request, res: exp
 function initFeed (parameters: {
   name: string
   description: string
+  imageUrl: string
   resourceType?: 'videos' | 'video-comments'
   queryString?: string
 }) {
   const webserverUrl = WEBSERVER.URL
-  const { name, description, resourceType, queryString } = parameters
+  const { name, description, resourceType, queryString, imageUrl } = parameters
 
   return new Feed({
     title: name,
@@ -241,7 +223,7 @@ function initFeed (parameters: {
     // updated: TODO: somehowGetLatestUpdate, // optional, default = today
     id: webserverUrl,
     link: webserverUrl,
-    image: webserverUrl + '/client/assets/images/icons/icon-96x96.png',
+    image: imageUrl,
     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.`,
@@ -369,3 +351,39 @@ function sendFeed (feed: Feed, req: express.Request, res: express.Response) {
 
   return res.send(feed.rss2()).end()
 }
+
+function buildFeedMetadata (options: {
+  videoChannel?: MChannelBannerAccountDefault
+  account?: MAccountDefault
+  video?: MVideoFullLight
+}) {
+  const { video, videoChannel, account } = options
+
+  let imageUrl = WEBSERVER.URL + '/client/assets/images/icons/icon-96x96.png'
+  let name: string
+  let description: string
+
+  if (videoChannel) {
+    name = videoChannel.getDisplayName()
+    description = videoChannel.description
+
+    if (videoChannel.Actor.hasImage(ActorImageType.AVATAR)) {
+      imageUrl = WEBSERVER.URL + videoChannel.Actor.Avatars[0].getStaticPath()
+    }
+  } else if (account) {
+    name = account.getDisplayName()
+    description = account.description
+
+    if (account.Actor.hasImage(ActorImageType.AVATAR)) {
+      imageUrl = WEBSERVER.URL + account.Actor.Avatars[0].getStaticPath()
+    }
+  } else if (video) {
+    name = video.name
+    description = video.description
+  } else {
+    name = CONFIG.INSTANCE.NAME
+    description = CONFIG.INSTANCE.DESCRIPTION
+  }
+
+  return { name, description, imageUrl }
+}
index 1d3c03d67fb1d37a4ec6bdffffca84e9af5b7b74..0ddb641e6f96d04b883a2343d98651e67b10671b 100644 (file)
@@ -9,6 +9,7 @@ import {
   createSingleServer,
   doubleFollow,
   makeGetRequest,
+  makeRawRequest,
   PeerTubeServer,
   setAccessTokensToServers,
   setDefaultChannelAvatar,
@@ -306,6 +307,15 @@ describe('Test syndication feeds', () => {
 
       await stopFfmpeg(ffmpeg)
     })
+
+    it('Should have the channel avatar as feed icon', async function () {
+      const json = await servers[0].feed.getJSON({ feed: 'videos', query: { videoChannelId: rootChannelId }, ignoreCache: true })
+
+      const jsonObj = JSON.parse(json)
+      const imageUrl = jsonObj.icon
+      expect(imageUrl).to.include('/lazy-static/avatars/')
+      await makeRawRequest(imageUrl)
+    })
   })
 
   describe('Video comments feed', function () {