mirror of
https://github.com/immich-app/immich.git
synced 2025-12-26 09:14:58 +03:00
@@ -1,10 +1,45 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { GitHubRelease, IServerInfoRepository } from 'src/interfaces/server-info.interface';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { exiftool } from 'exiftool-vendored';
|
||||
import { exec as execCallback } from 'node:child_process';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { promisify } from 'node:util';
|
||||
import sharp from 'sharp';
|
||||
import { ILoggerRepository } from 'src/interfaces/logger.interface';
|
||||
import { GitHubRelease, IServerInfoRepository, ServerBuildVersions } from 'src/interfaces/server-info.interface';
|
||||
import { Instrumentation } from 'src/utils/instrumentation';
|
||||
|
||||
const exec = promisify(execCallback);
|
||||
const maybeFirstLine = async (command: string): Promise<string> => {
|
||||
try {
|
||||
const { stdout } = await exec(command);
|
||||
return stdout.trim().split('\n')[0] || '';
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
type BuildLockfile = {
|
||||
sources: Array<{ name: string; version: string }>;
|
||||
packages: Array<{ name: string; version: string }>;
|
||||
};
|
||||
|
||||
const getLockfileVersion = (name: string, lockfile?: BuildLockfile) => {
|
||||
if (!lockfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
const items = [...(lockfile.sources || []), ...(lockfile?.packages || [])];
|
||||
const item = items.find((item) => item.name === name);
|
||||
return item?.version;
|
||||
};
|
||||
|
||||
@Instrumentation()
|
||||
@Injectable()
|
||||
export class ServerInfoRepository implements IServerInfoRepository {
|
||||
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
|
||||
this.logger.setContext(ServerInfoRepository.name);
|
||||
}
|
||||
|
||||
async getGitHubRelease(): Promise<GitHubRelease> {
|
||||
try {
|
||||
const response = await fetch('https://api.github.com/repos/immich-app/immich/releases/latest');
|
||||
@@ -18,4 +53,25 @@ export class ServerInfoRepository implements IServerInfoRepository {
|
||||
throw new Error(`Failed to fetch GitHub release: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getBuildVersions(): Promise<ServerBuildVersions> {
|
||||
const [nodejsOutput, ffmpegOutput, magickOutput] = await Promise.all([
|
||||
maybeFirstLine('node --version'),
|
||||
maybeFirstLine('ffmpeg -version'),
|
||||
maybeFirstLine('convert --version'),
|
||||
]);
|
||||
|
||||
const lockfile = await readFile('build-lock.json')
|
||||
.then((buffer) => JSON.parse(buffer.toString()))
|
||||
.catch(() => this.logger.warn('Failed to read build-lock.json'));
|
||||
|
||||
return {
|
||||
nodejs: nodejsOutput || process.env.NODE_VERSION || '',
|
||||
exiftool: await exiftool.version(),
|
||||
ffmpeg: getLockfileVersion('ffmpeg', lockfile) || ffmpegOutput.replaceAll('ffmpeg version', '') || '',
|
||||
libvips: getLockfileVersion('libvips', lockfile) || sharp.versions.vips,
|
||||
imagemagick:
|
||||
getLockfileVersion('imagemagick', lockfile) || magickOutput.replaceAll('Version: ImageMagick ', '') || '',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user