aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlberto Mardegan <mardy@users.sourceforge.net>2022-10-11 18:02:47 +0300
committerGitHub <noreply@github.com>2022-10-11 17:02:47 +0200
commit5e1bd8690b740e10aa3a959eb3ecaf7a0aae87cf (patch)
tree156a0cf2f3aafe34ef1af3fdb6b5b21476943ff0
parentbbae45c32ea41ba4926b291fac5f594c94d5aa9d (diff)
downloadPeerTube-5e1bd8690b740e10aa3a959eb3ecaf7a0aae87cf.tar.gz
PeerTube-5e1bd8690b740e10aa3a959eb3ecaf7a0aae87cf.tar.zst
PeerTube-5e1bd8690b740e10aa3a959eb3ecaf7a0aae87cf.zip
server: use account/channel avatar in RSS feeds (#5325)
* server: use account/channel avatar in RSS feeds Fixes: #5320 * Styling Co-authored-by: Chocobozzz <me@florianbigard.com>
-rw-r--r--server/controllers/feeds.ts78
-rw-r--r--server/tests/feeds/feeds.ts10
2 files changed, 58 insertions, 30 deletions
diff --git a/server/controllers/feeds.ts b/server/controllers/feeds.ts
index 241715fb9..772fe734d 100644
--- a/server/controllers/feeds.ts
+++ b/server/controllers/feeds.ts
@@ -4,7 +4,8 @@ import { Feed } from '@peertube/feed'
4import { mdToOneLinePlainText, toSafeHtml } from '@server/helpers/markdown' 4import { mdToOneLinePlainText, toSafeHtml } from '@server/helpers/markdown'
5import { getServerActor } from '@server/models/application/application' 5import { getServerActor } from '@server/models/application/application'
6import { getCategoryLabel } from '@server/models/video/formatter/video-format-utils' 6import { getCategoryLabel } from '@server/models/video/formatter/video-format-utils'
7import { VideoInclude } from '@shared/models' 7import { MAccountDefault, MChannelBannerAccountDefault, MVideoFullLight } from '@server/types/models'
8import { ActorImageType, VideoInclude } from '@shared/models'
8import { buildNSFWFilter } from '../helpers/express-utils' 9import { buildNSFWFilter } from '../helpers/express-utils'
9import { CONFIG } from '../initializers/config' 10import { CONFIG } from '../initializers/config'
10import { MIMETYPES, PREVIEWS_SIZE, ROUTE_CACHE_LIFETIME, WEBSERVER } from '../initializers/constants' 11import { MIMETYPES, PREVIEWS_SIZE, ROUTE_CACHE_LIFETIME, WEBSERVER } from '../initializers/constants'
@@ -82,22 +83,12 @@ async function generateVideoCommentsFeed (req: express.Request, res: express.Res
82 videoChannelId: videoChannel ? videoChannel.id : undefined 83 videoChannelId: videoChannel ? videoChannel.id : undefined
83 }) 84 })
84 85
85 let name: string 86 const { name, description, imageUrl } = buildFeedMetadata({ video, account, videoChannel })
86 let description: string
87 87
88 if (videoChannel) {
89 name = videoChannel.getDisplayName()
90 description = videoChannel.description
91 } else if (account) {
92 name = account.getDisplayName()
93 description = account.description
94 } else {
95 name = video ? video.name : CONFIG.INSTANCE.NAME
96 description = video ? video.description : CONFIG.INSTANCE.DESCRIPTION
97 }
98 const feed = initFeed({ 88 const feed = initFeed({
99 name, 89 name,
100 description, 90 description,
91 imageUrl,
101 resourceType: 'video-comments', 92 resourceType: 'video-comments',
102 queryString: new URL(WEBSERVER.URL + req.originalUrl).search 93 queryString: new URL(WEBSERVER.URL + req.originalUrl).search
103 }) 94 })
@@ -137,23 +128,12 @@ async function generateVideoFeed (req: express.Request, res: express.Response) {
137 const videoChannel = res.locals.videoChannel 128 const videoChannel = res.locals.videoChannel
138 const nsfw = buildNSFWFilter(res, req.query.nsfw) 129 const nsfw = buildNSFWFilter(res, req.query.nsfw)
139 130
140 let name: string 131 const { name, description, imageUrl } = buildFeedMetadata({ videoChannel, account })
141 let description: string
142
143 if (videoChannel) {
144 name = videoChannel.getDisplayName()
145 description = videoChannel.description
146 } else if (account) {
147 name = account.getDisplayName()
148 description = account.description
149 } else {
150 name = CONFIG.INSTANCE.NAME
151 description = CONFIG.INSTANCE.DESCRIPTION
152 }
153 132
154 const feed = initFeed({ 133 const feed = initFeed({
155 name, 134 name,
156 description, 135 description,
136 imageUrl,
157 resourceType: 'videos', 137 resourceType: 'videos',
158 queryString: new URL(WEBSERVER.URL + req.url).search 138 queryString: new URL(WEBSERVER.URL + req.url).search
159 }) 139 })
@@ -190,12 +170,13 @@ async function generateVideoFeedForSubscriptions (req: express.Request, res: exp
190 const start = 0 170 const start = 0
191 const account = res.locals.account 171 const account = res.locals.account
192 const nsfw = buildNSFWFilter(res, req.query.nsfw) 172 const nsfw = buildNSFWFilter(res, req.query.nsfw)
193 const name = account.getDisplayName() 173
194 const description = account.description 174 const { name, description, imageUrl } = buildFeedMetadata({ account })
195 175
196 const feed = initFeed({ 176 const feed = initFeed({
197 name, 177 name,
198 description, 178 description,
179 imageUrl,
199 resourceType: 'videos', 180 resourceType: 'videos',
200 queryString: new URL(WEBSERVER.URL + req.url).search 181 queryString: new URL(WEBSERVER.URL + req.url).search
201 }) 182 })
@@ -229,11 +210,12 @@ async function generateVideoFeedForSubscriptions (req: express.Request, res: exp
229function initFeed (parameters: { 210function initFeed (parameters: {
230 name: string 211 name: string
231 description: string 212 description: string
213 imageUrl: string
232 resourceType?: 'videos' | 'video-comments' 214 resourceType?: 'videos' | 'video-comments'
233 queryString?: string 215 queryString?: string
234}) { 216}) {
235 const webserverUrl = WEBSERVER.URL 217 const webserverUrl = WEBSERVER.URL
236 const { name, description, resourceType, queryString } = parameters 218 const { name, description, resourceType, queryString, imageUrl } = parameters
237 219
238 return new Feed({ 220 return new Feed({
239 title: name, 221 title: name,
@@ -241,7 +223,7 @@ function initFeed (parameters: {
241 // updated: TODO: somehowGetLatestUpdate, // optional, default = today 223 // updated: TODO: somehowGetLatestUpdate, // optional, default = today
242 id: webserverUrl, 224 id: webserverUrl,
243 link: webserverUrl, 225 link: webserverUrl,
244 image: webserverUrl + '/client/assets/images/icons/icon-96x96.png', 226 image: imageUrl,
245 favicon: webserverUrl + '/client/assets/images/favicon.png', 227 favicon: webserverUrl + '/client/assets/images/favicon.png',
246 copyright: `All rights reserved, unless otherwise specified in the terms specified at ${webserverUrl}/about` + 228 copyright: `All rights reserved, unless otherwise specified in the terms specified at ${webserverUrl}/about` +
247 ` and potential licenses granted by each content's rightholder.`, 229 ` and potential licenses granted by each content's rightholder.`,
@@ -369,3 +351,39 @@ function sendFeed (feed: Feed, req: express.Request, res: express.Response) {
369 351
370 return res.send(feed.rss2()).end() 352 return res.send(feed.rss2()).end()
371} 353}
354
355function buildFeedMetadata (options: {
356 videoChannel?: MChannelBannerAccountDefault
357 account?: MAccountDefault
358 video?: MVideoFullLight
359}) {
360 const { video, videoChannel, account } = options
361
362 let imageUrl = WEBSERVER.URL + '/client/assets/images/icons/icon-96x96.png'
363 let name: string
364 let description: string
365
366 if (videoChannel) {
367 name = videoChannel.getDisplayName()
368 description = videoChannel.description
369
370 if (videoChannel.Actor.hasImage(ActorImageType.AVATAR)) {
371 imageUrl = WEBSERVER.URL + videoChannel.Actor.Avatars[0].getStaticPath()
372 }
373 } else if (account) {
374 name = account.getDisplayName()
375 description = account.description
376
377 if (account.Actor.hasImage(ActorImageType.AVATAR)) {
378 imageUrl = WEBSERVER.URL + account.Actor.Avatars[0].getStaticPath()
379 }
380 } else if (video) {
381 name = video.name
382 description = video.description
383 } else {
384 name = CONFIG.INSTANCE.NAME
385 description = CONFIG.INSTANCE.DESCRIPTION
386 }
387
388 return { name, description, imageUrl }
389}
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts
index 1d3c03d67..0ddb641e6 100644
--- a/server/tests/feeds/feeds.ts
+++ b/server/tests/feeds/feeds.ts
@@ -9,6 +9,7 @@ import {
9 createSingleServer, 9 createSingleServer,
10 doubleFollow, 10 doubleFollow,
11 makeGetRequest, 11 makeGetRequest,
12 makeRawRequest,
12 PeerTubeServer, 13 PeerTubeServer,
13 setAccessTokensToServers, 14 setAccessTokensToServers,
14 setDefaultChannelAvatar, 15 setDefaultChannelAvatar,
@@ -306,6 +307,15 @@ describe('Test syndication feeds', () => {
306 307
307 await stopFfmpeg(ffmpeg) 308 await stopFfmpeg(ffmpeg)
308 }) 309 })
310
311 it('Should have the channel avatar as feed icon', async function () {
312 const json = await servers[0].feed.getJSON({ feed: 'videos', query: { videoChannelId: rootChannelId }, ignoreCache: true })
313
314 const jsonObj = JSON.parse(json)
315 const imageUrl = jsonObj.icon
316 expect(imageUrl).to.include('/lazy-static/avatars/')
317 await makeRawRequest(imageUrl)
318 })
309 }) 319 })
310 320
311 describe('Video comments feed', function () { 321 describe('Video comments feed', function () {