mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-12-08 04:09:07 +00:00
feat(server): split generated content into a separate folder (#2047)
* feat: organize media folders * fix: tests
This commit is contained in:
@@ -275,7 +275,7 @@ describe('AssetService', () => {
|
||||
expect(assetRepositoryMock.create).toHaveBeenCalled();
|
||||
expect(assetRepositoryMock.save).toHaveBeenCalledWith({
|
||||
id: 'id_1',
|
||||
originalPath: 'upload/user_id_1/2022/2022-06-19/asset_1.jpeg',
|
||||
originalPath: 'upload/library/user_id_1/2022/2022-06-19/asset_1.jpeg',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -137,16 +137,7 @@ describe('assetUploadOption', () => {
|
||||
destination(mock.userRequest, mock.file, callback);
|
||||
|
||||
expect(mkdirSync).not.toHaveBeenCalled();
|
||||
expect(callback).toHaveBeenCalledWith(null, 'upload/test-user/original/test-device');
|
||||
});
|
||||
|
||||
it('should sanitize the deviceId', () => {
|
||||
const request = { ...mock.userRequest, body: { deviceId: 'test-devi\u0000ce' } } as Request;
|
||||
destination(request, mock.file, callback);
|
||||
|
||||
const [folderName] = existsSync.mock.calls[0];
|
||||
expect(folderName.endsWith('test-device')).toBeTruthy();
|
||||
expect(callback).toHaveBeenCalledWith(null, 'upload/test-user/original/test-device');
|
||||
expect(callback).toHaveBeenCalledWith(null, 'upload/upload/test-user');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { APP_UPLOAD_LOCATION } from '@app/domain/domain.constant';
|
||||
import { StorageCore, StorageFolder } from '@app/domain/storage';
|
||||
import { BadRequestException, Logger, UnauthorizedException } from '@nestjs/common';
|
||||
import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface';
|
||||
import { createHash, randomUUID } from 'crypto';
|
||||
import { Request } from 'express';
|
||||
import { existsSync, mkdirSync } from 'fs';
|
||||
import { diskStorage, StorageEngine } from 'multer';
|
||||
import { extname, join } from 'path';
|
||||
import { extname } from 'path';
|
||||
import sanitize from 'sanitize-filename';
|
||||
import { AuthUserDto } from '../decorators/auth-user.decorator';
|
||||
import { patchFormData } from '../utils/path-form-data.util';
|
||||
@@ -20,6 +20,8 @@ export const assetUploadOption: MulterOptions = {
|
||||
storage: customStorage(),
|
||||
};
|
||||
|
||||
const storageCore = new StorageCore();
|
||||
|
||||
export function customStorage(): StorageEngine {
|
||||
const storage = diskStorage({ destination, filename });
|
||||
|
||||
@@ -71,16 +73,13 @@ function destination(req: Request, file: Express.Multer.File, cb: any) {
|
||||
|
||||
const user = req.user as AuthUserDto;
|
||||
|
||||
const basePath = APP_UPLOAD_LOCATION;
|
||||
const sanitizedDeviceId = sanitize(String(req.body['deviceId']));
|
||||
const originalUploadFolder = join(basePath, user.id, 'original', sanitizedDeviceId);
|
||||
|
||||
if (!existsSync(originalUploadFolder)) {
|
||||
mkdirSync(originalUploadFolder, { recursive: true });
|
||||
const uploadFolder = storageCore.getFolderLocation(StorageFolder.UPLOAD, user.id);
|
||||
if (!existsSync(uploadFolder)) {
|
||||
mkdirSync(uploadFolder, { recursive: true });
|
||||
}
|
||||
|
||||
// Save original to disk
|
||||
cb(null, originalUploadFolder);
|
||||
cb(null, uploadFolder);
|
||||
}
|
||||
|
||||
function filename(req: Request, file: Express.Multer.File, cb: any) {
|
||||
|
||||
@@ -85,7 +85,7 @@ describe('profileImageUploadOption', () => {
|
||||
destination(mock.userRequest, mock.file, callback);
|
||||
|
||||
expect(mkdirSync).not.toHaveBeenCalled();
|
||||
expect(callback).toHaveBeenCalledWith(null, './upload/test-user/profile');
|
||||
expect(callback).toHaveBeenCalledWith(null, 'upload/profile/test-user');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { APP_UPLOAD_LOCATION } from '@app/domain/domain.constant';
|
||||
import { StorageCore, StorageFolder } from '@app/domain/storage';
|
||||
import { BadRequestException, UnauthorizedException } from '@nestjs/common';
|
||||
import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface';
|
||||
import { Request } from 'express';
|
||||
@@ -19,6 +19,8 @@ export const profileImageUploadOption: MulterOptions = {
|
||||
|
||||
export const multerUtils = { fileFilter, filename, destination };
|
||||
|
||||
const storageCore = new StorageCore();
|
||||
|
||||
function fileFilter(req: Request, file: any, cb: any) {
|
||||
if (!req.user) {
|
||||
return cb(new UnauthorizedException());
|
||||
@@ -38,9 +40,7 @@ function destination(req: Request, file: Express.Multer.File, cb: any) {
|
||||
|
||||
const user = req.user as AuthUserDto;
|
||||
|
||||
const basePath = APP_UPLOAD_LOCATION;
|
||||
const profileImageLocation = `${basePath}/${user.id}/profile`;
|
||||
|
||||
const profileImageLocation = storageCore.getFolderLocation(StorageFolder.PROFILE, user.id);
|
||||
if (!existsSync(profileImageLocation)) {
|
||||
mkdirSync(profileImageLocation, { recursive: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user