mirror of https://github.com/Chocobozzz/PeerTube
Generate 600x600 and 1500x1500 avatars
parent
fb2dc40858
commit
109e93c139
|
@ -21,7 +21,7 @@ export class ActorAvatarComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
@Input() previewImage: string
|
@Input() previewImage: string
|
||||||
|
|
||||||
@Input({ transform: numberAttribute }) size: number
|
@Input({ transform: numberAttribute }) size = 120
|
||||||
|
|
||||||
// Use an external link
|
// Use an external link
|
||||||
@Input() href: string
|
@Input() href: string
|
||||||
|
|
|
@ -30,6 +30,16 @@ export class ConfigCommand extends AbstractCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getDisableRatesLimitOverrideConfig () {
|
||||||
|
return {
|
||||||
|
rates_limit: {
|
||||||
|
api: {
|
||||||
|
max: 5000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
enableSignup (requiresApproval: boolean, limit = -1) {
|
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 |
|
@ -11,7 +11,7 @@ import {
|
||||||
PeerTubeServer,
|
PeerTubeServer,
|
||||||
setAccessTokensToServers
|
setAccessTokensToServers
|
||||||
} from '@peertube/peertube-server-commands'
|
} 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'
|
import { basename } from 'path'
|
||||||
|
|
||||||
function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
|
function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) {
|
||||||
|
@ -739,7 +739,7 @@ describe('Test config', function () {
|
||||||
const { avatars } = await checkAndGetServerImages()
|
const { avatars } = await checkAndGetServerImages()
|
||||||
|
|
||||||
for (const avatar of avatars) {
|
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
|
avatarPath = avatars[0].path
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import './oauth.js'
|
import './oauth.js'
|
||||||
import './registrations`.js'
|
import './registrations.js'
|
||||||
import './two-factor.js'
|
import './two-factor.js'
|
||||||
import './user-export.js'
|
import './user-export.js'
|
||||||
import './user-import.js'
|
import './user-import.js'
|
||||||
|
|
|
@ -435,7 +435,7 @@ function runTest (withObjectStorage: boolean) {
|
||||||
expect(secondaryChannel.description).to.equal('noah description')
|
expect(secondaryChannel.description).to.equal('noah description')
|
||||||
expect(secondaryChannel.support).to.equal('noah support')
|
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)
|
expect(secondaryChannel.banners).to.have.lengthOf(1)
|
||||||
|
|
||||||
const urls = [ ...secondaryChannel.avatars, ...secondaryChannel.banners ].map(a => a.url)
|
const urls = [ ...secondaryChannel.avatars, ...secondaryChannel.banners ].map(a => a.url)
|
||||||
|
@ -627,7 +627,7 @@ function runTest (withObjectStorage: boolean) {
|
||||||
// PeerTube format
|
// PeerTube format
|
||||||
{
|
{
|
||||||
const json = await parseZIPJSONFile<AccountExportJSON>(zip, 'peertube/account.json')
|
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) {
|
for (const avatar of json.avatars) {
|
||||||
await makeRawRequest({ url: avatar.url, expectedStatus: HttpStatusCode.OK_200 })
|
await makeRawRequest({ url: avatar.url, expectedStatus: HttpStatusCode.OK_200 })
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils
|
||||||
import { writeFile } from 'fs/promises'
|
import { writeFile } from 'fs/promises'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { expect } from 'chai'
|
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 { completeVideoCheck } from '@tests/shared/videos.js'
|
||||||
import { completeCheckHlsPlaylist } from '@tests/shared/streaming-playlists.js'
|
import { completeCheckHlsPlaylist } from '@tests/shared/streaming-playlists.js'
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ function runTest (withObjectStorage: boolean) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add avatars
|
// Add avatars
|
||||||
await server.users.updateMyAvatar({ token: noahToken, fixture: 'avatar.gif' })
|
await server.users.updateMyAvatar({ token: noahToken, fixture: 'avatar.png' })
|
||||||
|
|
||||||
// Add password protected video
|
// Add password protected video
|
||||||
await server.videos.upload({
|
await server.videos.upload({
|
||||||
|
@ -168,9 +168,10 @@ function runTest (withObjectStorage: boolean) {
|
||||||
expect(me.account.displayName).to.equal('noah')
|
expect(me.account.displayName).to.equal('noah')
|
||||||
expect(me.username).to.equal('noah_remote')
|
expect(me.username).to.equal('noah_remote')
|
||||||
expect(me.account.description).to.equal('super noah description')
|
expect(me.account.description).to.equal('super noah description')
|
||||||
|
expect(me.account.avatars).to.have.lengthOf(4)
|
||||||
|
|
||||||
for (const avatar of me.account.avatars) {
|
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
|
// My avatars
|
||||||
{
|
{
|
||||||
const me = await remoteServer.users.getMyInfo({ token: remoteNoahToken })
|
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
|
// Channels
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||||
|
|
||||||
import { expect } from 'chai'
|
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 { 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 () {
|
describe('Test users', function () {
|
||||||
let server: PeerTubeServer
|
let server: PeerTubeServer
|
||||||
|
@ -264,7 +268,7 @@ describe('Test users', function () {
|
||||||
|
|
||||||
const user = await server.users.getMyInfo({ token: userToken })
|
const user = await server.users.getMyInfo({ token: userToken })
|
||||||
for (const avatar of user.account.avatars) {
|
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 })
|
const user = await server.users.getMyInfo({ token: userToken })
|
||||||
for (const avatar of user.account.avatars) {
|
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}` })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -131,13 +131,13 @@ describe('Test multiple servers', function () {
|
||||||
await completeVideoCheck({ server, originServer: servers[0], videoUUID: video.uuid, attributes: checkAttributes })
|
await completeVideoCheck({ server, originServer: servers[0], videoUUID: video.uuid, attributes: checkAttributes })
|
||||||
publishedAt = video.publishedAt as string
|
publishedAt = video.publishedAt as string
|
||||||
|
|
||||||
expect(video.channel.avatars).to.have.lengthOf(2)
|
expect(video.channel.avatars).to.have.lengthOf(4)
|
||||||
expect(video.account.avatars).to.have.lengthOf(2)
|
expect(video.account.avatars).to.have.lengthOf(4)
|
||||||
|
|
||||||
for (const image of [ ...video.channel.avatars, ...video.account.avatars ]) {
|
for (const image of [ ...video.channel.avatars, ...video.account.avatars ]) {
|
||||||
expect(image.createdAt).to.exist
|
expect(image.createdAt).to.exist
|
||||||
expect(image.updatedAt).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
|
expect(image.path).to.exist
|
||||||
|
|
||||||
await makeGetRequest({
|
await makeGetRequest({
|
||||||
|
|
|
@ -257,7 +257,7 @@ describe('Test video comments', function () {
|
||||||
expect(data[0].text).to.equal('my second answer to thread 4')
|
expect(data[0].text).to.equal('my second answer to thread 4')
|
||||||
expect(data[0].account.name).to.equal('root')
|
expect(data[0].account.name).to.equal('root')
|
||||||
expect(data[0].account.displayName).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(total).to.equal(7)
|
||||||
expect(data).to.have.lengthOf(2)
|
expect(data).to.have.lengthOf(2)
|
||||||
|
|
||||||
expect(data[0].account.avatars).to.have.lengthOf(2)
|
expect(data[0].account.avatars).to.have.lengthOf(4)
|
||||||
expect(data[1].account.avatars).to.have.lengthOf(2)
|
expect(data[1].account.avatars).to.have.lengthOf(4)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -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
|
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')
|
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'))
|
const hlsRootCount = await server.servers.countFiles(join('streaming-playlists', 'hls'))
|
||||||
expect(hlsRootCount).to.equal(3) // 2 videos + private directory
|
expect(hlsRootCount).to.equal(3) // 2 videos + private directory
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { expect } from 'chai'
|
import { expect } from 'chai'
|
||||||
import { pathExists } from 'fs-extra/esm'
|
import { pathExists } from 'fs-extra/esm'
|
||||||
import { readFile } from 'fs/promises'
|
import { readFile } from 'fs/promises'
|
||||||
import { join } from 'path'
|
import { join, parse } from 'path'
|
||||||
import { HttpStatusCode } from '@peertube/peertube-models'
|
import { HttpStatusCode } from '@peertube/peertube-models'
|
||||||
import { buildAbsoluteFixturePath } from '@peertube/peertube-node-utils'
|
import { buildAbsoluteFixturePath } from '@peertube/peertube-node-utils'
|
||||||
import { makeGetRequest, PeerTubeServer } from '@peertube/peertube-server-commands'
|
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)
|
expect(content.toString()).to.contain(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testImageSize (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') {
|
async function testAvatarSize (options: {
|
||||||
const res = await makeGetRequest({
|
url: string
|
||||||
|
imageName: string
|
||||||
|
avatar: {
|
||||||
|
width: number
|
||||||
|
path: string
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
const { url, imageName, avatar } = options
|
||||||
|
|
||||||
|
const { body } = await makeGetRequest({
|
||||||
url,
|
url,
|
||||||
path: imageHTTPPath,
|
path: avatar.path,
|
||||||
expectedStatus: HttpStatusCode.OK_200
|
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 data = await readFile(buildAbsoluteFixturePath(imageName + extension))
|
||||||
const minLength = data.length - ((40 * data.length) / 100)
|
const minLength = data.length - ((40 * data.length) / 100)
|
||||||
|
@ -162,7 +173,7 @@ async function checkVideoDuration (server: PeerTubeServer, videoUUID: string, du
|
||||||
export {
|
export {
|
||||||
dateIsValid,
|
dateIsValid,
|
||||||
testImageGeneratedByFFmpeg,
|
testImageGeneratedByFFmpeg,
|
||||||
testImageSize,
|
testAvatarSize,
|
||||||
testImage,
|
testImage,
|
||||||
expectLogDoesNotContain,
|
expectLogDoesNotContain,
|
||||||
testFileExistsOrNot,
|
testFileExistsOrNot,
|
||||||
|
|
|
@ -127,9 +127,15 @@ export async function prepareImportExportTests (options: {
|
||||||
|
|
||||||
const emailPort = await MockSmtpServer.Instance.collectEmails(emails)
|
const emailPort = await MockSmtpServer.Instance.collectEmails(emails)
|
||||||
|
|
||||||
|
const overrideConfig = {
|
||||||
|
...objectStorageConfig,
|
||||||
|
...ConfigCommand.getEmailOverrideConfig(emailPort),
|
||||||
|
...ConfigCommand.getDisableRatesLimitOverrideConfig()
|
||||||
|
}
|
||||||
|
|
||||||
const [ server, remoteServer, blockedServer ] = await Promise.all([
|
const [ server, remoteServer, blockedServer ] = await Promise.all([
|
||||||
createSingleServer(1, { ...objectStorageConfig, ...ConfigCommand.getEmailOverrideConfig(emailPort) }),
|
createSingleServer(1, overrideConfig),
|
||||||
createSingleServer(2, { ...objectStorageConfig, ...ConfigCommand.getEmailOverrideConfig(emailPort) }),
|
createSingleServer(2, overrideConfig),
|
||||||
|
|
||||||
withBlockedServer
|
withBlockedServer
|
||||||
? createSingleServer(3)
|
? createSingleServer(3)
|
||||||
|
|
|
@ -933,7 +933,7 @@ function checkActor (actor: any, options: { withAvatar?: boolean } = {}) {
|
||||||
|
|
||||||
if (withAvatar) {
|
if (withAvatar) {
|
||||||
expect(actor.avatars).to.be.an('array')
|
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
|
expect(actor.avatars[0].path).to.exist.and.not.empty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ export async function processImage (options: {
|
||||||
if (extension === '.gif') {
|
if (extension === '.gif') {
|
||||||
await processGIF({ path, destination, newSize })
|
await processGIF({ path, destination, newSize })
|
||||||
} else {
|
} else {
|
||||||
await jimpProcessor(path, destination, newSize, extension)
|
await jimpProcessor({ path, destination, newSize, inputExt: extension })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keepOriginal !== true) await remove(path)
|
if (keepOriginal !== true) await remove(path)
|
||||||
|
@ -56,7 +56,17 @@ export async function getImageSize (path: string) {
|
||||||
// Private
|
// 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
|
let sourceImage: Jimp
|
||||||
const inputBuffer = await readFile(path)
|
const inputBuffer = await readFile(path)
|
||||||
|
|
||||||
|
@ -125,7 +135,7 @@ function skipProcessing (options: {
|
||||||
const { width, height } = newSize
|
const { width, height } = newSize
|
||||||
|
|
||||||
if (hasExif(sourceImage)) return false
|
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
|
if (inputExt !== outputExt) return false
|
||||||
|
|
||||||
const kB = 1000
|
const kB = 1000
|
||||||
|
|
|
@ -882,6 +882,14 @@ const PREVIEWS_SIZE = {
|
||||||
}
|
}
|
||||||
const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height: number }[] } = {
|
const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height: number }[] } = {
|
||||||
[ActorImageType.AVATAR]: [
|
[ActorImageType.AVATAR]: [
|
||||||
|
{
|
||||||
|
width: 1500,
|
||||||
|
height: 1500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 600,
|
||||||
|
height: 600
|
||||||
|
},
|
||||||
{
|
{
|
||||||
width: 120,
|
width: 120,
|
||||||
height: 120
|
height: 120
|
||||||
|
|
Loading…
Reference in New Issue