1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-10 13:56:47 +01:00
immich/server/src/services/system-config.service.ts

128 lines
4.4 KiB
TypeScript
Raw Normal View History

import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { instanceToPlain } from 'class-transformer';
import _ from 'lodash';
import { LogLevel, SystemConfig, defaults } from 'src/config';
import {
supportedDayTokens,
supportedHourTokens,
supportedMinuteTokens,
supportedMonthTokens,
supportedPresetTokens,
supportedSecondTokens,
supportedWeekTokens,
supportedYearTokens,
2024-03-21 04:15:09 +01:00
} from 'src/constants';
import { SystemConfigCore } from 'src/cores/system-config.core';
import { EventHandlerOptions, OnServerEvent } from 'src/decorators';
import { SystemConfigDto, SystemConfigTemplateStorageOptionDto, mapConfig } from 'src/dtos/system-config.dto';
import {
ClientEvent,
IEventRepository,
OnEvents,
ServerEvent,
SystemConfigUpdate,
} from 'src/interfaces/event.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
@Injectable()
export class SystemConfigService implements OnEvents {
private core: SystemConfigCore;
constructor(
@Inject(ISystemMetadataRepository) repository: ISystemMetadataRepository,
@Inject(IEventRepository) private eventRepository: IEventRepository,
@Inject(ILoggerRepository) private logger: ILoggerRepository,
) {
this.logger.setContext(SystemConfigService.name);
this.core = SystemConfigCore.create(repository, this.logger);
this.core.config$.subscribe((config) => this.setLogLevel(config));
}
@EventHandlerOptions({ priority: -100 })
async onBootstrapEvent() {
2024-06-12 13:07:35 +02:00
const config = await this.core.getConfig({ withCache: false });
this.config$.next(config);
}
get config$() {
return this.core.config$;
}
async getConfig(): Promise<SystemConfigDto> {
2024-06-12 13:07:35 +02:00
const config = await this.core.getConfig({ withCache: false });
return mapConfig(config);
}
getDefaults(): SystemConfigDto {
return mapConfig(defaults);
}
onConfigValidateEvent({ newConfig, oldConfig }: SystemConfigUpdate) {
if (!_.isEqual(instanceToPlain(newConfig.logging), oldConfig.logging) && this.getEnvLogLevel()) {
throw new Error('Logging cannot be changed while the environment variable IMMICH_LOG_LEVEL is set.');
}
}
async updateConfig(dto: SystemConfigDto): Promise<SystemConfigDto> {
if (this.core.isUsingConfigFile()) {
throw new BadRequestException('Cannot update configuration while IMMICH_CONFIG_FILE is in use');
}
2024-06-12 13:07:35 +02:00
const oldConfig = await this.core.getConfig({ withCache: false });
try {
await this.eventRepository.emit('onConfigValidateEvent', { newConfig: dto, oldConfig });
} catch (error) {
this.logger.warn(`Unable to save system config due to a validation error: ${error}`);
throw new BadRequestException(error instanceof Error ? error.message : error);
}
2023-12-08 17:15:46 +01:00
const newConfig = await this.core.updateConfig(dto);
// TODO probably move web socket emits to a separate service
this.eventRepository.clientBroadcast(ClientEvent.CONFIG_UPDATE, {});
this.eventRepository.serverSend(ServerEvent.CONFIG_UPDATE, null);
await this.eventRepository.emit('onConfigUpdateEvent', { newConfig, oldConfig });
2023-12-08 17:15:46 +01:00
return mapConfig(newConfig);
}
getStorageTemplateOptions(): SystemConfigTemplateStorageOptionDto {
const options = new SystemConfigTemplateStorageOptionDto();
options.dayOptions = supportedDayTokens;
options.weekOptions = supportedWeekTokens;
options.monthOptions = supportedMonthTokens;
options.yearOptions = supportedYearTokens;
options.hourOptions = supportedHourTokens;
options.secondOptions = supportedSecondTokens;
options.minuteOptions = supportedMinuteTokens;
options.presetOptions = supportedPresetTokens;
return options;
}
async getCustomCss(): Promise<string> {
2024-06-12 13:07:35 +02:00
const { theme } = await this.core.getConfig({ withCache: false });
return theme.customCss;
}
@OnServerEvent(ServerEvent.CONFIG_UPDATE)
async onConfigUpdateEvent() {
await this.core.refreshConfig();
}
private setLogLevel({ logging }: SystemConfig) {
const envLevel = this.getEnvLogLevel();
const configLevel = logging.enabled ? logging.level : false;
const level = envLevel ?? configLevel;
this.logger.setLogLevel(level);
this.logger.log(`LogLevel=${level} ${envLevel ? '(set via IMMICH_LOG_LEVEL)' : '(set via system config)'}`);
}
private getEnvLogLevel() {
return process.env.IMMICH_LOG_LEVEL as LogLevel;
}
}