Add flatten option to the chromium convert route

This commit is contained in:
Peter Chakalov
2025-01-27 13:45:04 +02:00
parent 4bad2f8861
commit cdab8b4e6b
2 changed files with 43 additions and 7 deletions

View File

@@ -330,15 +330,19 @@ func convertUrlRoute(chromium Api, engine gotenberg.PdfEngine) api.Route {
pdfFormats := pdfengines.FormDataPdfFormats(form) pdfFormats := pdfengines.FormDataPdfFormats(form)
metadata := pdfengines.FormDataPdfMetadata(form, false) metadata := pdfengines.FormDataPdfMetadata(form, false)
var url string var (
url string
flatten bool
)
err := form. err := form.
MandatoryString("url", &url). MandatoryString("url", &url).
Bool("flatten", &flatten, false).
Validate() Validate()
if err != nil { if err != nil {
return fmt.Errorf("validate form data: %w", err) return fmt.Errorf("validate form data: %w", err)
} }
err = convertUrl(ctx, chromium, engine, url, options, mode, pdfFormats, metadata) err = convertUrl(ctx, chromium, engine, url, options, mode, pdfFormats, metadata, flatten)
if err != nil { if err != nil {
return fmt.Errorf("convert URL to PDF: %w", err) return fmt.Errorf("convert URL to PDF: %w", err)
} }
@@ -391,16 +395,20 @@ func convertHtmlRoute(chromium Api, engine gotenberg.PdfEngine) api.Route {
pdfFormats := pdfengines.FormDataPdfFormats(form) pdfFormats := pdfengines.FormDataPdfFormats(form)
metadata := pdfengines.FormDataPdfMetadata(form, false) metadata := pdfengines.FormDataPdfMetadata(form, false)
var inputPath string var (
inputPath string
flatten bool
)
err := form. err := form.
MandatoryPath("index.html", &inputPath). MandatoryPath("index.html", &inputPath).
Bool("flatten", &flatten, false).
Validate() Validate()
if err != nil { if err != nil {
return fmt.Errorf("validate form data: %w", err) return fmt.Errorf("validate form data: %w", err)
} }
url := fmt.Sprintf("file://%s", inputPath) url := fmt.Sprintf("file://%s", inputPath)
err = convertUrl(ctx, chromium, engine, url, options, mode, pdfFormats, metadata) err = convertUrl(ctx, chromium, engine, url, options, mode, pdfFormats, metadata, flatten)
if err != nil { if err != nil {
return fmt.Errorf("convert HTML to PDF: %w", err) return fmt.Errorf("convert HTML to PDF: %w", err)
} }
@@ -457,11 +465,13 @@ func convertMarkdownRoute(chromium Api, engine gotenberg.PdfEngine) api.Route {
var ( var (
inputPath string inputPath string
markdownPaths []string markdownPaths []string
flatten bool
) )
err := form. err := form.
MandatoryPath("index.html", &inputPath). MandatoryPath("index.html", &inputPath).
MandatoryPaths([]string{".md"}, &markdownPaths). MandatoryPaths([]string{".md"}, &markdownPaths).
Bool("flatten", &flatten, false).
Validate() Validate()
if err != nil { if err != nil {
return fmt.Errorf("validate form data: %w", err) return fmt.Errorf("validate form data: %w", err)
@@ -472,7 +482,7 @@ func convertMarkdownRoute(chromium Api, engine gotenberg.PdfEngine) api.Route {
return fmt.Errorf("transform markdown file(s) to HTML: %w", err) return fmt.Errorf("transform markdown file(s) to HTML: %w", err)
} }
err = convertUrl(ctx, chromium, engine, url, options, mode, pdfFormats, metadata) err = convertUrl(ctx, chromium, engine, url, options, mode, pdfFormats, metadata, flatten)
if err != nil { if err != nil {
return fmt.Errorf("convert markdown to PDF: %w", err) return fmt.Errorf("convert markdown to PDF: %w", err)
} }
@@ -596,7 +606,7 @@ func markdownToHtml(ctx *api.Context, inputPath string, markdownPaths []string)
return fmt.Sprintf("file://%s", inputPath), nil return fmt.Sprintf("file://%s", inputPath), nil
} }
func convertUrl(ctx *api.Context, chromium Api, engine gotenberg.PdfEngine, url string, options PdfOptions, mode gotenberg.SplitMode, pdfFormats gotenberg.PdfFormats, metadata map[string]interface{}) error { func convertUrl(ctx *api.Context, chromium Api, engine gotenberg.PdfEngine, url string, options PdfOptions, mode gotenberg.SplitMode, pdfFormats gotenberg.PdfFormats, metadata map[string]interface{}, flatten bool) error {
outputPath := ctx.GeneratePath(".pdf") outputPath := ctx.GeneratePath(".pdf")
err := chromium.Pdf(ctx, ctx.Log(), url, outputPath, options) err := chromium.Pdf(ctx, ctx.Log(), url, outputPath, options)
@@ -650,6 +660,13 @@ func convertUrl(ctx *api.Context, chromium Api, engine gotenberg.PdfEngine, url
return fmt.Errorf("write metadata: %w", err) return fmt.Errorf("write metadata: %w", err)
} }
if flatten {
convertOutputPaths, err = pdfengines.FlattenStub(ctx, engine, outputPaths)
if err != nil {
return fmt.Errorf("flatten PDFs: %w", err)
}
}
zeroValuedSplitMode := gotenberg.SplitMode{} zeroValuedSplitMode := gotenberg.SplitMode{}
zeroValuedPdfFormats := gotenberg.PdfFormats{} zeroValuedPdfFormats := gotenberg.PdfFormats{}
if mode != zeroValuedSplitMode && pdfFormats != zeroValuedPdfFormats { if mode != zeroValuedSplitMode && pdfFormats != zeroValuedPdfFormats {

View File

@@ -1431,6 +1431,7 @@ func TestConvertUrl(t *testing.T) {
splitMode gotenberg.SplitMode splitMode gotenberg.SplitMode
pdfFormats gotenberg.PdfFormats pdfFormats gotenberg.PdfFormats
metadata map[string]interface{} metadata map[string]interface{}
flatten bool
expectError bool expectError bool
expectHttpError bool expectHttpError bool
expectHttpStatus int expectHttpStatus int
@@ -1669,6 +1670,20 @@ func TestConvertUrl(t *testing.T) {
expectError: true, expectError: true,
expectHttpError: false, expectHttpError: false,
}, },
{
scenario: "PDF engine flatten error",
ctx: &api.ContextMock{Context: new(api.Context)},
api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error {
return nil
}},
engine: &gotenberg.PdfEngineMock{FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
return errors.New("bar")
}},
options: DefaultPdfOptions(),
flatten: true,
expectError: true,
expectHttpError: false,
},
{ {
scenario: "cannot add output paths", scenario: "cannot add output paths",
ctx: func() *api.ContextMock { ctx: func() *api.ContextMock {
@@ -1697,6 +1712,9 @@ func TestConvertUrl(t *testing.T) {
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
return nil return nil
}, },
FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
return nil
},
}, },
options: DefaultPdfOptions(), options: DefaultPdfOptions(),
pdfFormats: gotenberg.PdfFormats{PdfA: gotenberg.PdfA1b}, pdfFormats: gotenberg.PdfFormats{PdfA: gotenberg.PdfA1b},
@@ -1704,6 +1722,7 @@ func TestConvertUrl(t *testing.T) {
"Creator": "foo", "Creator": "foo",
"Producer": "bar", "Producer": "bar",
}, },
flatten: true,
expectError: false, expectError: false,
expectHttpError: false, expectHttpError: false,
expectOutputPathsCount: 1, expectOutputPathsCount: 1,
@@ -1717,7 +1736,7 @@ func TestConvertUrl(t *testing.T) {
tc.ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { tc.ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error {
return nil return nil
}}) }})
err := convertUrl(tc.ctx.Context, tc.api, tc.engine, "", tc.options, tc.splitMode, tc.pdfFormats, tc.metadata) err := convertUrl(tc.ctx.Context, tc.api, tc.engine, "", tc.options, tc.splitMode, tc.pdfFormats, tc.metadata, tc.flatten)
if tc.expectError && err == nil { if tc.expectError && err == nil {
t.Fatal("expected error but got none", err) t.Fatal("expected error but got none", err)