]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/controllers/api/users.ts
Automatically resize avatars
[github/Chocobozzz/PeerTube.git] / server / controllers / api / users.ts
index 995542604530d3d69376f6c8fc1430e626329144..6c24434f2f588a15949c4b328fbbb1ef97c704dd 100644 (file)
@@ -1,32 +1,27 @@
 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 { getFormattedObjects, logger, retryTransactionWrapper } from '../../helpers'
-import { CONFIG } from '../../initializers'
-import { createUserAccountAndChannel } from '../../lib'
+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, AVATARS_SIZE, CONFIG, sequelizeTypescript } from '../../initializers'
+import { createUserAccountAndChannel } from '../../lib/user'
 import {
-  asyncMiddleware,
-  authenticate,
-  ensureUserHasRight,
-  ensureUserRegistrationAllowed,
-  paginationValidator,
-  setPagination,
-  setUsersSort,
-  setVideosSort,
-  token,
-  usersAddValidator,
-  usersGetValidator,
-  usersRegisterValidator,
-  usersRemoveValidator,
-  usersSortValidator,
-  usersUpdateMeValidator,
-  usersUpdateValidator,
-  usersVideoRatingValidator
+  asyncMiddleware, authenticate, ensureUserHasRight, ensureUserRegistrationAllowed, paginationValidator, setPagination, setUsersSort,
+  setVideosSort, token, usersAddValidator, usersGetValidator, usersRegisterValidator, usersRemoveValidator, usersSortValidator,
+  usersUpdateMeValidator, usersUpdateValidator, usersVideoRatingValidator
 } from '../../middlewares'
-import { videosSortValidator } from '../../middlewares/validators'
+import { usersUpdateMyAvatarValidator, videosSortValidator } from '../../middlewares/validators'
 import { AccountVideoRateModel } from '../../models/account/account-video-rate'
 import { UserModel } from '../../models/account/user'
+import { AvatarModel } from '../../models/avatar/avatar'
 import { VideoModel } from '../../models/video/video'
 
+const reqAvatarFile = createReqFiles('avatarfile', CONFIG.STORAGE.AVATARS_DIR, AVATAR_MIMETYPE_EXT)
+
 const usersRouter = express.Router()
 
 usersRouter.get('/me',
@@ -83,6 +78,13 @@ usersRouter.put('/me',
   asyncMiddleware(updateMe)
 )
 
+usersRouter.post('/me/avatar/pick',
+  authenticate,
+  reqAvatarFile,
+  usersUpdateMyAvatarValidator,
+  asyncMiddleware(updateMyAvatar)
+)
+
 usersRouter.put('/:id',
   authenticate,
   ensureUserHasRight(UserRight.MANAGE_USERS),
@@ -228,6 +230,44 @@ async function updateMe (req: express.Request, res: express.Response, next: expr
   return res.sendStatus(204)
 }
 
+async function updateMyAvatar (req: express.Request, res: express.Response, next: express.NextFunction) {
+  const avatarPhysicalFile = req.files['avatarfile'][0]
+  const actor = res.locals.oauth.token.user.Account.Actor
+
+  const avatarDir = CONFIG.STORAGE.AVATARS_DIR
+  const source = join(avatarDir, avatarPhysicalFile.filename)
+  const extension = extname(avatarPhysicalFile.filename)
+  const avatarName = uuidv4() + extension
+  const destination = join(avatarDir, avatarName)
+
+  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({
+      filename: avatarName
+    }, { transaction: t })
+
+    if (actor.Avatar) {
+      await actor.Avatar.destroy({ transaction: t })
+    }
+
+    actor.set('avatarId', avatar.id)
+    await actor.save({ transaction: t })
+
+    return { actor, avatar }
+  })
+
+  return res
+    .json({
+      avatar: avatar.toFormattedJSON()
+    })
+    .end()
+}
+
 async function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
   const body: UserUpdate = req.body
   const user = res.locals.user as UserModel