66aeab282c
Build and Push Multi-Platform Images / build-and-push (push) Successful in 19s
This reverts commit 07dfd7e840.
280 lines
7.8 KiB
TypeScript
280 lines
7.8 KiB
TypeScript
import {
|
|
BadRequestException,
|
|
Body,
|
|
Controller,
|
|
Delete,
|
|
Get,
|
|
HttpCode,
|
|
Param,
|
|
ParseIntPipe,
|
|
Post,
|
|
Put,
|
|
Request,
|
|
Res,
|
|
StreamableFile,
|
|
} from '@nestjs/common';
|
|
import type { Response } from 'express';
|
|
import { createReadStream } from 'fs';
|
|
import { InboxService } from './inbox.service';
|
|
import { InboxPostprocessorService } from '../inbox-postprocessor/inbox-postprocessor.service';
|
|
import { BarcodeScannerService } from '../barcode/barcode-scanner.service';
|
|
import { UserSettingsService } from '../user-settings/user-settings.service';
|
|
import { RequirePermissions } from '../auth/permissions.decorator';
|
|
import { Permission } from '../auth/permissions.enum';
|
|
|
|
@Controller('api/inbox')
|
|
@RequirePermissions(Permission.VIEW_SCANNER)
|
|
export class InboxController {
|
|
constructor(
|
|
private readonly inboxService: InboxService,
|
|
private readonly postprocessor: InboxPostprocessorService,
|
|
private readonly barcodeScanner: BarcodeScannerService,
|
|
private readonly userSettingsService: UserSettingsService,
|
|
) {}
|
|
|
|
@Get()
|
|
async list(@Request() req: any) {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
return this.inboxService.listFiles(preferredUsername);
|
|
}
|
|
|
|
@Post('rescan')
|
|
async rescan() {
|
|
return this.barcodeScanner.rescanAll();
|
|
}
|
|
|
|
@Get(':id/preview')
|
|
async preview(
|
|
@Param('id') id: string,
|
|
@Request() req: any,
|
|
@Res({ passthrough: true }) res: Response,
|
|
): Promise<StreamableFile> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
const { doc, pdfPath } = await this.inboxService.resolveDocument(
|
|
id,
|
|
preferredUsername,
|
|
);
|
|
|
|
res.setHeader('Content-Type', 'application/pdf');
|
|
res.setHeader(
|
|
'Content-Disposition',
|
|
`inline; filename="${doc.OriginalName}"`,
|
|
);
|
|
return new StreamableFile(createReadStream(pdfPath));
|
|
}
|
|
|
|
@Get(':id/pages/:page/thumbnail')
|
|
async pageThumbnail(
|
|
@Param('id') id: string,
|
|
@Param('page', ParseIntPipe) page: number,
|
|
@Request() req: any,
|
|
@Res({ passthrough: true }) res: Response,
|
|
): Promise<StreamableFile> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
const filePath = await this.inboxService.resolvePageImage(
|
|
id,
|
|
page,
|
|
'thumbnail',
|
|
preferredUsername,
|
|
);
|
|
|
|
res.setHeader('Content-Type', 'image/png');
|
|
res.setHeader('Cache-Control', 'private, max-age=3600');
|
|
return new StreamableFile(createReadStream(filePath));
|
|
}
|
|
|
|
@Delete(':id')
|
|
@HttpCode(204)
|
|
async remove(@Param('id') id: string, @Request() req: any): Promise<void> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
await this.inboxService.deleteDocument(id, preferredUsername);
|
|
}
|
|
|
|
@Delete(':id/pages/:page')
|
|
@HttpCode(204)
|
|
async removePage(
|
|
@Param('id') id: string,
|
|
@Param('page', ParseIntPipe) page: number,
|
|
@Request() req: any,
|
|
): Promise<void> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
await this.inboxService.deletePage(id, page, preferredUsername);
|
|
}
|
|
|
|
@Post(':id/pages/:page/split')
|
|
@HttpCode(204)
|
|
async toggleManualSplit(
|
|
@Param('id') id: string,
|
|
@Param('page', ParseIntPipe) page: number,
|
|
@Request() req: any,
|
|
): Promise<void> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
await this.inboxService.toggleManualSplit(id, page, preferredUsername);
|
|
}
|
|
|
|
@Post(':id/reset-edits')
|
|
@HttpCode(204)
|
|
async resetEdits(
|
|
@Param('id') id: string,
|
|
@Request() req: any,
|
|
): Promise<void> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
await this.inboxService.resetEdits(id, preferredUsername);
|
|
}
|
|
|
|
@Post(':id/postprocess')
|
|
async postprocess(
|
|
@Param('id') id: string,
|
|
@Request() req: any,
|
|
@Body()
|
|
body: {
|
|
sectionOffset?: number;
|
|
processOnlyOne?: boolean;
|
|
replaceDuplicate?: boolean;
|
|
},
|
|
) {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
const { results, totalSections } = await this.postprocessor.runForDocument(
|
|
id,
|
|
preferredUsername,
|
|
body?.sectionOffset ?? 0,
|
|
body?.processOnlyOne ?? false,
|
|
body?.replaceDuplicate ?? false,
|
|
);
|
|
return { results, totalSections };
|
|
}
|
|
|
|
@Put(':id/pages/:page/rotation')
|
|
@HttpCode(204)
|
|
async setPageRotation(
|
|
@Param('id') id: string,
|
|
@Param('page', ParseIntPipe) page: number,
|
|
@Body() body: { rotation?: number },
|
|
@Request() req: any,
|
|
): Promise<void> {
|
|
const rotation = Number(body?.rotation);
|
|
if (!Number.isFinite(rotation)) {
|
|
throw new BadRequestException('rotation muss eine Zahl sein');
|
|
}
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
await this.inboxService.setPageRotation(
|
|
id,
|
|
page,
|
|
rotation,
|
|
preferredUsername,
|
|
);
|
|
}
|
|
|
|
@Get(':id/pages/:page/preview')
|
|
async pagePreview(
|
|
@Param('id') id: string,
|
|
@Param('page', ParseIntPipe) page: number,
|
|
@Request() req: any,
|
|
@Res({ passthrough: true }) res: Response,
|
|
): Promise<StreamableFile> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
const filePath = await this.inboxService.resolvePageImage(
|
|
id,
|
|
page,
|
|
'preview',
|
|
preferredUsername,
|
|
);
|
|
|
|
res.setHeader('Content-Type', 'image/png');
|
|
res.setHeader('Cache-Control', 'private, max-age=3600');
|
|
return new StreamableFile(createReadStream(filePath));
|
|
}
|
|
|
|
@Post(':id/pages/:page/scan-region')
|
|
async scanRegion(
|
|
@Param('id') id: string,
|
|
@Param('page', ParseIntPipe) page: number,
|
|
@Body() body: { x: number; y: number; w: number; h: number },
|
|
@Request() req: any,
|
|
): Promise<{ found: string[] }> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
return this.inboxService.scanRegion(
|
|
id,
|
|
page,
|
|
body.x,
|
|
body.y,
|
|
body.w,
|
|
body.h,
|
|
preferredUsername,
|
|
);
|
|
}
|
|
|
|
@Post(':id/source')
|
|
@HttpCode(204)
|
|
async updateSource(
|
|
@Param('id') id: string,
|
|
@Body() body: { source: any },
|
|
@Request() req: any,
|
|
): Promise<void> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
await this.inboxService.updateSource(id, body.source, preferredUsername);
|
|
}
|
|
|
|
@Post(':id/download-segment')
|
|
async downloadSegment(
|
|
@Param('id') id: string,
|
|
@Body() body: { pages: number[] },
|
|
@Request() req: any,
|
|
@Res({ passthrough: true }) res: Response,
|
|
): Promise<StreamableFile> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
const { buffer, filename } = await this.inboxService.getSegmentPdfBuffer(
|
|
id,
|
|
preferredUsername,
|
|
body.pages ?? [],
|
|
);
|
|
const { Readable } = await import('stream');
|
|
res.setHeader('Content-Type', 'application/pdf');
|
|
res.setHeader(
|
|
'Content-Disposition',
|
|
`attachment; filename="${encodeURIComponent(filename)}"`,
|
|
);
|
|
return new StreamableFile(Readable.from(buffer));
|
|
}
|
|
|
|
@Post(':id/send-email')
|
|
@HttpCode(204)
|
|
async sendEmail(
|
|
@Param('id') id: string,
|
|
@Body()
|
|
body: {
|
|
to: string;
|
|
subject: string;
|
|
body: string;
|
|
html?: string;
|
|
segments: { pages: number[]; filename: string }[];
|
|
sender?: string;
|
|
},
|
|
@Request() req: any,
|
|
): Promise<void> {
|
|
const preferredUsername: string | null =
|
|
req.user?.preferredUsername ?? null;
|
|
const smtpOverride =
|
|
body.sender === 'user'
|
|
? await this.userSettingsService.getSmtpConfig(req.user.userId)
|
|
: null;
|
|
await this.inboxService.sendAsEmail(id, preferredUsername, {
|
|
...body,
|
|
smtpOverride: smtpOverride ?? undefined,
|
|
});
|
|
}
|
|
}
|