diff --git a/pkg/modules/libreoffice/routes.go b/pkg/modules/libreoffice/routes.go index b6786189..6d470bc1 100644 --- a/pkg/modules/libreoffice/routes.go +++ b/pkg/modules/libreoffice/routes.go @@ -60,6 +60,7 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap maxImageResolution int nativePdfFormats bool merge bool + flatten bool ) err := form. @@ -135,6 +136,7 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap } return nil }). + Bool("flatten", &flatten, false). Validate() if err != nil { return fmt.Errorf("validate form data: %w", err) @@ -261,6 +263,13 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap return fmt.Errorf("write metadata: %w", err) } + if flatten { + outputPaths, err = pdfengines.FlattenStub(ctx, engine, outputPaths) + if err != nil { + return fmt.Errorf("flatten PDFs: %w", err) + } + } + if len(outputPaths) > 1 && splitMode == zeroValuedSplitMode { // If .zip archive, document.docx -> document.docx.pdf. for i, inputPath := range inputPaths { diff --git a/pkg/modules/libreoffice/routes_test.go b/pkg/modules/libreoffice/routes_test.go index 139f5748..5cfd5bfd 100644 --- a/pkg/modules/libreoffice/routes_test.go +++ b/pkg/modules/libreoffice/routes_test.go @@ -402,6 +402,38 @@ func TestConvertRoute(t *testing.T) { expectHttpError: false, expectOutputPathsCount: 0, }, + { + scenario: "PDF engine flatten error", + ctx: func() *api.ContextMock { + ctx := &api.ContextMock{Context: new(api.Context)} + ctx.SetFiles(map[string]string{ + "document.docx": "/document.docx", + }) + ctx.SetValues(map[string][]string{ + "flatten": { + "true", + }, + }) + ctx.SetCancelled(true) + return ctx + }(), + libreOffice: &libreofficeapi.ApiMock{ + PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { + return nil + }, + ExtensionsMock: func() []string { + return []string{".docx"} + }, + }, + engine: &gotenberg.PdfEngineMock{ + FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error { + return errors.New("foo") + }, + }, + expectError: true, + expectHttpError: false, + expectOutputPathsCount: 0, + }, { scenario: "cannot add output paths", ctx: func() *api.ContextMock { @@ -454,6 +486,9 @@ func TestConvertRoute(t *testing.T) { "metadata": { "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", }, + "flatten": { + "true", + }, }) return ctx }(), @@ -475,6 +510,9 @@ func TestConvertRoute(t *testing.T) { WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { return nil }, + FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error { + return nil + }, }, expectError: false, expectHttpError: false, @@ -502,6 +540,9 @@ func TestConvertRoute(t *testing.T) { "metadata": { "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", }, + "flatten": { + "true", + }, }) ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { return nil @@ -526,6 +567,9 @@ func TestConvertRoute(t *testing.T) { WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { return nil }, + FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error { + return nil + }, }, expectError: false, expectHttpError: false,