Generate 600x600 and 1500x1500 avatars

pull/6266/head
Chocobozzz 2024-02-26 14:33:22 +01:00
parent fb2dc40858
commit 109e93c139
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
19 changed files with 83 additions and 33 deletions

View File

@ -21,7 +21,7 @@ export class ActorAvatarComponent implements OnInit, OnChanges {
@Input() previewImage: string
@Input({ transform: numberAttribute }) size: number
@Input({ transform: numberAttribute }) size = 120
// Use an external link
@Input() href: string

View File

@ -30,6 +30,16 @@ export class ConfigCommand extends AbstractCommand {
}
}
static getDisableRatesLimitOverrideConfig () {
return {
rates_limit: {
api: {
max: 5000
}
}
}
}
// ---------------------------------------------------------------------------
enableSignup (requiresApproval: boolean, limit = -1) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -11,7 +11,7 @@ import {
PeerTubeServer,
setAccessTokensToServers
} from '@peertube/peertube-server-commands'
import { testFileExistsOrNot, testImage, testImageSize } from '@tests/shared/checks.js'
import { testFileExistsOrNot, testImage, testAvatarSize } from '@tests/shared/checks.js'
import { basename } from 'path'
function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
@ -739,7 +739,7 @@ describe('Test config', function () {
const { avatars } = await checkAndGetServerImages()
for (const avatar of avatars) {
await testImageSize(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, extension)
await testAvatarSize({ url: server.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` })
}
avatarPath = avatars[0].path

View File

@ -1,5 +1,5 @@
import './oauth.js'
import './registrations`.js'
import './registrations.js'
import './two-factor.js'
import './user-export.js'
import './user-import.js'

View File

@ -435,7 +435,7 @@ function runTest (withObjectStorage: boolean) {
expect(secondaryChannel.description).to.equal('noah description')
expect(secondaryChannel.support).to.equal('noah support')
expect(secondaryChannel.avatars).to.have.lengthOf(2)
expect(secondaryChannel.avatars).to.have.lengthOf(4)
expect(secondaryChannel.banners).to.have.lengthOf(1)
const urls = [ ...secondaryChannel.avatars, ...secondaryChannel.banners ].map(a => a.url)
@ -627,7 +627,7 @@ function runTest (withObjectStorage: boolean) {
// PeerTube format
{
const json = await parseZIPJSONFile<AccountExportJSON>(zip, 'peertube/account.json')
expect(json.avatars).to.have.lengthOf(2)
expect(json.avatars).to.have.lengthOf(4)
for (const avatar of json.avatars) {
await makeRawRequest({ url: avatar.url, expectedStatus: HttpStatusCode.OK_200 })

View File

@ -21,7 +21,7 @@ import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils
import { writeFile } from 'fs/promises'
import { join } from 'path'
import { expect } from 'chai'
import { testImage, testImageSize } from '@tests/shared/checks.js'
import { testImage, testAvatarSize } from '@tests/shared/checks.js'
import { completeVideoCheck } from '@tests/shared/videos.js'
import { completeCheckHlsPlaylist } from '@tests/shared/streaming-playlists.js'
@ -84,7 +84,7 @@ function runTest (withObjectStorage: boolean) {
}
// Add avatars
await server.users.updateMyAvatar({ token: noahToken, fixture: 'avatar.gif' })
await server.users.updateMyAvatar({ token: noahToken, fixture: 'avatar.png' })
// Add password protected video
await server.videos.upload({
@ -168,9 +168,10 @@ function runTest (withObjectStorage: boolean) {
expect(me.account.displayName).to.equal('noah')
expect(me.username).to.equal('noah_remote')
expect(me.account.description).to.equal('super noah description')
expect(me.account.avatars).to.have.lengthOf(4)
for (const avatar of me.account.avatars) {
await testImageSize(remoteServer.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, '.gif')
await testAvatarSize({ url: remoteServer.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` })
}
})
@ -482,7 +483,7 @@ function runTest (withObjectStorage: boolean) {
// My avatars
{
const me = await remoteServer.users.getMyInfo({ token: remoteNoahToken })
expect(me.account.avatars).to.have.lengthOf(2)
expect(me.account.avatars).to.have.lengthOf(4)
}
// Channels

View File

@ -1,9 +1,13 @@
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import { expect } from 'chai'
import { testImageSize } from '@tests/shared/checks.js'
import { testAvatarSize } from '@tests/shared/checks.js'
import { AbuseState, HttpStatusCode, UserAdminFlag, UserRole, VideoPlaylistType } from '@peertube/peertube-models'
import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@peertube/peertube-server-commands'
import {
cleanupTests,
createSingleServer, PeerTubeServer,
setAccessTokensToServers
} from '@peertube/peertube-server-commands'
describe('Test users', function () {
let server: PeerTubeServer
@ -264,7 +268,7 @@ describe('Test users', function () {
const user = await server.users.getMyInfo({ token: userToken })
for (const avatar of user.account.avatars) {
await testImageSize(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, '.gif')
await testAvatarSize({ url: server.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` })
}
})
@ -276,7 +280,7 @@ describe('Test users', function () {
const user = await server.users.getMyInfo({ token: userToken })
for (const avatar of user.account.avatars) {
await testImageSize(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, extension)
await testAvatarSize({ url: server.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` })
}
}
})

View File

@ -131,13 +131,13 @@ describe('Test multiple servers', function () {
await completeVideoCheck({ server, originServer: servers[0], videoUUID: video.uuid, attributes: checkAttributes })
publishedAt = video.publishedAt as string
expect(video.channel.avatars).to.have.lengthOf(2)
expect(video.account.avatars).to.have.lengthOf(2)
expect(video.channel.avatars).to.have.lengthOf(4)
expect(video.account.avatars).to.have.lengthOf(4)
for (const image of [ ...video.channel.avatars, ...video.account.avatars ]) {
expect(image.createdAt).to.exist
expect(image.updatedAt).to.exist
expect(image.width).to.be.above(20).and.below(1000)
expect(image.width).to.be.above(20).and.below(2000)
expect(image.path).to.exist
await makeGetRequest({

View File

@ -257,7 +257,7 @@ describe('Test video comments', function () {
expect(data[0].text).to.equal('my second answer to thread 4')
expect(data[0].account.name).to.equal('root')
expect(data[0].account.displayName).to.equal('root')
expect(data[0].account.avatars).to.have.lengthOf(2)
expect(data[0].account.avatars).to.have.lengthOf(4)
}
{
@ -266,8 +266,8 @@ describe('Test video comments', function () {
expect(total).to.equal(7)
expect(data).to.have.lengthOf(2)
expect(data[0].account.avatars).to.have.lengthOf(2)
expect(data[1].account.avatars).to.have.lengthOf(2)
expect(data[0].account.avatars).to.have.lengthOf(4)
expect(data[1].account.avatars).to.have.lengthOf(4)
}
})

View File

@ -46,7 +46,7 @@ async function assertCountAreOkay (servers: PeerTubeServer[]) {
expect(thumbnailsCount).to.equal(5) // 3 local videos, 1 local playlist, 2 remotes videos (lazy downloaded) and 1 remote playlist
const avatarsCount = await server.servers.countFiles('avatars')
expect(avatarsCount).to.equal(4)
expect(avatarsCount).to.equal(8)
const hlsRootCount = await server.servers.countFiles(join('streaming-playlists', 'hls'))
expect(hlsRootCount).to.equal(3) // 2 videos + private directory

View File

@ -3,7 +3,7 @@
import { expect } from 'chai'
import { pathExists } from 'fs-extra/esm'
import { readFile } from 'fs/promises'
import { join } from 'path'
import { join, parse } from 'path'
import { HttpStatusCode } from '@peertube/peertube-models'
import { buildAbsoluteFixturePath } from '@peertube/peertube-node-utils'
import { makeGetRequest, PeerTubeServer } from '@peertube/peertube-server-commands'
@ -42,14 +42,25 @@ async function expectLogContain (server: PeerTubeServer, str: string) {
expect(content.toString()).to.contain(str)
}
async function testImageSize (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') {
const res = await makeGetRequest({
async function testAvatarSize (options: {
url: string
imageName: string
avatar: {
width: number
path: string
}
}) {
const { url, imageName, avatar } = options
const { body } = await makeGetRequest({
url,
path: imageHTTPPath,
path: avatar.path,
expectedStatus: HttpStatusCode.OK_200
})
const body = res.body
const extension = parse(avatar.path).ext
// We don't test big GIF avatars
if (extension === '.gif' && avatar.width > 150) return
const data = await readFile(buildAbsoluteFixturePath(imageName + extension))
const minLength = data.length - ((40 * data.length) / 100)
@ -162,7 +173,7 @@ async function checkVideoDuration (server: PeerTubeServer, videoUUID: string, du
export {
dateIsValid,
testImageGeneratedByFFmpeg,
testImageSize,
testAvatarSize,
testImage,
expectLogDoesNotContain,
testFileExistsOrNot,

View File

@ -127,9 +127,15 @@ export async function prepareImportExportTests (options: {
const emailPort = await MockSmtpServer.Instance.collectEmails(emails)
const overrideConfig = {
...objectStorageConfig,
...ConfigCommand.getEmailOverrideConfig(emailPort),
...ConfigCommand.getDisableRatesLimitOverrideConfig()
}
const [ server, remoteServer, blockedServer ] = await Promise.all([
createSingleServer(1, { ...objectStorageConfig, ...ConfigCommand.getEmailOverrideConfig(emailPort) }),
createSingleServer(2, { ...objectStorageConfig, ...ConfigCommand.getEmailOverrideConfig(emailPort) }),
createSingleServer(1, overrideConfig),
createSingleServer(2, overrideConfig),
withBlockedServer
? createSingleServer(3)

View File

@ -933,7 +933,7 @@ function checkActor (actor: any, options: { withAvatar?: boolean } = {}) {
if (withAvatar) {
expect(actor.avatars).to.be.an('array')
expect(actor.avatars).to.have.lengthOf(2)
expect(actor.avatars).to.have.lengthOf(4)
expect(actor.avatars[0].path).to.exist.and.not.empty
}
}

View File

@ -31,7 +31,7 @@ export async function processImage (options: {
if (extension === '.gif') {
await processGIF({ path, destination, newSize })
} else {
await jimpProcessor(path, destination, newSize, extension)
await jimpProcessor({ path, destination, newSize, inputExt: extension })
}
if (keepOriginal !== true) await remove(path)
@ -56,7 +56,17 @@ export async function getImageSize (path: string) {
// Private
// ---------------------------------------------------------------------------
async function jimpProcessor (path: string, destination: string, newSize: { width: number, height: number }, inputExt: string) {
async function jimpProcessor (options: {
path: string
destination: string
newSize: {
width: number
height: number
}
inputExt: string
}) {
const { path, destination, newSize, inputExt } = options
let sourceImage: Jimp
const inputBuffer = await readFile(path)
@ -125,7 +135,7 @@ function skipProcessing (options: {
const { width, height } = newSize
if (hasExif(sourceImage)) return false
if (sourceImage.getWidth() > width || sourceImage.getHeight() > height) return false
if (sourceImage.getWidth() !== width || sourceImage.getHeight() !== height) return false
if (inputExt !== outputExt) return false
const kB = 1000

View File

@ -882,6 +882,14 @@ const PREVIEWS_SIZE = {
}
const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height: number }[] } = {
[ActorImageType.AVATAR]: [
{
width: 1500,
height: 1500
},
{
width: 600,
height: 600
},
{
width: 120,
height: 120