feat(pdfengines): one flag per PDF engine method for a more granular selection of PDF engines

This commit is contained in:
Julien Neuhart
2024-10-13 11:29:38 +02:00
parent 8ff9d3bcf1
commit 249745f256
5 changed files with 370 additions and 158 deletions

View File

@@ -27,9 +27,12 @@ func init() {
// the [api.Router] interface to expose relevant PDF processing routes if
// enabled.
type PdfEngines struct {
names []string
engines []gotenberg.PdfEngine
disableRoutes bool
mergeNames []string
convertNames []string
readMetadataNames []string
writeMedataNames []string
engines []gotenberg.PdfEngine
disableRoutes bool
}
// Descriptor returns a PdfEngines' module descriptor.
@@ -38,9 +41,18 @@ func (mod *PdfEngines) Descriptor() gotenberg.ModuleDescriptor {
ID: "pdfengines",
FlagSet: func() *flag.FlagSet {
fs := flag.NewFlagSet("pdfengines", flag.ExitOnError)
fs.StringSlice("pdfengines-engines", make([]string, 0), "Set the PDF engines and their order - all by default")
fs.StringSlice("pdfengines-merge-engines", []string{"qpdf", "pdfcpu", "pdftk"}, "Set the PDF engines and their order for the merge feature")
fs.StringSlice("pdfengines-convert-engines", []string{"libreoffice-pdfengine"}, "Set the PDF engines and their order for the convert feature")
fs.StringSlice("pdfengines-read-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the read metadata feature")
fs.StringSlice("pdfengines-write-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the write metadata feature")
fs.Bool("pdfengines-disable-routes", false, "Disable the routes")
fs.StringSlice("pdfengines-engines", make([]string, 0), "Set the default PDF engines and their default order - all by default")
err := fs.MarkDeprecated("pdfengines-engines", "use other flags for a more granular selection of PDF engines per method")
if err != nil {
panic(err)
}
return fs
}(),
New: func() gotenberg.Module { return new(PdfEngines) },
@@ -51,7 +63,10 @@ func (mod *PdfEngines) Descriptor() gotenberg.ModuleDescriptor {
// selected by the user thanks to the "engines" flag.
func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
flags := ctx.ParsedFlags()
names := flags.MustStringSlice("pdfengines-engines")
mergeNames := flags.MustStringSlice("pdfengines-merge-engines")
convertNames := flags.MustStringSlice("pdfengines-convert-engines")
readMetadataNames := flags.MustStringSlice("pdfengines-read-metadata-engines")
writeMetadataNames := flags.MustStringSlice("pdfengines-write-metadata-engines")
mod.disableRoutes = flags.MustBool("pdfengines-disable-routes")
engines, err := ctx.Modules(new(gotenberg.PdfEngine))
@@ -65,26 +80,37 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
mod.engines[i] = engine.(gotenberg.PdfEngine)
}
if len(names) > 0 {
// Selection from user.
mod.names = names
// Example in case of deprecated module name.
//for i, name := range names {
// if name == "unoconv-pdfengine" || name == "uno-pdfengine" {
// logger.Warn(fmt.Sprintf("%s is deprecated; prefer libreoffice-pdfengine instead", name))
// mod.names[i] = "libreoffice-pdfengine"
// }
//}
return nil
defaultNames := make([]string, len(mod.engines))
for i, engine := range mod.engines {
defaultNames[i] = engine.(gotenberg.Module).Descriptor().ID
}
// No selection from user, use all PDF engines available.
mod.names = make([]string, len(mod.engines))
// Example in case of deprecated module name.
//for i, name := range defaultNames {
// if name == "unoconv-pdfengine" || name == "uno-pdfengine" {
// logger.Warn(fmt.Sprintf("%s is deprecated; prefer libreoffice-pdfengine instead", name))
// mod.defaultNames[i] = "libreoffice-pdfengine"
// }
//}
for i, engine := range mod.engines {
mod.names[i] = engine.(gotenberg.Module).Descriptor().ID
mod.mergeNames = defaultNames
if len(mergeNames) > 0 {
mod.mergeNames = mergeNames
}
mod.convertNames = defaultNames
if len(convertNames) > 0 {
mod.convertNames = convertNames
}
mod.readMetadataNames = defaultNames
if len(readMetadataNames) > 0 {
mod.readMetadataNames = readMetadataNames
}
mod.writeMedataNames = defaultNames
if len(writeMetadataNames) > 0 {
mod.writeMedataNames = writeMetadataNames
}
return nil
@@ -105,22 +131,40 @@ func (mod *PdfEngines) Validate() error {
}
nonExistingEngines := make([]string, 0)
findNonExistingEngines := func(names []string) {
for _, name := range names {
engineExists := false
for _, name := range mod.names {
engineExists := false
for _, engine := range mod.engines {
if name == engine.(gotenberg.Module).Descriptor().ID {
engineExists = true
break
}
}
for _, engine := range mod.engines {
if name == engine.(gotenberg.Module).Descriptor().ID {
engineExists = true
break
if engineExists {
continue
}
alreadyInSlice := false
for _, engine := range nonExistingEngines {
if engine == name {
alreadyInSlice = true
break
}
}
if !alreadyInSlice {
nonExistingEngines = append(nonExistingEngines, name)
}
}
if !engineExists {
nonExistingEngines = append(nonExistingEngines, name)
}
}
findNonExistingEngines(mod.mergeNames)
findNonExistingEngines(mod.convertNames)
findNonExistingEngines(mod.readMetadataNames)
findNonExistingEngines(mod.writeMedataNames)
if len(nonExistingEngines) == 0 {
return nil
}
@@ -132,24 +176,35 @@ func (mod *PdfEngines) Validate() error {
// modules.
func (mod *PdfEngines) SystemMessages() []string {
return []string{
strings.Join(mod.names[:], " "),
fmt.Sprintf("merge engines - %s", strings.Join(mod.mergeNames[:], " ")),
fmt.Sprintf("convert engines - %s", strings.Join(mod.convertNames[:], " ")),
fmt.Sprintf("read metadata engines - %s", strings.Join(mod.readMetadataNames[:], " ")),
fmt.Sprintf("write medata engines - %s", strings.Join(mod.writeMedataNames[:], " ")),
}
}
// PdfEngine returns a [gotenberg.PdfEngine].
func (mod *PdfEngines) PdfEngine() (gotenberg.PdfEngine, error) {
engines := make([]gotenberg.PdfEngine, len(mod.names))
for i, name := range mod.names {
for _, engine := range mod.engines {
if name == engine.(gotenberg.Module).Descriptor().ID {
engines[i] = engine
break
engines := func(names []string) []gotenberg.PdfEngine {
list := make([]gotenberg.PdfEngine, len(names))
for i, name := range names {
for _, engine := range mod.engines {
if name == engine.(gotenberg.Module).Descriptor().ID {
list[i] = engine
break
}
}
}
return list
}
return newMultiPdfEngines(engines...), nil
return newMultiPdfEngines(
engines(mod.mergeNames),
engines(mod.convertNames),
engines(mod.readMetadataNames),
engines(mod.writeMedataNames),
), nil
}
// Routes returns the HTTP routes.