mirror of
https://github.com/immich-app/immich.git
synced 2026-02-14 21:08:15 +03:00
feat: plugins
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
"email:dev": "email dev -p 3050 --dir src/emails"
|
||||
},
|
||||
"dependencies": {
|
||||
"@extism/extism": "2.0.0-rc13",
|
||||
"@nestjs/bullmq": "^11.0.1",
|
||||
"@nestjs/common": "^11.0.4",
|
||||
"@nestjs/core": "^11.0.4",
|
||||
|
||||
@@ -33,6 +33,11 @@ type Item<T extends EmitEvent> = {
|
||||
label: string;
|
||||
};
|
||||
|
||||
type AssetCreateV1 = {
|
||||
id: string;
|
||||
ownerId: string;
|
||||
};
|
||||
|
||||
type EventMap = {
|
||||
// app events
|
||||
AppBootstrap: [];
|
||||
@@ -53,6 +58,7 @@ type EventMap = {
|
||||
AlbumInvite: [{ id: string; userId: string }];
|
||||
|
||||
// asset events
|
||||
AssetCreate: [{ asset: AssetCreateV1 }];
|
||||
AssetTag: [{ assetId: string }];
|
||||
AssetUntag: [{ assetId: string }];
|
||||
AssetHide: [{ assetId: string; userId: string }];
|
||||
|
||||
@@ -426,6 +426,9 @@ export class AssetMediaService extends BaseService {
|
||||
}
|
||||
await this.storageRepository.utimes(file.originalPath, new Date(), new Date(dto.fileModifiedAt));
|
||||
await this.assetRepository.upsertExif({ assetId: asset.id, fileSizeInByte: file.size });
|
||||
|
||||
await this.eventRepository.emit('AssetCreate', { asset });
|
||||
|
||||
await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: { id: asset.id, source: 'upload' } });
|
||||
|
||||
return asset;
|
||||
|
||||
@@ -22,6 +22,7 @@ import { NotificationAdminService } from 'src/services/notification-admin.servic
|
||||
import { NotificationService } from 'src/services/notification.service';
|
||||
import { PartnerService } from 'src/services/partner.service';
|
||||
import { PersonService } from 'src/services/person.service';
|
||||
import { PluginService } from 'src/services/plugin.service';
|
||||
import { SearchService } from 'src/services/search.service';
|
||||
import { ServerService } from 'src/services/server.service';
|
||||
import { SessionService } from 'src/services/session.service';
|
||||
@@ -66,6 +67,7 @@ export const services = [
|
||||
NotificationAdminService,
|
||||
PartnerService,
|
||||
PersonService,
|
||||
PluginService,
|
||||
SearchService,
|
||||
ServerService,
|
||||
SessionService,
|
||||
|
||||
31
server/src/services/plugin.service.ts
Normal file
31
server/src/services/plugin.service.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { CurrentPlugin, newPlugin } from '@extism/extism';
|
||||
import { Updateable } from 'kysely';
|
||||
import { resolve } from 'node:path';
|
||||
import { OnEvent } from 'src/decorators';
|
||||
import { ArgOf } from 'src/repositories/event.repository';
|
||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||
import { BaseService } from 'src/services/base.service';
|
||||
|
||||
export class PluginService extends BaseService {
|
||||
@OnEvent({ name: 'AssetCreate' })
|
||||
async handleAssetCreate({ asset }: ArgOf<'AssetCreate'>) {
|
||||
console.log(`PluginService.handleAssetCreate: ${asset.id}`);
|
||||
const corePath = resolve('../plugins/dist/plugin.wasm');
|
||||
const plugin = await newPlugin(corePath, {
|
||||
useWasi: true,
|
||||
functions: {
|
||||
'extism:host/user': {
|
||||
updateAsset: (cp: CurrentPlugin, offs: bigint) => this.updateAsset(JSON.parse(cp.read(offs)!.text())),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const event = { asset };
|
||||
await plugin.call('archiveAssetAction', JSON.stringify(event));
|
||||
}
|
||||
|
||||
async updateAsset(asset: Updateable<AssetTable> & { id: string }) {
|
||||
console.log(`Updating asset ${asset.id} -- ${JSON.stringify({ ...asset, id: undefined })}`);
|
||||
await this.assetRepository.update(asset);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user