From e8e122002d5a6a2bedcf3d66d35657c9b9e1ebaf Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 3 Jan 2018 11:36:03 +0100 Subject: [PATCH] Automatically resize avatars --- package.json | 1 + server.ts | 2 +- server/controllers/activitypub/inbox.ts | 2 +- server/controllers/activitypub/outbox.ts | 2 +- server/controllers/api/users.ts | 11 ++++++++--- server/initializers/constants.ts | 5 +++++ server/middlewares/validators/users.ts | 3 +-- server/models/server/server.ts | 2 +- server/models/video/video-comment.ts | 2 +- server/tests/api/fixtures/avatar-resized.png | Bin 0 -> 2420 bytes server/tests/api/users/users.ts | 2 +- yarn.lock | 6 ++++++ 12 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 server/tests/api/fixtures/avatar-resized.png diff --git a/package.json b/package.json index adaccaf37..e082eeb6e 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "@types/request": "^2.0.3", "@types/sanitize-html": "^1.14.0", "@types/sequelize": "^4.0.55", + "@types/sharp": "^0.17.6", "@types/supertest": "^2.0.3", "@types/validator": "^6.2.0", "@types/webtorrent": "^0.98.4", diff --git a/server.ts b/server.ts index e46ff85c7..05fc39acb 100644 --- a/server.ts +++ b/server.ts @@ -164,7 +164,7 @@ function onDatabaseInitDone () { .then(() => { // ----------- Make the server listening ----------- server.listen(port, () => { - VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.FILE_SIZE) + VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE) activitypubHttpJobScheduler.activate() transcodingJobScheduler.activate() diff --git a/server/controllers/activitypub/inbox.ts b/server/controllers/activitypub/inbox.ts index bfcb7b369..8d65639f8 100644 --- a/server/controllers/activitypub/inbox.ts +++ b/server/controllers/activitypub/inbox.ts @@ -16,7 +16,7 @@ inboxRouter.post('/inbox', asyncMiddleware(inboxController) ) -inboxRouter.post('/account/:name/inbox', +inboxRouter.post('/accounts/:name/inbox', signatureValidator, asyncMiddleware(checkSignature), localAccountValidator, diff --git a/server/controllers/activitypub/outbox.ts b/server/controllers/activitypub/outbox.ts index 01ba253c6..620f9ee83 100644 --- a/server/controllers/activitypub/outbox.ts +++ b/server/controllers/activitypub/outbox.ts @@ -11,7 +11,7 @@ import { VideoModel } from '../../models/video/video' const outboxRouter = express.Router() -outboxRouter.get('/account/:name/outbox', +outboxRouter.get('/accounts/:name/outbox', localAccountValidator, asyncMiddleware(outboxController) ) diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts index 57b98b84a..6c24434f2 100644 --- a/server/controllers/api/users.ts +++ b/server/controllers/api/users.ts @@ -1,12 +1,13 @@ import * as express from 'express' import { extname, join } from 'path' +import * as sharp from 'sharp' import * as uuidv4 from 'uuid/v4' import { UserCreate, UserRight, UserRole, UserUpdate, UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../shared' -import { renamePromise } from '../../helpers/core-utils' +import { renamePromise, unlinkPromise } from '../../helpers/core-utils' import { retryTransactionWrapper } from '../../helpers/database-utils' import { logger } from '../../helpers/logger' import { createReqFiles, getFormattedObjects } from '../../helpers/utils' -import { AVATAR_MIMETYPE_EXT, CONFIG, sequelizeTypescript } from '../../initializers' +import { AVATAR_MIMETYPE_EXT, AVATARS_SIZE, CONFIG, sequelizeTypescript } from '../../initializers' import { createUserAccountAndChannel } from '../../lib/user' import { asyncMiddleware, authenticate, ensureUserHasRight, ensureUserRegistrationAllowed, paginationValidator, setPagination, setUsersSort, @@ -239,7 +240,11 @@ async function updateMyAvatar (req: express.Request, res: express.Response, next const avatarName = uuidv4() + extension const destination = join(avatarDir, avatarName) - await renamePromise(source, destination) + await sharp(source) + .resize(AVATARS_SIZE.width, AVATARS_SIZE.height) + .toFile(destination) + + await unlinkPromise(source) const { avatar } = await sequelizeTypescript.transaction(async t => { const avatar = await AvatarModel.create({ diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index aefb91537..d9b21b389 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -316,6 +316,10 @@ const PREVIEWS_SIZE = { width: 560, height: 315 } +const AVATARS_SIZE = { + width: 120, + height: 120 +} const EMBED_SIZE = { width: 560, @@ -355,6 +359,7 @@ CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WE export { API_VERSION, + AVATARS_SIZE, ACCEPT_HEADERS, BCRYPT_SALT_SIZE, CACHE, diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 7de3e442c..d22a745b4 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts @@ -12,7 +12,6 @@ import { isSignupAllowed } from '../../helpers/utils' import { CONSTRAINTS_FIELDS } from '../../initializers' import { UserModel } from '../../models/account/user' import { areValidationErrors } from './utils' -import Multer = require('multer') const usersAddValidator = [ body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'), @@ -105,7 +104,7 @@ const usersUpdateMyAvatarValidator = [ ), (req: express.Request, res: express.Response, next: express.NextFunction) => { - logger.debug('Checking usersUpdateMyAvatarValidator parameters', { parameters: req.body }) + logger.debug('Checking usersUpdateMyAvatarValidator parameters', { files: req.files }) if (areValidationErrors(req, res)) return diff --git a/server/models/server/server.ts b/server/models/server/server.ts index 122e5f74f..d35aa0ca4 100644 --- a/server/models/server/server.ts +++ b/server/models/server/server.ts @@ -27,7 +27,7 @@ export class ServerModel extends Model { @AllowNull(false) @Default(SERVERS_SCORE.BASE) @IsInt - @Max(SERVERS_SCORE.max) + @Max(SERVERS_SCORE.MAX) @Column score: number diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index 829022a51..63675c20b 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts @@ -214,7 +214,7 @@ export class VideoCommentModel extends Model { static listThreadCommentsForApi (videoId: number, threadId: number) { const query = { - order: [ [ 'createdAt', 'DESC' ] ], + order: [ [ 'createdAt', 'ASC' ] ], where: { videoId, [ Sequelize.Op.or ]: [ diff --git a/server/tests/api/fixtures/avatar-resized.png b/server/tests/api/fixtures/avatar-resized.png new file mode 100644 index 0000000000000000000000000000000000000000..e05fc07ce896e0a096b2c58802cc2c9c9301f89a GIT binary patch literal 2420 zcmb_e`#TeS8`sIH70Ee=<{{E@Y6&riOihS|a@u(2Fd-&1l0%OuhppyVPE9e)A%~o2 z$@5rRS`14whlhw+$)1t(yPp5xeXsYv?)!UR*Y}tE`hLEj&wbwyot-Wol2n!y5fM2A zyJQO&X6&yJ-zz*@M2Yu>Nh0Es$1M?&gEGHj&k!eJOL%tzW^3(=E#eh>Tw%XgP73PM zdX%Ll-5~DlHl$$wEoyUQI`f3JN}bh*$XDlTJ_*hs`;f z1eKhcjWaKyg$MREwY?)WjQOSRwKG2q*uP=EEp)35i485LY~g8ZEhz}X)}JA91drp^66OYHUMn_ZmS}8x{yV2l| z&dy_a8gt>F*Qf%s6&hZB-G|e{Lxbbu+c%78XAZ?_T}(t&j9}7gmv)R>gr)BDPrA{{_N`~5%;RAzfVxSyu6yi z?huU5IR$h|QbnWyLBxzl}1Y#7Z0`+uL7=T~|%d$|pfhMQ{;9HdbJ! z7WPd&aB21?K5S{0QN~h3eKhQ8jC|gfH!ys$FSXzeT_x7$Xa|;Wtqfs9= zn)LGNxS5n*KlCH@x2=f!#O;j{13(>WS0(8Bv%coAO?GSeD^K1RdOoBy{JI9pfhDlj zaM6*~ggtfl(xgXfJVqNA)+4D1AD?Y*?-|E4x%OJwFd7ESP+2K{7fI92?)Qh3N~QI3 zx!jD53)u`XNwL<>#IiSNZ!I79~E@c6qBb&}T0t!FtU#l>#q zk*X{5x5korCOA!)kQY}zE1&h65+ZT4m3>#uO{^xO#+_VPSjecX5FM;_=g!Tg(mspn zMGJND%CnZug9MjOn=j8ZN`so-9$7^DunGs}hV?&4RsQ(N6Q3W!2WI;C_+UDI4kzmf zKeVIHlH}tdJv?&5jU^alU1Uf<_&XkA*}s#YHZ3gf``K7%o_+az zvw}*}fz+{3`54ppiOwW=)%=>$!(DGr0-!hP(8*f|qtff@>-p>EEUh6G=mqEAiy3pq zmB17RgAv9qiD>=ayR1sd)~sUlgpWM}`R(k{y$nb`T`mJUaj<+nJ@uK8e8NJ~M*X(~ zDh|6UR|NOXU{a1xLDUXy1|{z9)N;+<98T5lQ9N&9ai4O(D;$8DLK0qdc6OFpCcfEe zjEy)n9iNbJ*vmrtro;uX>+x5fr{yz%{%bnR?ry`x~uuS^8_@p5Jcba)u(?x3)KLKj7|;4cJsyBfPx} zD%MwdUO&gm{*s-|?e}-Oas^mtSPEWUd)^amTzG($Kuz?e%90#_*qI+#jmJrx)VEZU z66jo#*$dCwgqzn7V`5T%T0JOV*(O%`OKBPTa56I_M*e)V~Ebu~jl|6b43a;v)CV@L!< zvjKFfaG-*@P*`}(&22C)GBF^qte>Ll=B7%6mBZV;^<*A~hKAPE*Y}QondWnx?^}-h zJ=;kWc0}bYyDC>9EW8*mf~NTFShvmq94r#8(^c|?zivZ(+1A$9+}zyQDDz8PrL>vk zdf-2|?})vR>Et+(o^v+@g6QXi=vMZ!=^d!c+^kR3YT2H19ZINTC$a8>3`IWHJlX0s zSMa7U_NUq&pm3J-U2kO{pbLq-x+<>+J((LYR*ReOF?ymtnB)a)ySuMaY+SvY{ry|` z8Dd?U*c2kjX{+OXJ~}_a@%dJo{4I1$lBpbrQFKh@NCV`5Uql`z?zwi_ck=p1R)KJh O5`jUTZ0l@%@BIf^kcNH$ literal 0 HcmV?d00001 diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts index 3390b2d56..f7e5972d3 100644 --- a/server/tests/api/users/users.ts +++ b/server/tests/api/users/users.ts @@ -352,7 +352,7 @@ describe('Test users', function () { const res = await getMyUserInformation(server.url, accessTokenUser) const user = res.body - const test = await testVideoImage(server.url, 'avatar', user.account.avatar.path, '.png') + const test = await testVideoImage(server.url, 'avatar-resized', user.account.avatar.path, '.png') expect(test).to.equal(true) }) diff --git a/yarn.lock b/yarn.lock index 67337c08b..7929d6ae0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -170,6 +170,12 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" +"@types/sharp@^0.17.6": + version "0.17.6" + resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.17.6.tgz#3138602163b30b4969f75a2755a3f90caaaa9be3" + dependencies: + "@types/node" "*" + "@types/simple-peer@*": version "6.1.4" resolved "https://registry.yarnpkg.com/@types/simple-peer/-/simple-peer-6.1.4.tgz#1d1384e1d8dc17b9e7d1673d704febe91ca48191"