Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server: use account/channel avatar in RSS feeds #5325

Merged
merged 2 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 48 additions & 30 deletions server/controllers/feeds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
})
Expand Down Expand Up @@ -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
})
Expand Down Expand Up @@ -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
})
Expand Down Expand Up @@ -229,19 +210,20 @@ 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,
description: mdToOneLinePlainText(description),
// 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.`,
Expand Down Expand Up @@ -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 }
}
10 changes: 10 additions & 0 deletions server/tests/feeds/feeds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
createSingleServer,
doubleFollow,
makeGetRequest,
makeRawRequest,
PeerTubeServer,
setAccessTokensToServers,
setDefaultChannelAvatar,
Expand Down Expand Up @@ -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 () {
Expand Down