mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-18 05:02:15 +01:00
initial changes
This commit is contained in:
2
Makefile
2
Makefile
@@ -74,6 +74,7 @@ LOG_FIELDS_PREFIX=
|
|||||||
PDFENGINES_ENGINES=
|
PDFENGINES_ENGINES=
|
||||||
PDFENGINES_MERGE_ENGINES=qpdf,pdfcpu,pdftk
|
PDFENGINES_MERGE_ENGINES=qpdf,pdfcpu,pdftk
|
||||||
PDFENGINES_SPLIT_ENGINES=pdfcpu,qpdf,pdftk
|
PDFENGINES_SPLIT_ENGINES=pdfcpu,qpdf,pdftk
|
||||||
|
PDFENGINES_FLATTEN_ENGINES=qpdf
|
||||||
PDFENGINES_CONVERT_ENGINES=libreoffice-pdfengine
|
PDFENGINES_CONVERT_ENGINES=libreoffice-pdfengine
|
||||||
PDFENGINES_READ_METADATA_ENGINES=exiftool
|
PDFENGINES_READ_METADATA_ENGINES=exiftool
|
||||||
PDFENGINES_WRITE_METADATA_ENGINES=exiftool
|
PDFENGINES_WRITE_METADATA_ENGINES=exiftool
|
||||||
@@ -143,6 +144,7 @@ run: ## Start a Gotenberg container
|
|||||||
--pdfengines-engines=$(PDFENGINES_ENGINES) \
|
--pdfengines-engines=$(PDFENGINES_ENGINES) \
|
||||||
--pdfengines-merge-engines=$(PDFENGINES_MERGE_ENGINES) \
|
--pdfengines-merge-engines=$(PDFENGINES_MERGE_ENGINES) \
|
||||||
--pdfengines-split-engines=$(PDFENGINES_SPLIT_ENGINES) \
|
--pdfengines-split-engines=$(PDFENGINES_SPLIT_ENGINES) \
|
||||||
|
--pdfengines-convert-engines=$(PDFENGINES_FLATTEN_ENGINES) \
|
||||||
--pdfengines-convert-engines=$(PDFENGINES_CONVERT_ENGINES) \
|
--pdfengines-convert-engines=$(PDFENGINES_CONVERT_ENGINES) \
|
||||||
--pdfengines-read-metadata-engines=$(PDFENGINES_READ_METADATA_ENGINES) \
|
--pdfengines-read-metadata-engines=$(PDFENGINES_READ_METADATA_ENGINES) \
|
||||||
--pdfengines-write-metadata-engines=$(PDFENGINES_WRITE_METADATA_ENGINES) \
|
--pdfengines-write-metadata-engines=$(PDFENGINES_WRITE_METADATA_ENGINES) \
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ func (mod *ValidatorMock) Validate() error {
|
|||||||
type PdfEngineMock struct {
|
type PdfEngineMock struct {
|
||||||
MergeMock func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error
|
MergeMock func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error
|
||||||
SplitMock func(ctx context.Context, logger *zap.Logger, mode SplitMode, inputPath, outputDirPath string) ([]string, error)
|
SplitMock func(ctx context.Context, logger *zap.Logger, mode SplitMode, inputPath, outputDirPath string) ([]string, error)
|
||||||
|
FlattenMock func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error
|
||||||
ConvertMock func(ctx context.Context, logger *zap.Logger, formats PdfFormats, inputPath, outputPath string) error
|
ConvertMock func(ctx context.Context, logger *zap.Logger, formats PdfFormats, inputPath, outputPath string) error
|
||||||
ReadMetadataMock func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error)
|
ReadMetadataMock func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error)
|
||||||
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
|
||||||
@@ -51,6 +52,10 @@ func (engine *PdfEngineMock) Split(ctx context.Context, logger *zap.Logger, mode
|
|||||||
return engine.SplitMock(ctx, logger, mode, inputPath, outputDirPath)
|
return engine.SplitMock(ctx, logger, mode, inputPath, outputDirPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (engine *PdfEngineMock) Flatten(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
|
||||||
|
return engine.FlattenMock(ctx, logger, inputPath, outputPath)
|
||||||
|
}
|
||||||
|
|
||||||
func (engine *PdfEngineMock) Convert(ctx context.Context, logger *zap.Logger, formats PdfFormats, inputPath, outputPath string) error {
|
func (engine *PdfEngineMock) Convert(ctx context.Context, logger *zap.Logger, formats PdfFormats, inputPath, outputPath string) error {
|
||||||
return engine.ConvertMock(ctx, logger, formats, inputPath, outputPath)
|
return engine.ConvertMock(ctx, logger, formats, inputPath, outputPath)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,10 @@ type PdfEngine interface {
|
|||||||
// Split splits a given PDF file.
|
// Split splits a given PDF file.
|
||||||
Split(ctx context.Context, logger *zap.Logger, mode SplitMode, inputPath, outputDirPath string) ([]string, error)
|
Split(ctx context.Context, logger *zap.Logger, mode SplitMode, inputPath, outputDirPath string) ([]string, error)
|
||||||
|
|
||||||
|
// Flatten PDF refers to merging the annotations (such as markup, widgets, 3D models, etc.) into a static area that is part of the PDF document
|
||||||
|
// By flattening and merging existing annotation appearances with page content, the original annotations are deleted from the PDF pages.
|
||||||
|
Flatten(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error
|
||||||
|
|
||||||
// Convert transforms a given PDF to the specified formats defined in
|
// Convert transforms a given PDF to the specified formats defined in
|
||||||
// PdfFormats. If no format, it does nothing.
|
// PdfFormats. If no format, it does nothing.
|
||||||
Convert(ctx context.Context, logger *zap.Logger, formats PdfFormats, inputPath, outputPath string) error
|
Convert(ctx context.Context, logger *zap.Logger, formats PdfFormats, inputPath, outputPath string) error
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ func (engine *ExifTool) Split(ctx context.Context, logger *zap.Logger, mode gote
|
|||||||
return nil, fmt.Errorf("split PDF with ExifTool: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return nil, fmt.Errorf("split PDF with ExifTool: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flatten is not available in this implementation.
|
||||||
|
func (engine *ExifTool) Flatten(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
|
||||||
|
return fmt.Errorf("flatten PDF with ExifTool: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert is not available in this implementation.
|
// Convert is not available in this implementation.
|
||||||
func (engine *ExifTool) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
func (engine *ExifTool) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
return fmt.Errorf("convert PDF to '%+v' with ExifTool: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
|
return fmt.Errorf("convert PDF to '%+v' with ExifTool: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ func (engine *LibreOfficePdfEngine) Split(ctx context.Context, logger *zap.Logge
|
|||||||
return nil, fmt.Errorf("split PDF with LibreOffice: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return nil, fmt.Errorf("split PDF with LibreOffice: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flatten is not available in this implementation.
|
||||||
|
func (engine *LibreOfficePdfEngine) Flatten(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
|
||||||
|
return fmt.Errorf("Flatten PDF with LibreOffice: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert converts the given PDF to a specific PDF format. Currently, only the
|
// Convert converts the given PDF to a specific PDF format. Currently, only the
|
||||||
// PDF/A-1b, PDF/A-2b, PDF/A-3b and PDF/UA formats are available. If another
|
// PDF/A-1b, PDF/A-2b, PDF/A-3b and PDF/UA formats are available. If another
|
||||||
// PDF format is requested, it returns a [gotenberg.ErrPdfFormatNotSupported]
|
// PDF format is requested, it returns a [gotenberg.ErrPdfFormatNotSupported]
|
||||||
|
|||||||
@@ -107,6 +107,11 @@ func (engine *PdfCpu) Split(ctx context.Context, logger *zap.Logger, mode gotenb
|
|||||||
return outputPaths, nil
|
return outputPaths, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flatten is not available in this implementation.
|
||||||
|
func (engine *PdfCpu) Flatten(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
|
||||||
|
return fmt.Errorf("flatten PDF with pdfcpu: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert is not available in this implementation.
|
// Convert is not available in this implementation.
|
||||||
func (engine *PdfCpu) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
func (engine *PdfCpu) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
return fmt.Errorf("convert PDF to '%+v' with pdfcpu: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
|
return fmt.Errorf("convert PDF to '%+v' with pdfcpu: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
type multiPdfEngines struct {
|
type multiPdfEngines struct {
|
||||||
mergeEngines []gotenberg.PdfEngine
|
mergeEngines []gotenberg.PdfEngine
|
||||||
splitEngines []gotenberg.PdfEngine
|
splitEngines []gotenberg.PdfEngine
|
||||||
|
flattenEngines []gotenberg.PdfEngine
|
||||||
convertEngines []gotenberg.PdfEngine
|
convertEngines []gotenberg.PdfEngine
|
||||||
readMetadataEngines []gotenberg.PdfEngine
|
readMetadataEngines []gotenberg.PdfEngine
|
||||||
writeMetadataEngines []gotenberg.PdfEngine
|
writeMetadataEngines []gotenberg.PdfEngine
|
||||||
@@ -22,6 +23,7 @@ type multiPdfEngines struct {
|
|||||||
func newMultiPdfEngines(
|
func newMultiPdfEngines(
|
||||||
mergeEngines,
|
mergeEngines,
|
||||||
splitEngines,
|
splitEngines,
|
||||||
|
flattenEngines,
|
||||||
convertEngines,
|
convertEngines,
|
||||||
readMetadataEngines,
|
readMetadataEngines,
|
||||||
writeMetadataEngines []gotenberg.PdfEngine,
|
writeMetadataEngines []gotenberg.PdfEngine,
|
||||||
@@ -29,6 +31,7 @@ func newMultiPdfEngines(
|
|||||||
return &multiPdfEngines{
|
return &multiPdfEngines{
|
||||||
mergeEngines: mergeEngines,
|
mergeEngines: mergeEngines,
|
||||||
splitEngines: splitEngines,
|
splitEngines: splitEngines,
|
||||||
|
flattenEngines: flattenEngines,
|
||||||
convertEngines: convertEngines,
|
convertEngines: convertEngines,
|
||||||
readMetadataEngines: readMetadataEngines,
|
readMetadataEngines: readMetadataEngines,
|
||||||
writeMetadataEngines: writeMetadataEngines,
|
writeMetadataEngines: writeMetadataEngines,
|
||||||
@@ -98,6 +101,29 @@ func (multi *multiPdfEngines) Split(ctx context.Context, logger *zap.Logger, mod
|
|||||||
return nil, fmt.Errorf("split PDF with multi PDF engines: %w", err)
|
return nil, fmt.Errorf("split PDF with multi PDF engines: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (multi *multiPdfEngines) Flatten(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
|
||||||
|
var err error
|
||||||
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
|
for _, engine := range multi.flattenEngines {
|
||||||
|
go func(engine gotenberg.PdfEngine) {
|
||||||
|
errChan <- engine.Flatten(ctx, logger, inputPath, outputPath)
|
||||||
|
}(engine)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case mergeErr := <-errChan:
|
||||||
|
errored := multierr.AppendInto(&err, mergeErr)
|
||||||
|
if !errored {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("flatten PDF with multi PDF engines: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert converts the given PDF to a specific PDF format. thanks to its
|
// Convert converts the given PDF to a specific PDF format. thanks to its
|
||||||
// children. If the context is done, it stops and returns an error.
|
// children. If the context is done, it stops and returns an error.
|
||||||
func (multi *multiPdfEngines) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
func (multi *multiPdfEngines) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ func init() {
|
|||||||
type PdfEngines struct {
|
type PdfEngines struct {
|
||||||
mergeNames []string
|
mergeNames []string
|
||||||
splitNames []string
|
splitNames []string
|
||||||
|
flattenNames []string
|
||||||
convertNames []string
|
convertNames []string
|
||||||
readMetadataNames []string
|
readMetadataNames []string
|
||||||
writeMetadataNames []string
|
writeMetadataNames []string
|
||||||
@@ -44,6 +45,7 @@ func (mod *PdfEngines) Descriptor() gotenberg.ModuleDescriptor {
|
|||||||
fs := flag.NewFlagSet("pdfengines", flag.ExitOnError)
|
fs := flag.NewFlagSet("pdfengines", flag.ExitOnError)
|
||||||
fs.StringSlice("pdfengines-merge-engines", []string{"qpdf", "pdfcpu", "pdftk"}, "Set the PDF engines and their order for the merge feature - empty means all")
|
fs.StringSlice("pdfengines-merge-engines", []string{"qpdf", "pdfcpu", "pdftk"}, "Set the PDF engines and their order for the merge feature - empty means all")
|
||||||
fs.StringSlice("pdfengines-split-engines", []string{"pdfcpu", "qpdf", "pdftk"}, "Set the PDF engines and their order for the split feature - empty means all")
|
fs.StringSlice("pdfengines-split-engines", []string{"pdfcpu", "qpdf", "pdftk"}, "Set the PDF engines and their order for the split feature - empty means all")
|
||||||
|
fs.StringSlice("pdfengines-flatten-engines", []string{"qpdf"}, "Set the PDF engines and their order for the flatten feature - empty means all")
|
||||||
fs.StringSlice("pdfengines-convert-engines", []string{"libreoffice-pdfengine"}, "Set the PDF engines and their order for the convert feature - empty means all")
|
fs.StringSlice("pdfengines-convert-engines", []string{"libreoffice-pdfengine"}, "Set the PDF engines and their order for the convert feature - empty means all")
|
||||||
fs.StringSlice("pdfengines-read-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the read metadata feature - empty means all")
|
fs.StringSlice("pdfengines-read-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the read metadata feature - empty means all")
|
||||||
fs.StringSlice("pdfengines-write-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the write metadata feature - empty means all")
|
fs.StringSlice("pdfengines-write-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the write metadata feature - empty means all")
|
||||||
@@ -67,6 +69,7 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
|
|||||||
flags := ctx.ParsedFlags()
|
flags := ctx.ParsedFlags()
|
||||||
mergeNames := flags.MustStringSlice("pdfengines-merge-engines")
|
mergeNames := flags.MustStringSlice("pdfengines-merge-engines")
|
||||||
splitNames := flags.MustStringSlice("pdfengines-split-engines")
|
splitNames := flags.MustStringSlice("pdfengines-split-engines")
|
||||||
|
flattenNames := flags.MustStringSlice("pdfengines-flatten-engines")
|
||||||
convertNames := flags.MustStringSlice("pdfengines-convert-engines")
|
convertNames := flags.MustStringSlice("pdfengines-convert-engines")
|
||||||
readMetadataNames := flags.MustStringSlice("pdfengines-read-metadata-engines")
|
readMetadataNames := flags.MustStringSlice("pdfengines-read-metadata-engines")
|
||||||
writeMetadataNames := flags.MustStringSlice("pdfengines-write-metadata-engines")
|
writeMetadataNames := flags.MustStringSlice("pdfengines-write-metadata-engines")
|
||||||
@@ -106,6 +109,10 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
|
|||||||
mod.splitNames = splitNames
|
mod.splitNames = splitNames
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(flattenNames) > 0 {
|
||||||
|
mod.flattenNames = flattenNames
|
||||||
|
}
|
||||||
|
|
||||||
mod.convertNames = defaultNames
|
mod.convertNames = defaultNames
|
||||||
if len(convertNames) > 0 {
|
if len(convertNames) > 0 {
|
||||||
mod.convertNames = convertNames
|
mod.convertNames = convertNames
|
||||||
@@ -212,6 +219,7 @@ func (mod *PdfEngines) PdfEngine() (gotenberg.PdfEngine, error) {
|
|||||||
return newMultiPdfEngines(
|
return newMultiPdfEngines(
|
||||||
engines(mod.mergeNames),
|
engines(mod.mergeNames),
|
||||||
engines(mod.splitNames),
|
engines(mod.splitNames),
|
||||||
|
engines(mod.flattenNames),
|
||||||
engines(mod.convertNames),
|
engines(mod.convertNames),
|
||||||
engines(mod.readMetadataNames),
|
engines(mod.readMetadataNames),
|
||||||
engines(mod.writeMetadataNames),
|
engines(mod.writeMetadataNames),
|
||||||
@@ -234,6 +242,7 @@ func (mod *PdfEngines) Routes() ([]api.Route, error) {
|
|||||||
return []api.Route{
|
return []api.Route{
|
||||||
mergeRoute(engine),
|
mergeRoute(engine),
|
||||||
splitRoute(engine),
|
splitRoute(engine),
|
||||||
|
flattenRoute(engine),
|
||||||
convertRoute(engine),
|
convertRoute(engine),
|
||||||
readMetadataRoute(engine),
|
readMetadataRoute(engine),
|
||||||
writeMetadataRoute(engine),
|
writeMetadataRoute(engine),
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
ctx *gotenberg.Context
|
ctx *gotenberg.Context
|
||||||
expectedMergePdfEngines []string
|
expectedMergePdfEngines []string
|
||||||
expectedSplitPdfEngines []string
|
expectedSplitPdfEngines []string
|
||||||
|
expectedFlattenPdfEngines []string
|
||||||
expectedConvertPdfEngines []string
|
expectedConvertPdfEngines []string
|
||||||
expectedReadMetadataPdfEngines []string
|
expectedReadMetadataPdfEngines []string
|
||||||
expectedWriteMetadataPdfEngines []string
|
expectedWriteMetadataPdfEngines []string
|
||||||
@@ -68,6 +69,7 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
expectedMergePdfEngines: []string{"qpdf", "pdfcpu", "pdftk"},
|
expectedMergePdfEngines: []string{"qpdf", "pdfcpu", "pdftk"},
|
||||||
expectedSplitPdfEngines: []string{"pdfcpu", "qpdf", "pdftk"},
|
expectedSplitPdfEngines: []string{"pdfcpu", "qpdf", "pdftk"},
|
||||||
|
expectedFlattenPdfEngines: []string{"qpdf"},
|
||||||
expectedConvertPdfEngines: []string{"libreoffice-pdfengine"},
|
expectedConvertPdfEngines: []string{"libreoffice-pdfengine"},
|
||||||
expectedReadMetadataPdfEngines: []string{"exiftool"},
|
expectedReadMetadataPdfEngines: []string{"exiftool"},
|
||||||
expectedWriteMetadataPdfEngines: []string{"exiftool"},
|
expectedWriteMetadataPdfEngines: []string{"exiftool"},
|
||||||
@@ -109,7 +111,7 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs := new(PdfEngines).Descriptor().FlagSet
|
fs := new(PdfEngines).Descriptor().FlagSet
|
||||||
err := fs.Parse([]string{"--pdfengines-merge-engines=b", "--pdfengines-split-engines=a", "--pdfengines-convert-engines=b", "--pdfengines-read-metadata-engines=a", "--pdfengines-write-metadata-engines=a"})
|
err := fs.Parse([]string{"--pdfengines-merge-engines=b", "--pdfengines-split-engines=a", "--pdfengines-flatten-engines=c", "--pdfengines-convert-engines=b", "--pdfengines-read-metadata-engines=a", "--pdfengines-write-metadata-engines=a"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected no error but got: %v", err)
|
t.Fatalf("expected no error but got: %v", err)
|
||||||
}
|
}
|
||||||
@@ -128,6 +130,7 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
|
|
||||||
expectedMergePdfEngines: []string{"b"},
|
expectedMergePdfEngines: []string{"b"},
|
||||||
expectedSplitPdfEngines: []string{"a"},
|
expectedSplitPdfEngines: []string{"a"},
|
||||||
|
expectedFlattenPdfEngines: []string{"c"},
|
||||||
expectedConvertPdfEngines: []string{"b"},
|
expectedConvertPdfEngines: []string{"b"},
|
||||||
expectedReadMetadataPdfEngines: []string{"a"},
|
expectedReadMetadataPdfEngines: []string{"a"},
|
||||||
expectedWriteMetadataPdfEngines: []string{"a"},
|
expectedWriteMetadataPdfEngines: []string{"a"},
|
||||||
@@ -185,6 +188,10 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
t.Fatalf("expected %d merge names but got %d", len(tc.expectedMergePdfEngines), len(mod.mergeNames))
|
t.Fatalf("expected %d merge names but got %d", len(tc.expectedMergePdfEngines), len(mod.mergeNames))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(tc.expectedFlattenPdfEngines) != len(mod.flattenNames) {
|
||||||
|
t.Fatalf("expected %d flatten names but got %d", len(tc.expectedFlattenPdfEngines), len(mod.flattenNames))
|
||||||
|
}
|
||||||
|
|
||||||
if len(tc.expectedConvertPdfEngines) != len(mod.convertNames) {
|
if len(tc.expectedConvertPdfEngines) != len(mod.convertNames) {
|
||||||
t.Fatalf("expected %d convert names but got %d", len(tc.expectedConvertPdfEngines), len(mod.convertNames))
|
t.Fatalf("expected %d convert names but got %d", len(tc.expectedConvertPdfEngines), len(mod.convertNames))
|
||||||
}
|
}
|
||||||
@@ -382,7 +389,7 @@ func TestPdfEngines_Routes(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
scenario: "routes not disabled",
|
scenario: "routes not disabled",
|
||||||
expectRoutes: 5,
|
expectRoutes: 6,
|
||||||
disableRoutes: false,
|
disableRoutes: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -202,6 +202,20 @@ func SplitPdfStub(ctx *api.Context, engine gotenberg.PdfEngine, mode gotenberg.S
|
|||||||
return outputPaths, nil
|
return outputPaths, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FlattenStub(ctx *api.Context, engine gotenberg.PdfEngine, inputPaths []string) ([]string, error) {
|
||||||
|
outputPaths := make([]string, len(inputPaths))
|
||||||
|
for i, inputPath := range inputPaths {
|
||||||
|
outputPaths[i] = ctx.GeneratePath(".pdf")
|
||||||
|
|
||||||
|
err := engine.Flatten(ctx, ctx.Log(), inputPath, outputPaths[i])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("flatten '%s': %w", inputPath, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputPaths, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ConvertStub transforms a given PDF to the specified formats defined in
|
// ConvertStub transforms a given PDF to the specified formats defined in
|
||||||
// [gotenberg.PdfFormats]. If no format, it does nothing and returns the input
|
// [gotenberg.PdfFormats]. If no format, it does nothing and returns the input
|
||||||
// paths.
|
// paths.
|
||||||
@@ -347,6 +361,51 @@ func splitRoute(engine gotenberg.PdfEngine) api.Route {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func flattenRoute(engine gotenberg.PdfEngine) api.Route {
|
||||||
|
return api.Route{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/forms/pdfengines/flatten",
|
||||||
|
IsMultipart: true,
|
||||||
|
Handler: func(c echo.Context) error {
|
||||||
|
ctx := c.Get("context").(*api.Context)
|
||||||
|
|
||||||
|
form := ctx.FormData()
|
||||||
|
|
||||||
|
var inputPaths []string
|
||||||
|
err := form.
|
||||||
|
MandatoryPaths([]string{".pdf"}, &inputPaths).
|
||||||
|
Validate()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("validate form data: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outputPaths, err := FlattenStub(ctx, engine, inputPaths)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("convert PDFs: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(outputPaths) > 1 {
|
||||||
|
// If .zip archive, keep the original filename.
|
||||||
|
for i, inputPath := range inputPaths {
|
||||||
|
err = ctx.Rename(outputPaths[i], inputPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("rename output path: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outputPaths[i] = inputPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ctx.AddOutputPaths(outputPaths...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("add output paths: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// convertRoute returns an [api.Route] which can convert PDFs to a specific ODF
|
// convertRoute returns an [api.Route] which can convert PDFs to a specific ODF
|
||||||
// format.
|
// format.
|
||||||
func convertRoute(engine gotenberg.PdfEngine) api.Route {
|
func convertRoute(engine gotenberg.PdfEngine) api.Route {
|
||||||
|
|||||||
@@ -99,6 +99,11 @@ func (engine *PdfTk) Merge(ctx context.Context, logger *zap.Logger, inputPaths [
|
|||||||
return fmt.Errorf("merge PDFs with PDFtk: %w", err)
|
return fmt.Errorf("merge PDFs with PDFtk: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flatten is not available in this implementation.
|
||||||
|
func (engine *PdfTk) Flatten(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
|
||||||
|
return fmt.Errorf("flatten PDF with PDFtk: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert is not available in this implementation.
|
// Convert is not available in this implementation.
|
||||||
func (engine *PdfTk) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
func (engine *PdfTk) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
return fmt.Errorf("convert PDF to '%+v' with PDFtk: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
|
return fmt.Errorf("convert PDF to '%+v' with PDFtk: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
|||||||
@@ -101,6 +101,11 @@ func (engine *QPdf) Merge(ctx context.Context, logger *zap.Logger, inputPaths []
|
|||||||
return fmt.Errorf("merge PDFs with QPDF: %w", err)
|
return fmt.Errorf("merge PDFs with QPDF: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flatten is not available in this implementation.
|
||||||
|
func (engine *QPdf) Flatten(ctx context.Context, logger *zap.Logger, inputPath, outputPath string) error {
|
||||||
|
return fmt.Errorf("flatten PDF with QPDF: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert is not available in this implementation.
|
// Convert is not available in this implementation.
|
||||||
func (engine *QPdf) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
func (engine *QPdf) Convert(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
return fmt.Errorf("convert PDF to '%+v' with QPDF: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
|
return fmt.Errorf("convert PDF to '%+v' with QPDF: %w", formats, gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
|
|||||||
Reference in New Issue
Block a user