mirror of
https://github.com/immich-app/immich.git
synced 2025-05-31 12:15:47 -04:00
refactor(server): common (#2066)
This commit is contained in:
parent
54f98053a8
commit
1efc74dabc
@ -1,4 +1,4 @@
|
|||||||
import { immichAppConfig } from '@app/common/config';
|
import { immichAppConfig } from '@app/domain';
|
||||||
import { Module, OnModuleInit } from '@nestjs/common';
|
import { Module, OnModuleInit } from '@nestjs/common';
|
||||||
import { AssetModule } from './api-v1/asset/asset.module';
|
import { AssetModule } from './api-v1/asset/asset.module';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
|
@ -9,7 +9,7 @@ import { AppModule } from './app.module';
|
|||||||
import { RedisIoAdapter } from './middlewares/redis-io.adapter.middleware';
|
import { RedisIoAdapter } from './middlewares/redis-io.adapter.middleware';
|
||||||
import { json } from 'body-parser';
|
import { json } from 'body-parser';
|
||||||
import { patchOpenAPI } from './utils/patch-open-api.util';
|
import { patchOpenAPI } from './utils/patch-open-api.util';
|
||||||
import { getLogLevels, MACHINE_LEARNING_ENABLED } from '@app/common';
|
import { getLogLevels, MACHINE_LEARNING_ENABLED } from '@app/domain';
|
||||||
import { SERVER_VERSION, IMMICH_ACCESS_COOKIE, SearchService } from '@app/domain';
|
import { SERVER_VERSION, IMMICH_ACCESS_COOKIE, SearchService } from '@app/domain';
|
||||||
|
|
||||||
const logger = new Logger('ImmichServer');
|
const logger = new Logger('ImmichServer');
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
"^.+\\.(t|j)s$": "ts-jest"
|
"^.+\\.(t|j)s$": "ts-jest"
|
||||||
},
|
},
|
||||||
"moduleNameMapper": {
|
"moduleNameMapper": {
|
||||||
"^@app/common": "<rootDir>../../../libs/common/src",
|
|
||||||
"^@app/infra(|/.*)$": "<rootDir>../../../libs/infra/src/$1",
|
"^@app/infra(|/.*)$": "<rootDir>../../../libs/infra/src/$1",
|
||||||
"^@app/domain(|/.*)$": "<rootDir>../../../libs/domain/src/$1"
|
"^@app/domain(|/.*)$": "<rootDir>../../../libs/domain/src/$1"
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { SERVER_VERSION } from '@app/domain';
|
import { SERVER_VERSION } from '@app/domain';
|
||||||
import { getLogLevels } from '@app/common';
|
import { getLogLevels } from '@app/domain';
|
||||||
import { RedisIoAdapter } from '../../immich/src/middlewares/redis-io.adapter.middleware';
|
import { RedisIoAdapter } from '../../immich/src/middlewares/redis-io.adapter.middleware';
|
||||||
import { MicroservicesModule } from './microservices.module';
|
import { MicroservicesModule } from './microservices.module';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { immichAppConfig } from '@app/common/config';
|
import { immichAppConfig } from '@app/domain';
|
||||||
import { DomainModule } from '@app/domain';
|
import { DomainModule } from '@app/domain';
|
||||||
import { ExifEntity, InfraModule } from '@app/infra';
|
import { ExifEntity, InfraModule } from '@app/infra';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export * from './app.config';
|
|
@ -1,10 +0,0 @@
|
|||||||
import { BadRequestException } from '@nestjs/common';
|
|
||||||
|
|
||||||
export const MACHINE_LEARNING_URL = process.env.IMMICH_MACHINE_LEARNING_URL || 'http://immich-machine-learning:3003';
|
|
||||||
export const MACHINE_LEARNING_ENABLED = MACHINE_LEARNING_URL !== 'false';
|
|
||||||
|
|
||||||
export function assertMachineLearningEnabled() {
|
|
||||||
if (!MACHINE_LEARNING_ENABLED) {
|
|
||||||
throw new BadRequestException('Machine learning is not enabled.');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export * from './config';
|
|
||||||
export * from './constants';
|
|
||||||
export * from './utils';
|
|
@ -1,20 +0,0 @@
|
|||||||
import { assetUtils } from './asset-utils';
|
|
||||||
|
|
||||||
describe('Asset Utilities', () => {
|
|
||||||
describe('isWebPlayable', () => {
|
|
||||||
it('Check that it returns true with mimetype webm', () => {
|
|
||||||
const result = assetUtils.isWebPlayable('video/webm');
|
|
||||||
expect(result).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Check that returns true with mimetype mp4', () => {
|
|
||||||
const result = assetUtils.isWebPlayable('video/mp4');
|
|
||||||
expect(result).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Check that returns false with mimetype quicktime', () => {
|
|
||||||
const result = assetUtils.isWebPlayable('video/quicktime');
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,48 +0,0 @@
|
|||||||
import { AssetEntity } from '@app/infra/db/entities';
|
|
||||||
import { AssetResponseDto } from '@app/domain';
|
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
const deleteFiles = (asset: AssetEntity | AssetResponseDto) => {
|
|
||||||
fs.unlink(asset.originalPath, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.log('error deleting ', asset.originalPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: what if there is no asset.resizePath. Should fail the Job?
|
|
||||||
// => panoti report: Job not fail
|
|
||||||
if (asset.resizePath) {
|
|
||||||
fs.unlink(asset.resizePath, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.log('error deleting ', asset.resizePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (asset.webpPath) {
|
|
||||||
fs.unlink(asset.webpPath, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.log('error deleting ', asset.webpPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (asset.encodedVideoPath) {
|
|
||||||
fs.unlink(asset.encodedVideoPath, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.log('error deleting ', asset.encodedVideoPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const isWebPlayable = (mimeType: string | null): boolean => {
|
|
||||||
const WEB_PLAYABLE = ['video/webm', 'video/mp4'];
|
|
||||||
|
|
||||||
if (mimeType !== null) {
|
|
||||||
return WEB_PLAYABLE.includes(mimeType);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const assetUtils = { deleteFiles, isWebPlayable };
|
|
@ -1,14 +0,0 @@
|
|||||||
import { LogLevel } from '@nestjs/common';
|
|
||||||
|
|
||||||
export * from './time-utils';
|
|
||||||
export * from './asset-utils';
|
|
||||||
|
|
||||||
export function getLogLevels() {
|
|
||||||
const LOG_LEVELS: LogLevel[] = ['verbose', 'debug', 'log', 'warn', 'error'];
|
|
||||||
let logLevel = process.env.LOG_LEVEL || 'log';
|
|
||||||
if (logLevel === 'simple') {
|
|
||||||
logLevel = 'log';
|
|
||||||
}
|
|
||||||
const logLevelIndex = LOG_LEVELS.indexOf(logLevel as LogLevel);
|
|
||||||
return logLevelIndex === -1 ? [] : LOG_LEVELS.slice(logLevelIndex);
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
// create unit test for time utils
|
|
||||||
|
|
||||||
import { timeUtils } from './time-utils';
|
|
||||||
|
|
||||||
describe('Time Utilities', () => {
|
|
||||||
describe('timezone', () => {
|
|
||||||
it('should always be UTC', () => {
|
|
||||||
expect(new Date().getTimezoneOffset()).toBe(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('checkValidTimestamp', () => {
|
|
||||||
it('check for year 0000', () => {
|
|
||||||
const result = timeUtils.checkValidTimestamp('0000-00-00T00:00:00.000Z');
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check for 6-digits year with plus sign', () => {
|
|
||||||
const result = timeUtils.checkValidTimestamp('+12345-00-00T00:00:00.000Z');
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check for 6-digits year with negative sign', () => {
|
|
||||||
const result = timeUtils.checkValidTimestamp('-12345-00-00T00:00:00.000Z');
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check for current date', () => {
|
|
||||||
const result = timeUtils.checkValidTimestamp(new Date().toISOString());
|
|
||||||
expect(result).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check for year before 1583', () => {
|
|
||||||
const result = timeUtils.checkValidTimestamp('1582-12-31T23:59:59.999Z');
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check for year after 9999', () => {
|
|
||||||
const result = timeUtils.checkValidTimestamp('10000-00-00T00:00:00.000Z');
|
|
||||||
expect(result).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,21 +0,0 @@
|
|||||||
function createTimeUtils() {
|
|
||||||
const checkValidTimestamp = (timestamp: string): boolean => {
|
|
||||||
const parsedTimestamp = Date.parse(timestamp);
|
|
||||||
|
|
||||||
if (isNaN(parsedTimestamp)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const date = new Date(parsedTimestamp);
|
|
||||||
|
|
||||||
if (date.getFullYear() < 1583 || date.getFullYear() > 9999) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return date.getFullYear() > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
return { checkValidTimestamp };
|
|
||||||
}
|
|
||||||
|
|
||||||
export const timeUtils = createTimeUtils();
|
|
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"declaration": true,
|
|
||||||
"outDir": "../../dist/libs/common"
|
|
||||||
},
|
|
||||||
"include": ["src/**/*"],
|
|
||||||
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
|
|
||||||
}
|
|
@ -1,3 +1,5 @@
|
|||||||
|
// TODO: remove nestjs references from domain
|
||||||
|
import { LogLevel } from '@nestjs/common';
|
||||||
import { ConfigModuleOptions } from '@nestjs/config';
|
import { ConfigModuleOptions } from '@nestjs/config';
|
||||||
import Joi from 'joi';
|
import Joi from 'joi';
|
||||||
|
|
||||||
@ -29,3 +31,13 @@ export const immichAppConfig: ConfigModuleOptions = {
|
|||||||
SERVER_PORT: Joi.number().optional(),
|
SERVER_PORT: Joi.number().optional(),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getLogLevels() {
|
||||||
|
const LOG_LEVELS: LogLevel[] = ['verbose', 'debug', 'log', 'warn', 'error'];
|
||||||
|
let logLevel = process.env.LOG_LEVEL || 'log';
|
||||||
|
if (logLevel === 'simple') {
|
||||||
|
logLevel = 'log';
|
||||||
|
}
|
||||||
|
const logLevelIndex = LOG_LEVELS.indexOf(logLevel as LogLevel);
|
||||||
|
return logLevelIndex === -1 ? [] : LOG_LEVELS.slice(logLevelIndex);
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import { BadRequestException } from '@nestjs/common';
|
||||||
import pkg from '../../../package.json';
|
import pkg from '../../../package.json';
|
||||||
|
|
||||||
const [major, minor, patch] = pkg.version.split('.');
|
const [major, minor, patch] = pkg.version.split('.');
|
||||||
@ -17,3 +18,12 @@ export const serverVersion: IServerVersion = {
|
|||||||
export const SERVER_VERSION = `${serverVersion.major}.${serverVersion.minor}.${serverVersion.patch}`;
|
export const SERVER_VERSION = `${serverVersion.major}.${serverVersion.minor}.${serverVersion.patch}`;
|
||||||
|
|
||||||
export const APP_UPLOAD_LOCATION = './upload';
|
export const APP_UPLOAD_LOCATION = './upload';
|
||||||
|
|
||||||
|
export const MACHINE_LEARNING_URL = process.env.IMMICH_MACHINE_LEARNING_URL || 'http://immich-machine-learning:3003';
|
||||||
|
export const MACHINE_LEARNING_ENABLED = MACHINE_LEARNING_URL !== 'false';
|
||||||
|
|
||||||
|
export function assertMachineLearningEnabled() {
|
||||||
|
if (!MACHINE_LEARNING_ENABLED) {
|
||||||
|
throw new BadRequestException('Machine learning is not enabled.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@ export * from './auth';
|
|||||||
export * from './communication';
|
export * from './communication';
|
||||||
export * from './crypto';
|
export * from './crypto';
|
||||||
export * from './device-info';
|
export * from './device-info';
|
||||||
|
export * from './domain.config';
|
||||||
export * from './domain.constant';
|
export * from './domain.constant';
|
||||||
export * from './domain.module';
|
export * from './domain.module';
|
||||||
export * from './domain.util';
|
export * from './domain.util';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { assertMachineLearningEnabled } from '@app/common';
|
|
||||||
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { assertMachineLearningEnabled } from '../domain.constant';
|
||||||
import { JobCommandDto } from './dto';
|
import { JobCommandDto } from './dto';
|
||||||
import { JobCommand, JobName, QueueName } from './job.constants';
|
import { JobCommand, JobName, QueueName } from './job.constants';
|
||||||
import { IJobRepository } from './job.repository';
|
import { IJobRepository } from './job.repository';
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { MACHINE_LEARNING_ENABLED } from '@app/common';
|
|
||||||
import { AlbumEntity, AssetEntity } from '@app/infra/db/entities';
|
import { AlbumEntity, AssetEntity } from '@app/infra/db/entities';
|
||||||
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
@ -7,6 +6,7 @@ import { IAlbumRepository } from '../album/album.repository';
|
|||||||
import { mapAsset } from '../asset';
|
import { mapAsset } from '../asset';
|
||||||
import { IAssetRepository } from '../asset/asset.repository';
|
import { IAssetRepository } from '../asset/asset.repository';
|
||||||
import { AuthUserDto } from '../auth';
|
import { AuthUserDto } from '../auth';
|
||||||
|
import { MACHINE_LEARNING_ENABLED } from '../domain.constant';
|
||||||
import { IBulkEntityJob, IJobRepository, JobName } from '../job';
|
import { IBulkEntityJob, IJobRepository, JobName } from '../job';
|
||||||
import { IMachineLearningRepository } from '../smart-info';
|
import { IMachineLearningRepository } from '../smart-info';
|
||||||
import { SearchDto } from './dto';
|
import { SearchDto } from './dto';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { MACHINE_LEARNING_ENABLED } from '@app/common';
|
|
||||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
import { IAssetRepository, WithoutProperty } from '../asset';
|
import { IAssetRepository, WithoutProperty } from '../asset';
|
||||||
|
import { MACHINE_LEARNING_ENABLED } from '../domain.constant';
|
||||||
import { IAssetJob, IBaseJob, IJobRepository, JobName } from '../job';
|
import { IAssetJob, IBaseJob, IJobRepository, JobName } from '../job';
|
||||||
import { IMachineLearningRepository } from './machine-learning.interface';
|
import { IMachineLearningRepository } from './machine-learning.interface';
|
||||||
import { ISmartInfoRepository } from './smart-info.repository';
|
import { ISmartInfoRepository } from './smart-info.repository';
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { MACHINE_LEARNING_URL } from '@app/common';
|
import { IMachineLearningRepository, MachineLearningInput, MACHINE_LEARNING_URL } from '@app/domain';
|
||||||
import { IMachineLearningRepository, MachineLearningInput } from '@app/domain';
|
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
|
@ -153,7 +153,6 @@
|
|||||||
"<rootDir>/libs/"
|
"<rootDir>/libs/"
|
||||||
],
|
],
|
||||||
"moduleNameMapper": {
|
"moduleNameMapper": {
|
||||||
"@app/common": "<rootDir>/libs/common/src",
|
|
||||||
"^@app/infra(|/.*)$": "<rootDir>/libs/infra/src/$1",
|
"^@app/infra(|/.*)$": "<rootDir>/libs/infra/src/$1",
|
||||||
"^@app/domain(|/.*)$": "<rootDir>/libs/domain/src/$1"
|
"^@app/domain(|/.*)$": "<rootDir>/libs/domain/src/$1"
|
||||||
},
|
},
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@app/common": ["libs/common/src"],
|
|
||||||
"@app/common/*": ["libs/common/src/*"],
|
|
||||||
"@app/infra": ["libs/infra/src"],
|
"@app/infra": ["libs/infra/src"],
|
||||||
"@app/infra/*": ["libs/infra/src/*"],
|
"@app/infra/*": ["libs/infra/src/*"],
|
||||||
"@app/domain": ["libs/domain/src"],
|
"@app/domain": ["libs/domain/src"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user