mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
193 lines
5.0 KiB
Go
193 lines
5.0 KiB
Go
package pdfengines
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
|
|
"github.com/gotenberg/gotenberg/v7/pkg/modules/api"
|
|
flag "github.com/spf13/pflag"
|
|
)
|
|
|
|
func init() {
|
|
gotenberg.MustRegisterModule(PDFEngines{})
|
|
}
|
|
|
|
// PDFEngines is a module which gathers available gotenberg.PDFEngine modules.
|
|
// The available gotenberg.PDFEngine modules can be either all
|
|
// gotenberg.PDFEngine modules or the modules selected by the user thanks to
|
|
// the "engines" flag.
|
|
//
|
|
// PDFEngines wraps the gotenberg.PDFEngine modules in an internal struct which
|
|
// also implements gotenberg.PDFEngine. This struct provides a sort of fallback
|
|
// mechanism: if an engine's method returns an error, it calls the same method
|
|
// from another engine.
|
|
//
|
|
// This module implements the gotenberg.PDFEngineProvider interface.
|
|
type PDFEngines struct {
|
|
names []string
|
|
engines []gotenberg.PDFEngine
|
|
disableRoutes bool
|
|
}
|
|
|
|
// Descriptor returns a PDFEngines' module descriptor.
|
|
func (PDFEngines) Descriptor() gotenberg.ModuleDescriptor {
|
|
return 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.Bool("pdfengines-disable-routes", false, "Disable the routes")
|
|
|
|
return fs
|
|
}(),
|
|
New: func() gotenberg.Module { return new(PDFEngines) },
|
|
}
|
|
}
|
|
|
|
// Provision gets either all gotenberg.PDFEngine modules or the modules
|
|
// 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")
|
|
mod.disableRoutes = flags.MustBool("pdfengines-disable-routes")
|
|
|
|
loggerProvider, err := ctx.Module(new(gotenberg.LoggerProvider))
|
|
if err != nil {
|
|
return fmt.Errorf("get logger provider: %w", err)
|
|
}
|
|
|
|
logger, err := loggerProvider.(gotenberg.LoggerProvider).Logger(mod)
|
|
if err != nil {
|
|
return fmt.Errorf("get logger: %w", err)
|
|
}
|
|
|
|
logger = logger.Named("pdfengines")
|
|
|
|
engines, err := ctx.Modules(new(gotenberg.PDFEngine))
|
|
if err != nil {
|
|
return fmt.Errorf("get PDF engines: %w", err)
|
|
}
|
|
|
|
mod.engines = make([]gotenberg.PDFEngine, len(engines))
|
|
|
|
for i, engine := range engines {
|
|
mod.engines[i] = engine.(gotenberg.PDFEngine)
|
|
}
|
|
|
|
if len(names) > 0 {
|
|
// Selection from user.
|
|
mod.names = names
|
|
|
|
for i, name := range names {
|
|
logger.Warn("unoconv-pdfengine is deprecated; prefer uno-pdfengine instead")
|
|
if name == "unoconv-pdfengine" {
|
|
mod.names[i] = "uno-pdfengine"
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// No selection from user, use all PDF engines available.
|
|
mod.names = make([]string, len(mod.engines))
|
|
|
|
for i, engine := range mod.engines {
|
|
mod.names[i] = engine.(gotenberg.Module).Descriptor().ID
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Validate validates there is at least one gotenberg.PDFEngine module
|
|
// available. It also validates that selected gotenberg.PDFEngine modules
|
|
// actually exist.
|
|
func (mod PDFEngines) Validate() error {
|
|
if len(mod.engines) == 0 {
|
|
return errors.New("no PDF engine")
|
|
}
|
|
|
|
availableEngines := make([]string, len(mod.engines))
|
|
|
|
for i, engine := range mod.engines {
|
|
availableEngines[i] = engine.(gotenberg.Module).Descriptor().ID
|
|
}
|
|
|
|
nonExistingEngines := make([]string, 0)
|
|
|
|
for _, name := range mod.names {
|
|
engineExists := false
|
|
|
|
for _, engine := range mod.engines {
|
|
if name == engine.(gotenberg.Module).Descriptor().ID {
|
|
engineExists = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !engineExists {
|
|
nonExistingEngines = append(nonExistingEngines, name)
|
|
}
|
|
}
|
|
|
|
if len(nonExistingEngines) == 0 {
|
|
return nil
|
|
}
|
|
|
|
return fmt.Errorf("non-existing PDF engine(s): %s - available PDF engine(s): %s", nonExistingEngines, availableEngines)
|
|
}
|
|
|
|
// SystemMessages returns one message with the selected gotenberg.PDFEngine
|
|
// modules.
|
|
func (mod PDFEngines) SystemMessages() []string {
|
|
return []string{
|
|
strings.Join(mod.names[:], " "),
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|
|
}
|
|
}
|
|
|
|
return newMultiPDFEngines(engines...), nil
|
|
}
|
|
|
|
// Routes returns the HTTP routes.
|
|
func (mod PDFEngines) Routes() ([]api.Route, error) {
|
|
if mod.disableRoutes {
|
|
return nil, nil
|
|
}
|
|
|
|
engine, err := mod.PDFEngine()
|
|
if err != nil {
|
|
// Should not happen, unless our provider implementation
|
|
// changes in the future.
|
|
return nil, fmt.Errorf("get pdf engine: %w", err)
|
|
}
|
|
|
|
return []api.Route{
|
|
mergeRoute(engine),
|
|
convertRoute(engine),
|
|
}, nil
|
|
}
|
|
|
|
// Interface guards.
|
|
var (
|
|
_ gotenberg.Module = (*PDFEngines)(nil)
|
|
_ gotenberg.Provisioner = (*PDFEngines)(nil)
|
|
_ gotenberg.Validator = (*PDFEngines)(nil)
|
|
_ gotenberg.SystemLogger = (*PDFEngines)(nil)
|
|
_ gotenberg.PDFEngineProvider = (*PDFEngines)(nil)
|
|
_ api.Router = (*PDFEngines)(nil)
|
|
)
|