mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
refactor(gofix): modernize
This commit is contained in:
@@ -45,10 +45,10 @@ func Run() {
|
|||||||
fs.Bool("gotenberg-build-debug-data", true, "Set if build data is needed")
|
fs.Bool("gotenberg-build-debug-data", true, "Set if build data is needed")
|
||||||
|
|
||||||
descriptors := gotenberg.GetModuleDescriptors()
|
descriptors := gotenberg.GetModuleDescriptors()
|
||||||
var modsInfo string
|
var modsInfo strings.Builder
|
||||||
for _, desc := range descriptors {
|
for _, desc := range descriptors {
|
||||||
fs.AddFlagSet(desc.FlagSet)
|
fs.AddFlagSet(desc.FlagSet)
|
||||||
modsInfo += desc.ID + " "
|
modsInfo.WriteString(desc.ID + " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the flags.
|
// Parse the flags.
|
||||||
@@ -94,7 +94,7 @@ func Run() {
|
|||||||
if !hideBanner {
|
if !hideBanner {
|
||||||
fmt.Printf(banner, Version)
|
fmt.Printf(banner, Version)
|
||||||
}
|
}
|
||||||
fmt.Printf("[SYSTEM] modules: %s\n", modsInfo)
|
fmt.Printf("[SYSTEM] modules: %s\n", modsInfo.String())
|
||||||
|
|
||||||
ctx := gotenberg.NewContext(parsedFlags, descriptors)
|
ctx := gotenberg.NewContext(parsedFlags, descriptors)
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
type Context struct {
|
type Context struct {
|
||||||
flags ParsedFlags
|
flags ParsedFlags
|
||||||
descriptors []ModuleDescriptor
|
descriptors []ModuleDescriptor
|
||||||
moduleInstances map[string]interface{}
|
moduleInstances map[string]any
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext creates a [Context].
|
// NewContext creates a [Context].
|
||||||
@@ -22,7 +22,7 @@ func NewContext(
|
|||||||
return &Context{
|
return &Context{
|
||||||
flags: flags,
|
flags: flags,
|
||||||
descriptors: descriptors,
|
descriptors: descriptors,
|
||||||
moduleInstances: make(map[string]interface{}),
|
moduleInstances: make(map[string]any),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ func (ctx *Context) ParsedFlags() ParsedFlags {
|
|||||||
//
|
//
|
||||||
// If the module has not yet been initialized, this method
|
// If the module has not yet been initialized, this method
|
||||||
// initializes it. Otherwise, returns the already initialized instance.
|
// initializes it. Otherwise, returns the already initialized instance.
|
||||||
func (ctx *Context) Module(kind interface{}) (interface{}, error) {
|
func (ctx *Context) Module(kind any) (any, error) {
|
||||||
mods, err := ctx.Modules(kind)
|
mods, err := ctx.Modules(kind)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get module: %w", err)
|
return nil, fmt.Errorf("get module: %w", err)
|
||||||
@@ -70,10 +70,10 @@ func (ctx *Context) Module(kind interface{}) (interface{}, error) {
|
|||||||
//
|
//
|
||||||
// If one or more modules have not yet been initialized, this method
|
// If one or more modules have not yet been initialized, this method
|
||||||
// initializes them. Otherwise, returns the already initialized instances.
|
// initializes them. Otherwise, returns the already initialized instances.
|
||||||
func (ctx *Context) Modules(kind interface{}) ([]interface{}, error) {
|
func (ctx *Context) Modules(kind any) ([]any, error) {
|
||||||
realKind := reflect.TypeOf(kind).Elem()
|
realKind := reflect.TypeOf(kind).Elem()
|
||||||
|
|
||||||
var mods []interface{}
|
var mods []any
|
||||||
|
|
||||||
for _, desc := range ctx.descriptors {
|
for _, desc := range ctx.descriptors {
|
||||||
newInstance := desc.New()
|
newInstance := desc.New()
|
||||||
@@ -101,7 +101,7 @@ func (ctx *Context) Modules(kind interface{}) ([]interface{}, error) {
|
|||||||
|
|
||||||
// loadModule calls the Provision and/or Validate methods of the requested
|
// loadModule calls the Provision and/or Validate methods of the requested
|
||||||
// module if it satisfies the [Provisioner] and/or [Validator] interfaces.
|
// module if it satisfies the [Provisioner] and/or [Validator] interfaces.
|
||||||
func (ctx *Context) loadModule(id string, instance interface{}) error {
|
func (ctx *Context) loadModule(id string, instance any) error {
|
||||||
if prov, ok := instance.(Provisioner); ok {
|
if prov, ok := instance.(Provisioner); ok {
|
||||||
// The instance can be provisioned.
|
// The instance can be provisioned.
|
||||||
err := prov.Provision(ctx)
|
err := prov.Provision(ctx)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ func TestContext_Module(t *testing.T) {
|
|||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
scenario string
|
scenario string
|
||||||
mods []ModuleDescriptor
|
mods []ModuleDescriptor
|
||||||
kind interface{}
|
kind any
|
||||||
expectError bool
|
expectError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -80,7 +80,7 @@ func TestContext_Modules(t *testing.T) {
|
|||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
scenario string
|
scenario string
|
||||||
mods []ModuleDescriptor
|
mods []ModuleDescriptor
|
||||||
kind interface{}
|
kind any
|
||||||
expectError bool
|
expectError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -151,12 +151,12 @@ func TestContext_Modules(t *testing.T) {
|
|||||||
func TestContext_loadModule(t *testing.T) {
|
func TestContext_loadModule(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
scenario string
|
scenario string
|
||||||
instance interface{}
|
instance any
|
||||||
expectError bool
|
expectError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
scenario: "module with error on provision",
|
scenario: "module with error on provision",
|
||||||
instance: func() interface{} {
|
instance: func() any {
|
||||||
mod := &struct {
|
mod := &struct {
|
||||||
ModuleMock
|
ModuleMock
|
||||||
ProvisionerMock
|
ProvisionerMock
|
||||||
@@ -171,7 +171,7 @@ func TestContext_loadModule(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: "module with error on validation",
|
scenario: "module with error on validation",
|
||||||
instance: func() interface{} {
|
instance: func() any {
|
||||||
mod := &struct {
|
mod := &struct {
|
||||||
ModuleMock
|
ModuleMock
|
||||||
ValidatorMock
|
ValidatorMock
|
||||||
@@ -186,7 +186,7 @@ func TestContext_loadModule(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: "success",
|
scenario: "success",
|
||||||
instance: func() interface{} {
|
instance: func() any {
|
||||||
mod := &struct {
|
mod := &struct {
|
||||||
ModuleMock
|
ModuleMock
|
||||||
ValidatorMock
|
ValidatorMock
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import (
|
|||||||
|
|
||||||
// DebugInfo gathers data for debugging.
|
// DebugInfo gathers data for debugging.
|
||||||
type DebugInfo struct {
|
type DebugInfo struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Timezone string `json:"timezone"`
|
Timezone string `json:"timezone"`
|
||||||
Architecture string `json:"architecture"`
|
Architecture string `json:"architecture"`
|
||||||
Modules []string `json:"modules"`
|
Modules []string `json:"modules"`
|
||||||
ModulesAdditionalData map[string]map[string]interface{} `json:"modules_additional_data"`
|
ModulesAdditionalData map[string]map[string]any `json:"modules_additional_data"`
|
||||||
Flags map[string]interface{} `json:"flags"`
|
Flags map[string]any `json:"flags"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildDebug builds the debug data from modules.
|
// BuildDebug builds the debug data from modules.
|
||||||
@@ -29,8 +29,8 @@ func BuildDebug(ctx *Context) {
|
|||||||
Timezone: time.Now().Location().String(),
|
Timezone: time.Now().Location().String(),
|
||||||
Architecture: runtime.GOARCH,
|
Architecture: runtime.GOARCH,
|
||||||
Modules: make([]string, len(ctx.moduleInstances)),
|
Modules: make([]string, len(ctx.moduleInstances)),
|
||||||
ModulesAdditionalData: make(map[string]map[string]interface{}),
|
ModulesAdditionalData: make(map[string]map[string]any),
|
||||||
Flags: make(map[string]interface{}),
|
Flags: make(map[string]any),
|
||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ func TestBuildDebug(t *testing.T) {
|
|||||||
mod2.DescriptorMock = func() ModuleDescriptor {
|
mod2.DescriptorMock = func() ModuleDescriptor {
|
||||||
return ModuleDescriptor{ID: "bar", New: func() Module { return mod2 }}
|
return ModuleDescriptor{ID: "bar", New: func() Module { return mod2 }}
|
||||||
}
|
}
|
||||||
mod2.DebugMock = func() map[string]interface{} {
|
mod2.DebugMock = func() map[string]any {
|
||||||
return map[string]interface{}{
|
return map[string]any{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,12 +59,12 @@ func TestBuildDebug(t *testing.T) {
|
|||||||
"bar",
|
"bar",
|
||||||
"foo",
|
"foo",
|
||||||
},
|
},
|
||||||
ModulesAdditionalData: map[string]map[string]interface{}{
|
ModulesAdditionalData: map[string]map[string]any{
|
||||||
"bar": {
|
"bar": {
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Flags: map[string]interface{}{
|
Flags: map[string]any{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,22 +32,22 @@ func NewLeveledLogger(logger *zap.Logger) *LeveledLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Error logs a message at the error level using the wrapped zap.Logger.
|
// Error logs a message at the error level using the wrapped zap.Logger.
|
||||||
func (leveled LeveledLogger) Error(msg string, keysAndValues ...interface{}) {
|
func (leveled LeveledLogger) Error(msg string, keysAndValues ...any) {
|
||||||
leveled.logger.Error(fmt.Sprintf("%s: %+v", msg, keysAndValues))
|
leveled.logger.Error(fmt.Sprintf("%s: %+v", msg, keysAndValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warn logs a message at the warning level using the wrapped zap.Logger.
|
// Warn logs a message at the warning level using the wrapped zap.Logger.
|
||||||
func (leveled LeveledLogger) Warn(msg string, keysAndValues ...interface{}) {
|
func (leveled LeveledLogger) Warn(msg string, keysAndValues ...any) {
|
||||||
leveled.logger.Warn(fmt.Sprintf("%s: %+v", msg, keysAndValues))
|
leveled.logger.Warn(fmt.Sprintf("%s: %+v", msg, keysAndValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info logs a message at the info level using the wrapped zap.Logger.
|
// Info logs a message at the info level using the wrapped zap.Logger.
|
||||||
func (leveled LeveledLogger) Info(msg string, keysAndValues ...interface{}) {
|
func (leveled LeveledLogger) Info(msg string, keysAndValues ...any) {
|
||||||
leveled.logger.Info(fmt.Sprintf("%s: %+v", msg, keysAndValues))
|
leveled.logger.Info(fmt.Sprintf("%s: %+v", msg, keysAndValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug logs a message at the debug level using the wrapped zap.Logger.
|
// Debug logs a message at the debug level using the wrapped zap.Logger.
|
||||||
func (leveled LeveledLogger) Debug(msg string, keysAndValues ...interface{}) {
|
func (leveled LeveledLogger) Debug(msg string, keysAndValues ...any) {
|
||||||
leveled.logger.Debug(fmt.Sprintf("%s: %+v", msg, keysAndValues))
|
leveled.logger.Debug(fmt.Sprintf("%s: %+v", msg, keysAndValues))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ func (mod *ValidatorMock) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DebuggableMock struct {
|
type DebuggableMock struct {
|
||||||
DebugMock func() map[string]interface{}
|
DebugMock func() map[string]any
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *DebuggableMock) Debug() map[string]interface{} {
|
func (mod *DebuggableMock) Debug() map[string]any {
|
||||||
return mod.DebugMock()
|
return mod.DebugMock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ type PdfEngineMock struct {
|
|||||||
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 string) error
|
FlattenMock func(ctx context.Context, logger *zap.Logger, inputPath 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]any, 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]any, inputPath string) error
|
||||||
EncryptMock func(ctx context.Context, logger *zap.Logger, inputPath, userPassword, ownerPassword string) error
|
EncryptMock func(ctx context.Context, logger *zap.Logger, inputPath, userPassword, ownerPassword string) error
|
||||||
EmbedFilesMock func(ctx context.Context, logger *zap.Logger, filePaths []string, inputPath string) error
|
EmbedFilesMock func(ctx context.Context, logger *zap.Logger, filePaths []string, inputPath string) error
|
||||||
}
|
}
|
||||||
@@ -72,11 +72,11 @@ func (engine *PdfEngineMock) Convert(ctx context.Context, logger *zap.Logger, fo
|
|||||||
return engine.ConvertMock(ctx, logger, formats, inputPath, outputPath)
|
return engine.ConvertMock(ctx, logger, formats, inputPath, outputPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *PdfEngineMock) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
func (engine *PdfEngineMock) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]any, error) {
|
||||||
return engine.ReadMetadataMock(ctx, logger, inputPath)
|
return engine.ReadMetadataMock(ctx, logger, inputPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *PdfEngineMock) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
func (engine *PdfEngineMock) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]any, inputPath string) error {
|
||||||
return engine.WriteMetadataMock(ctx, logger, metadata, inputPath)
|
return engine.WriteMetadataMock(ctx, logger, metadata, inputPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ type SystemLogger interface {
|
|||||||
// Debuggable is a module interface for modules which want to provide
|
// Debuggable is a module interface for modules which want to provide
|
||||||
// additional debug data.
|
// additional debug data.
|
||||||
type Debuggable interface {
|
type Debuggable interface {
|
||||||
Debug() map[string]interface{}
|
Debug() map[string]any
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustRegisterModule registers a module.
|
// MustRegisterModule registers a module.
|
||||||
|
|||||||
@@ -133,10 +133,10 @@ type PdfEngine interface {
|
|||||||
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
|
||||||
|
|
||||||
// ReadMetadata extracts the metadata of a given PDF file.
|
// ReadMetadata extracts the metadata of a given PDF file.
|
||||||
ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error)
|
ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]any, error)
|
||||||
|
|
||||||
// WriteMetadata writes the metadata into a given PDF file.
|
// WriteMetadata writes the metadata into a given PDF file.
|
||||||
WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error
|
WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]any, inputPath string) error
|
||||||
|
|
||||||
// Encrypt adds password protection to a PDF file.
|
// Encrypt adds password protection to a PDF file.
|
||||||
// The userPassword is required to open the document.
|
// The userPassword is required to open the document.
|
||||||
|
|||||||
@@ -409,14 +409,12 @@ func TestProcessSupervisor_Run(t *testing.T) {
|
|||||||
errorChan := make(chan error, tc.tasksToRun)
|
errorChan := make(chan error, tc.tasksToRun)
|
||||||
|
|
||||||
for i := 0; i < tc.tasksToRun; i++ {
|
for i := 0; i < tc.tasksToRun; i++ {
|
||||||
wg.Add(1)
|
wg.Go(func() {
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
err := ps.Run(ctx, logger, task)
|
err := ps.Run(ctx, logger, task)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorChan <- err
|
errorChan <- err
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@@ -522,17 +520,15 @@ func TestProcessSupervisor_ReqQueueSize(t *testing.T) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
errorChan := make(chan error, 10)
|
errorChan := make(chan error, 10)
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for range 10 {
|
||||||
wg.Add(1)
|
wg.Go(func() {
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
err := ps.Run(ctx, logger, func() error {
|
err := ps.Run(ctx, logger, func() error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorChan <- err
|
errorChan <- err
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to wait a little bit so that the request queue size may change.
|
// We have to wait a little bit so that the request queue size may change.
|
||||||
@@ -652,10 +648,8 @@ func TestProcessSupervisor_ConcurrentRun(t *testing.T) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
tasks := 6
|
tasks := 6
|
||||||
|
|
||||||
for i := 0; i < tasks; i++ {
|
for range tasks {
|
||||||
wg.Add(1)
|
wg.Go(func() {
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
err := ps.Run(ctx, logger, func() error {
|
err := ps.Run(ctx, logger, func() error {
|
||||||
cur := running.Add(1)
|
cur := running.Add(1)
|
||||||
for {
|
for {
|
||||||
@@ -671,7 +665,7 @@ func TestProcessSupervisor_ConcurrentRun(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@@ -714,10 +708,8 @@ func TestProcessSupervisor_RestartDrainsAllSlots(t *testing.T) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
tasks := 3
|
tasks := 3
|
||||||
|
|
||||||
for i := 0; i < tasks; i++ {
|
for range tasks {
|
||||||
wg.Add(1)
|
wg.Go(func() {
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
err := ps.Run(ctx, logger, func() error {
|
err := ps.Run(ctx, logger, func() error {
|
||||||
time.Sleep(50 * time.Millisecond)
|
time.Sleep(50 * time.Millisecond)
|
||||||
return nil
|
return nil
|
||||||
@@ -725,7 +717,7 @@ func TestProcessSupervisor_RestartDrainsAllSlots(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ func (form *FormData) append(err error) {
|
|||||||
// mustValue binds the target interface with a form field. If the value is
|
// mustValue binds the target interface with a form field. If the value is
|
||||||
// empty or the "key" does not exist, it binds the default value. Currently,
|
// empty or the "key" does not exist, it binds the default value. Currently,
|
||||||
// only the string, bool, int, float64 and time.Duration types are bindable.
|
// only the string, bool, int, float64 and time.Duration types are bindable.
|
||||||
func (form *FormData) mustValue(key string, target interface{}, defaultValue interface{}) *FormData {
|
func (form *FormData) mustValue(key string, target any, defaultValue any) *FormData {
|
||||||
val, ok := form.values[key]
|
val, ok := form.values[key]
|
||||||
|
|
||||||
if !ok || val[0] == "" {
|
if !ok || val[0] == "" {
|
||||||
@@ -468,7 +468,7 @@ func (form *FormData) mustValue(key string, target interface{}, defaultValue int
|
|||||||
// populates an error if the value is empty or the "key" does not exist.
|
// populates an error if the value is empty or the "key" does not exist.
|
||||||
// Currently, only the string, bool, int, float64 and time.Duration types are
|
// Currently, only the string, bool, int, float64 and time.Duration types are
|
||||||
// bindable.
|
// bindable.
|
||||||
func (form *FormData) mustMandatoryField(key string, target interface{}) *FormData {
|
func (form *FormData) mustMandatoryField(key string, target any) *FormData {
|
||||||
val, ok := form.values[key]
|
val, ok := form.values[key]
|
||||||
|
|
||||||
if !ok || val[0] == "" {
|
if !ok || val[0] == "" {
|
||||||
@@ -487,7 +487,7 @@ func (form *FormData) mustMandatoryField(key string, target interface{}) *FormDa
|
|||||||
// mustAssign parses the string value and tries to convert it to the target
|
// mustAssign parses the string value and tries to convert it to the target
|
||||||
// interface real type. Currently, only the string, bool, int, float64 and
|
// interface real type. Currently, only the string, bool, int, float64 and
|
||||||
// time.Duration types are bindable.
|
// time.Duration types are bindable.
|
||||||
func (form *FormData) mustAssign(key, value string, target interface{}) *FormData {
|
func (form *FormData) mustAssign(key, value string, target any) *FormData {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
switch t := (target).(type) {
|
switch t := (target).(type) {
|
||||||
|
|||||||
@@ -565,8 +565,8 @@ func (mod *Chromium) Stop(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debug returns additional debug data.
|
// Debug returns additional debug data.
|
||||||
func (mod *Chromium) Debug() map[string]interface{} {
|
func (mod *Chromium) Debug() map[string]any {
|
||||||
debug := make(map[string]interface{})
|
debug := make(map[string]any)
|
||||||
|
|
||||||
cmd := exec.Command(mod.args.binPath, "--version") //nolint:gosec
|
cmd := exec.Command(mod.args.binPath, "--version") //nolint:gosec
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func (debug *debugLogger) Write(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Printf logs a debug message.
|
// Printf logs a debug message.
|
||||||
func (debug *debugLogger) Printf(format string, v ...interface{}) {
|
func (debug *debugLogger) Printf(format string, v ...any) {
|
||||||
debug.logger.Debug(fmt.Sprintf(format, v...))
|
debug.logger.Debug(fmt.Sprintf(format, v...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func listenForEventRequestPaused(ctx context.Context, logger *zap.Logger, option
|
|||||||
logger.Debug(fmt.Sprintf("extra HTTP headers: %+v", options.extraHttpHeaders))
|
logger.Debug(fmt.Sprintf("extra HTTP headers: %+v", options.extraHttpHeaders))
|
||||||
}
|
}
|
||||||
|
|
||||||
chromedp.ListenTarget(ctx, func(ev interface{}) {
|
chromedp.ListenTarget(ctx, func(ev any) {
|
||||||
switch e := ev.(type) {
|
switch e := ev.(type) {
|
||||||
case *fetch.EventRequestPaused:
|
case *fetch.EventRequestPaused:
|
||||||
go func() {
|
go func() {
|
||||||
@@ -176,7 +176,7 @@ func listenForEventResponseReceived(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chromedp.ListenTarget(ctx, func(ev interface{}) {
|
chromedp.ListenTarget(ctx, func(ev any) {
|
||||||
switch ev := ev.(type) {
|
switch ev := ev.(type) {
|
||||||
case *network.EventResponseReceived:
|
case *network.EventResponseReceived:
|
||||||
if ev.Response.URL == options.mainPageUrl {
|
if ev.Response.URL == options.mainPageUrl {
|
||||||
@@ -299,7 +299,7 @@ type eventLoadingFailedOptions struct {
|
|||||||
// https://github.com/gotenberg/gotenberg/issues/959.
|
// https://github.com/gotenberg/gotenberg/issues/959.
|
||||||
// https://github.com/gotenberg/gotenberg/issues/1021.
|
// https://github.com/gotenberg/gotenberg/issues/1021.
|
||||||
func listenForEventLoadingFailed(ctx context.Context, logger *zap.Logger, options eventLoadingFailedOptions) {
|
func listenForEventLoadingFailed(ctx context.Context, logger *zap.Logger, options eventLoadingFailedOptions) {
|
||||||
chromedp.ListenTarget(ctx, func(ev interface{}) {
|
chromedp.ListenTarget(ctx, func(ev any) {
|
||||||
switch ev := ev.(type) {
|
switch ev := ev.(type) {
|
||||||
case *network.EventLoadingFailed:
|
case *network.EventLoadingFailed:
|
||||||
logger.Debug(fmt.Sprintf("event EventLoadingFailed fired: %+v", ev.ErrorText))
|
logger.Debug(fmt.Sprintf("event EventLoadingFailed fired: %+v", ev.ErrorText))
|
||||||
@@ -355,7 +355,7 @@ func listenForEventLoadingFailed(ctx context.Context, logger *zap.Logger, option
|
|||||||
// appends those exceptions to the given error pointer.
|
// appends those exceptions to the given error pointer.
|
||||||
// See https://github.com/gotenberg/gotenberg/issues/262.
|
// See https://github.com/gotenberg/gotenberg/issues/262.
|
||||||
func listenForEventExceptionThrown(ctx context.Context, logger *zap.Logger, consoleExceptions *error, consoleExceptionsMu *sync.RWMutex) {
|
func listenForEventExceptionThrown(ctx context.Context, logger *zap.Logger, consoleExceptions *error, consoleExceptionsMu *sync.RWMutex) {
|
||||||
chromedp.ListenTarget(ctx, func(ev interface{}) {
|
chromedp.ListenTarget(ctx, func(ev any) {
|
||||||
switch ev := ev.(type) {
|
switch ev := ev.(type) {
|
||||||
case *runtime.EventExceptionThrown:
|
case *runtime.EventExceptionThrown:
|
||||||
logger.Debug(fmt.Sprintf("event EventExceptionThrown fired: %+v", ev.ExceptionDetails))
|
logger.Debug(fmt.Sprintf("event EventExceptionThrown fired: %+v", ev.ExceptionDetails))
|
||||||
@@ -374,7 +374,7 @@ func waitForEventDomContentEventFired(ctx context.Context, logger *zap.Logger) f
|
|||||||
return func() error {
|
return func() error {
|
||||||
ch := make(chan struct{})
|
ch := make(chan struct{})
|
||||||
cctx, cancel := context.WithCancel(ctx)
|
cctx, cancel := context.WithCancel(ctx)
|
||||||
chromedp.ListenTarget(cctx, func(ev interface{}) {
|
chromedp.ListenTarget(cctx, func(ev any) {
|
||||||
switch ev.(type) {
|
switch ev.(type) {
|
||||||
case *page.EventDomContentEventFired:
|
case *page.EventDomContentEventFired:
|
||||||
cancel()
|
cancel()
|
||||||
@@ -398,7 +398,7 @@ func waitForEventLoadEventFired(ctx context.Context, logger *zap.Logger) func()
|
|||||||
return func() error {
|
return func() error {
|
||||||
ch := make(chan struct{})
|
ch := make(chan struct{})
|
||||||
cctx, cancel := context.WithCancel(ctx)
|
cctx, cancel := context.WithCancel(ctx)
|
||||||
chromedp.ListenTarget(cctx, func(ev interface{}) {
|
chromedp.ListenTarget(cctx, func(ev any) {
|
||||||
switch ev.(type) {
|
switch ev.(type) {
|
||||||
case *page.EventLoadEventFired:
|
case *page.EventLoadEventFired:
|
||||||
cancel()
|
cancel()
|
||||||
@@ -422,7 +422,7 @@ func waitForEventNetworkIdle(ctx context.Context, logger *zap.Logger) func() err
|
|||||||
return func() error {
|
return func() error {
|
||||||
ch := make(chan struct{})
|
ch := make(chan struct{})
|
||||||
cctx, cancel := context.WithCancel(ctx)
|
cctx, cancel := context.WithCancel(ctx)
|
||||||
chromedp.ListenTarget(cctx, func(ev interface{}) {
|
chromedp.ListenTarget(cctx, func(ev any) {
|
||||||
switch e := ev.(type) {
|
switch e := ev.(type) {
|
||||||
case *page.EventLifecycleEvent:
|
case *page.EventLifecycleEvent:
|
||||||
if e.Name == "networkIdle" {
|
if e.Name == "networkIdle" {
|
||||||
@@ -448,7 +448,7 @@ func waitForEventLoadingFinished(ctx context.Context, logger *zap.Logger) func()
|
|||||||
return func() error {
|
return func() error {
|
||||||
ch := make(chan struct{})
|
ch := make(chan struct{})
|
||||||
cctx, cancel := context.WithCancel(ctx)
|
cctx, cancel := context.WithCancel(ctx)
|
||||||
chromedp.ListenTarget(cctx, func(ev interface{}) {
|
chromedp.ListenTarget(cctx, func(ev any) {
|
||||||
switch ev.(type) {
|
switch ev.(type) {
|
||||||
case *network.EventLoadingFinished:
|
case *network.EventLoadingFinished:
|
||||||
cancel()
|
cancel()
|
||||||
|
|||||||
@@ -172,8 +172,8 @@ func FormDataChromiumOptions(ctx *api.Context) (*api.FormData, Options) {
|
|||||||
var valueTokens []string
|
var valueTokens []string
|
||||||
var invalidScopeToken bool
|
var invalidScopeToken bool
|
||||||
|
|
||||||
tokens := strings.Split(v, ";")
|
tokens := strings.SplitSeq(v, ";")
|
||||||
for _, token := range tokens {
|
for token := range tokens {
|
||||||
if strings.HasPrefix(strings.ToLower(strings.TrimSpace(token)), "scope") {
|
if strings.HasPrefix(strings.ToLower(strings.TrimSpace(token)), "scope") {
|
||||||
tokenNoSpaces := strings.Join(strings.Fields(token), "")
|
tokenNoSpaces := strings.Join(strings.Fields(token), "")
|
||||||
parts := strings.SplitN(tokenNoSpaces, "=", 2)
|
parts := strings.SplitN(tokenNoSpaces, "=", 2)
|
||||||
@@ -686,7 +686,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{}, userPassword, ownerPassword string, embedPaths []string) error {
|
func convertUrl(ctx *api.Context, chromium Api, engine gotenberg.PdfEngine, url string, options PdfOptions, mode gotenberg.SplitMode, pdfFormats gotenberg.PdfFormats, metadata map[string]any, userPassword, ownerPassword string, embedPaths []string) error {
|
||||||
outputPath := ctx.GeneratePath(".pdf")
|
outputPath := ctx.GeneratePath(".pdf")
|
||||||
// See https://github.com/gotenberg/gotenberg/issues/1130.
|
// See https://github.com/gotenberg/gotenberg/issues/1130.
|
||||||
filename := ctx.OutputFilename(outputPath)
|
filename := ctx.OutputFilename(outputPath)
|
||||||
|
|||||||
@@ -39,11 +39,9 @@ func (reader *streamReader) Read(p []byte) (n int, err error) {
|
|||||||
// Chromium might have an off-by-one when deciding the maximum size (at
|
// Chromium might have an off-by-one when deciding the maximum size (at
|
||||||
// least for base64 encoded data), usually it will overflow. We subtract
|
// least for base64 encoded data), usually it will overflow. We subtract
|
||||||
// one to make sure it fits into p.
|
// one to make sure it fits into p.
|
||||||
size := len(p) - 1
|
size := max(len(p)-1,
|
||||||
if size < 1 {
|
|
||||||
// Safety-check to avoid crashing Chrome (e.g. via SetSize(-1)).
|
// Safety-check to avoid crashing Chrome (e.g. via SetSize(-1)).
|
||||||
size = 1
|
1)
|
||||||
}
|
|
||||||
|
|
||||||
reply, err := reader.next(reader.pos, size)
|
reply, err := reader.next(reader.pos, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ func (engine *ExifTool) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debug returns additional debug data.
|
// Debug returns additional debug data.
|
||||||
func (engine *ExifTool) Debug() map[string]interface{} {
|
func (engine *ExifTool) Debug() map[string]any {
|
||||||
debug := make(map[string]interface{})
|
debug := make(map[string]any)
|
||||||
|
|
||||||
cmd := exec.Command(engine.binPath, "-ver") //nolint:gosec
|
cmd := exec.Command(engine.binPath, "-ver") //nolint:gosec
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||||
@@ -94,7 +94,7 @@ func (engine *ExifTool) Convert(ctx context.Context, logger *zap.Logger, formats
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadMetadata extracts the metadata of a given PDF file.
|
// ReadMetadata extracts the metadata of a given PDF file.
|
||||||
func (engine *ExifTool) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
func (engine *ExifTool) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]any, error) {
|
||||||
exifTool, err := exiftool.NewExiftool(exiftool.SetExiftoolBinaryPath(engine.binPath))
|
exifTool, err := exiftool.NewExiftool(exiftool.SetExiftoolBinaryPath(engine.binPath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("new ExifTool: %w", err)
|
return nil, fmt.Errorf("new ExifTool: %w", err)
|
||||||
@@ -116,7 +116,7 @@ func (engine *ExifTool) ReadMetadata(ctx context.Context, logger *zap.Logger, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteMetadata writes the metadata into a given PDF file.
|
// WriteMetadata writes the metadata into a given PDF file.
|
||||||
func (engine *ExifTool) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
func (engine *ExifTool) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]any, inputPath string) error {
|
||||||
exifTool, err := exiftool.NewExiftool(exiftool.SetExiftoolBinaryPath(engine.binPath))
|
exifTool, err := exiftool.NewExiftool(exiftool.SetExiftoolBinaryPath(engine.binPath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("new ExifTool: %w", err)
|
return fmt.Errorf("new ExifTool: %w", err)
|
||||||
@@ -167,7 +167,7 @@ func (engine *ExifTool) WriteMetadata(ctx context.Context, logger *zap.Logger, m
|
|||||||
fileMetadata[0].SetString(key, val)
|
fileMetadata[0].SetString(key, val)
|
||||||
case []string:
|
case []string:
|
||||||
fileMetadata[0].SetStrings(key, val)
|
fileMetadata[0].SetStrings(key, val)
|
||||||
case []interface{}:
|
case []any:
|
||||||
// See https://github.com/gotenberg/gotenberg/issues/1048.
|
// See https://github.com/gotenberg/gotenberg/issues/1048.
|
||||||
strs := make([]string, len(val))
|
strs := make([]string, len(val))
|
||||||
for i, entry := range val {
|
for i, entry := range val {
|
||||||
@@ -175,7 +175,7 @@ func (engine *ExifTool) WriteMetadata(ctx context.Context, logger *zap.Logger, m
|
|||||||
strs[i] = str
|
strs[i] = str
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return fmt.Errorf("write PDF metadata with ExifTool: %s %+v %s %w", key, val, reflect.TypeOf(val), gotenberg.ErrPdfEngineMetadataValueNotSupported)
|
return fmt.Errorf("write PDF metadata with ExifTool: %s %+v %s %w", key, val, reflect.TypeFor[[]interface{}](), gotenberg.ErrPdfEngineMetadataValueNotSupported)
|
||||||
}
|
}
|
||||||
fileMetadata[0].SetStrings(key, strs)
|
fileMetadata[0].SetStrings(key, strs)
|
||||||
case bool:
|
case bool:
|
||||||
|
|||||||
@@ -316,8 +316,8 @@ func (a *Api) Stop(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debug returns additional debug data.
|
// Debug returns additional debug data.
|
||||||
func (a *Api) Debug() map[string]interface{} {
|
func (a *Api) Debug() map[string]any {
|
||||||
debug := make(map[string]interface{})
|
debug := make(map[string]any)
|
||||||
|
|
||||||
cmd := exec.Command(a.args.binPath, "--version") //nolint:gosec
|
cmd := exec.Command(a.args.binPath, "--version") //nolint:gosec
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ func (engine *LibreOfficePdfEngine) Convert(ctx context.Context, logger *zap.Log
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadMetadata is not available in this implementation.
|
// ReadMetadata is not available in this implementation.
|
||||||
func (engine *LibreOfficePdfEngine) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
func (engine *LibreOfficePdfEngine) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]any, error) {
|
||||||
return nil, fmt.Errorf("read PDF metadata with LibreOffice: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return nil, fmt.Errorf("read PDF metadata with LibreOffice: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMetadata is not available in this implementation.
|
// WriteMetadata is not available in this implementation.
|
||||||
func (engine *LibreOfficePdfEngine) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
func (engine *LibreOfficePdfEngine) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]any, inputPath string) error {
|
||||||
return fmt.Errorf("write PDF metadata with LibreOffice: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return fmt.Errorf("write PDF metadata with LibreOffice: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ func (engine *PdfCpu) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debug returns additional debug data.
|
// Debug returns additional debug data.
|
||||||
func (engine *PdfCpu) Debug() map[string]interface{} {
|
func (engine *PdfCpu) Debug() map[string]any {
|
||||||
debug := make(map[string]interface{})
|
debug := make(map[string]any)
|
||||||
|
|
||||||
cmd := exec.Command(engine.binPath, "version") //nolint:gosec
|
cmd := exec.Command(engine.binPath, "version") //nolint:gosec
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||||
@@ -71,10 +71,10 @@ func (engine *PdfCpu) Debug() map[string]interface{} {
|
|||||||
|
|
||||||
debug["version"] = "Unable to determine pdfcpu version"
|
debug["version"] = "Unable to determine pdfcpu version"
|
||||||
|
|
||||||
lines := strings.Split(string(output), "\n")
|
lines := strings.SplitSeq(string(output), "\n")
|
||||||
for _, line := range lines {
|
for line := range lines {
|
||||||
if strings.HasPrefix(line, "pdfcpu:") {
|
if after, ok := strings.CutPrefix(line, "pdfcpu:"); ok {
|
||||||
debug["version"] = strings.TrimSpace(strings.TrimPrefix(line, "pdfcpu:"))
|
debug["version"] = strings.TrimSpace(after)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,12 +162,12 @@ func (engine *PdfCpu) Convert(ctx context.Context, logger *zap.Logger, formats g
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadMetadata is not available in this implementation.
|
// ReadMetadata is not available in this implementation.
|
||||||
func (engine *PdfCpu) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
func (engine *PdfCpu) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]any, error) {
|
||||||
return nil, fmt.Errorf("read PDF metadata with pdfcpu: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return nil, fmt.Errorf("read PDF metadata with pdfcpu: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMetadata is not available in this implementation.
|
// WriteMetadata is not available in this implementation.
|
||||||
func (engine *PdfCpu) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
func (engine *PdfCpu) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]any, inputPath string) error {
|
||||||
return fmt.Errorf("write PDF metadata with pdfcpu: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return fmt.Errorf("write PDF metadata with pdfcpu: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -156,13 +156,13 @@ func (multi *multiPdfEngines) Convert(ctx context.Context, logger *zap.Logger, f
|
|||||||
}
|
}
|
||||||
|
|
||||||
type readMetadataResult struct {
|
type readMetadataResult struct {
|
||||||
metadata map[string]interface{}
|
metadata map[string]any
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadMetadata extracts metadata from a PDF file using the first available
|
// ReadMetadata extracts metadata from a PDF file using the first available
|
||||||
// engine that supports metadata reading.
|
// engine that supports metadata reading.
|
||||||
func (multi *multiPdfEngines) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
func (multi *multiPdfEngines) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]any, error) {
|
||||||
var err error
|
var err error
|
||||||
var mu sync.Mutex // to safely append errors.
|
var mu sync.Mutex // to safely append errors.
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ func (multi *multiPdfEngines) ReadMetadata(ctx context.Context, logger *zap.Logg
|
|||||||
|
|
||||||
// WriteMetadata embeds metadata into a PDF file using the first available
|
// WriteMetadata embeds metadata into a PDF file using the first available
|
||||||
// engine that supports metadata writing.
|
// engine that supports metadata writing.
|
||||||
func (multi *multiPdfEngines) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
func (multi *multiPdfEngines) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]any, inputPath string) error {
|
||||||
var err error
|
var err error
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
|
|||||||
@@ -479,8 +479,8 @@ func TestMultiPdfEngines_ReadMetadata(t *testing.T) {
|
|||||||
engine: &multiPdfEngines{
|
engine: &multiPdfEngines{
|
||||||
readMetadataEngines: []gotenberg.PdfEngine{
|
readMetadataEngines: []gotenberg.PdfEngine{
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, error) {
|
||||||
return make(map[string]interface{}), nil
|
return make(map[string]any), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -492,13 +492,13 @@ func TestMultiPdfEngines_ReadMetadata(t *testing.T) {
|
|||||||
engine: &multiPdfEngines{
|
engine: &multiPdfEngines{
|
||||||
readMetadataEngines: []gotenberg.PdfEngine{
|
readMetadataEngines: []gotenberg.PdfEngine{
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, error) {
|
||||||
return nil, errors.New("foo")
|
return nil, errors.New("foo")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, error) {
|
||||||
return make(map[string]interface{}), nil
|
return make(map[string]any), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -510,12 +510,12 @@ func TestMultiPdfEngines_ReadMetadata(t *testing.T) {
|
|||||||
engine: &multiPdfEngines{
|
engine: &multiPdfEngines{
|
||||||
readMetadataEngines: []gotenberg.PdfEngine{
|
readMetadataEngines: []gotenberg.PdfEngine{
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, error) {
|
||||||
return nil, errors.New("foo")
|
return nil, errors.New("foo")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, error) {
|
||||||
return nil, errors.New("foo")
|
return nil, errors.New("foo")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -529,8 +529,8 @@ func TestMultiPdfEngines_ReadMetadata(t *testing.T) {
|
|||||||
engine: &multiPdfEngines{
|
engine: &multiPdfEngines{
|
||||||
readMetadataEngines: []gotenberg.PdfEngine{
|
readMetadataEngines: []gotenberg.PdfEngine{
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, error) {
|
||||||
return make(map[string]interface{}), nil
|
return make(map[string]any), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -570,7 +570,7 @@ func TestMultiPdfEngines_WriteMetadata(t *testing.T) {
|
|||||||
engine: &multiPdfEngines{
|
engine: &multiPdfEngines{
|
||||||
writeMetadataEngines: []gotenberg.PdfEngine{
|
writeMetadataEngines: []gotenberg.PdfEngine{
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, inputPath string) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -583,12 +583,12 @@ func TestMultiPdfEngines_WriteMetadata(t *testing.T) {
|
|||||||
engine: &multiPdfEngines{
|
engine: &multiPdfEngines{
|
||||||
writeMetadataEngines: []gotenberg.PdfEngine{
|
writeMetadataEngines: []gotenberg.PdfEngine{
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, inputPath string) error {
|
||||||
return errors.New("foo")
|
return errors.New("foo")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, inputPath string) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -601,12 +601,12 @@ func TestMultiPdfEngines_WriteMetadata(t *testing.T) {
|
|||||||
engine: &multiPdfEngines{
|
engine: &multiPdfEngines{
|
||||||
writeMetadataEngines: []gotenberg.PdfEngine{
|
writeMetadataEngines: []gotenberg.PdfEngine{
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, inputPath string) error {
|
||||||
return errors.New("foo")
|
return errors.New("foo")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, inputPath string) error {
|
||||||
return errors.New("foo")
|
return errors.New("foo")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -620,7 +620,7 @@ func TestMultiPdfEngines_WriteMetadata(t *testing.T) {
|
|||||||
engine: &multiPdfEngines{
|
engine: &multiPdfEngines{
|
||||||
writeMetadataEngines: []gotenberg.PdfEngine{
|
writeMetadataEngines: []gotenberg.PdfEngine{
|
||||||
&gotenberg.PdfEngineMock{
|
&gotenberg.PdfEngineMock{
|
||||||
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]any, inputPath string) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package pdfengines
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
@@ -179,13 +180,7 @@ func (mod *PdfEngines) Validate() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
alreadyInSlice := false
|
alreadyInSlice := slices.Contains(nonExistingEngines, name)
|
||||||
for _, engine := range nonExistingEngines {
|
|
||||||
if engine == name {
|
|
||||||
alreadyInSlice = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !alreadyInSlice {
|
if !alreadyInSlice {
|
||||||
nonExistingEngines = append(nonExistingEngines, name)
|
nonExistingEngines = append(nonExistingEngines, name)
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ func FormDataPdfFormats(form *api.FormData) gotenberg.PdfFormats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FormDataPdfMetadata creates metadata object from the form data.
|
// FormDataPdfMetadata creates metadata object from the form data.
|
||||||
func FormDataPdfMetadata(form *api.FormData, mandatory bool) map[string]interface{} {
|
func FormDataPdfMetadata(form *api.FormData, mandatory bool) map[string]any {
|
||||||
var metadata map[string]interface{}
|
var metadata map[string]any
|
||||||
|
|
||||||
metadataFunc := func(value string) error {
|
metadataFunc := func(value string) error {
|
||||||
if len(value) > 0 {
|
if len(value) > 0 {
|
||||||
@@ -239,7 +239,7 @@ func ConvertStub(ctx *api.Context, engine gotenberg.PdfEngine, formats gotenberg
|
|||||||
|
|
||||||
// WriteMetadataStub writes the metadata into PDF files. If no metadata, it
|
// WriteMetadataStub writes the metadata into PDF files. If no metadata, it
|
||||||
// does nothing.
|
// does nothing.
|
||||||
func WriteMetadataStub(ctx *api.Context, engine gotenberg.PdfEngine, metadata map[string]interface{}, inputPaths []string) error {
|
func WriteMetadataStub(ctx *api.Context, engine gotenberg.PdfEngine, metadata map[string]any, inputPaths []string) error {
|
||||||
if len(metadata) == 0 {
|
if len(metadata) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -558,7 +558,7 @@ func readMetadataRoute(engine gotenberg.PdfEngine) api.Route {
|
|||||||
return fmt.Errorf("validate form data: %w", err)
|
return fmt.Errorf("validate form data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make(map[string]map[string]interface{}, len(inputPaths))
|
res := make(map[string]map[string]any, len(inputPaths))
|
||||||
for _, inputPath := range inputPaths {
|
for _, inputPath := range inputPaths {
|
||||||
metadata, err := engine.ReadMetadata(ctx, ctx.Log(), inputPath)
|
metadata, err := engine.ReadMetadata(ctx, ctx.Log(), inputPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ func (engine *PdfTk) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debug returns additional debug data.
|
// Debug returns additional debug data.
|
||||||
func (engine *PdfTk) Debug() map[string]interface{} {
|
func (engine *PdfTk) Debug() map[string]any {
|
||||||
debug := make(map[string]interface{})
|
debug := make(map[string]any)
|
||||||
|
|
||||||
cmd := exec.Command(engine.binPath, "--version") //nolint:gosec
|
cmd := exec.Command(engine.binPath, "--version") //nolint:gosec
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||||
@@ -136,12 +136,12 @@ func (engine *PdfTk) Convert(ctx context.Context, logger *zap.Logger, formats go
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadMetadata is not available in this implementation.
|
// ReadMetadata is not available in this implementation.
|
||||||
func (engine *PdfTk) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
func (engine *PdfTk) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]any, error) {
|
||||||
return nil, fmt.Errorf("read PDF metadata with PDFtk: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return nil, fmt.Errorf("read PDF metadata with PDFtk: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMetadata is not available in this implementation.
|
// WriteMetadata is not available in this implementation.
|
||||||
func (engine *PdfTk) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
func (engine *PdfTk) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]any, inputPath string) error {
|
||||||
return fmt.Errorf("write PDF metadata with PDFtk: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return fmt.Errorf("write PDF metadata with PDFtk: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ func (engine *QPdf) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debug returns additional debug data.
|
// Debug returns additional debug data.
|
||||||
func (engine *QPdf) Debug() map[string]interface{} {
|
func (engine *QPdf) Debug() map[string]any {
|
||||||
debug := make(map[string]interface{})
|
debug := make(map[string]any)
|
||||||
|
|
||||||
cmd := exec.Command(engine.binPath, "--version") //nolint:gosec
|
cmd := exec.Command(engine.binPath, "--version") //nolint:gosec
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||||
@@ -163,12 +163,12 @@ func (engine *QPdf) Convert(ctx context.Context, logger *zap.Logger, formats got
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadMetadata is not available in this implementation.
|
// ReadMetadata is not available in this implementation.
|
||||||
func (engine *QPdf) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
func (engine *QPdf) ReadMetadata(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]any, error) {
|
||||||
return nil, fmt.Errorf("read PDF metadata with QPDF: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return nil, fmt.Errorf("read PDF metadata with QPDF: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMetadata is not available in this implementation.
|
// WriteMetadata is not available in this implementation.
|
||||||
func (engine *QPdf) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
func (engine *QPdf) WriteMetadata(ctx context.Context, logger *zap.Logger, metadata map[string]any, inputPath string) error {
|
||||||
return fmt.Errorf("write PDF metadata with QPDF: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
return fmt.Errorf("write PDF metadata with QPDF: %w", gotenberg.ErrPdfEngineMethodNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
func compareJson(expected, actual interface{}) error {
|
func compareJson(expected, actual any) error {
|
||||||
// Handle maps (JSON objects).
|
// Handle maps (JSON objects).
|
||||||
expectedMap, ok := expected.(map[string]interface{})
|
expectedMap, ok := expected.(map[string]any)
|
||||||
if ok {
|
if ok {
|
||||||
actualMap, ok := actual.(map[string]interface{})
|
actualMap, ok := actual.(map[string]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("expected an object, but actual is: %T", actual)
|
return fmt.Errorf("expected an object, but actual is: %T", actual)
|
||||||
}
|
}
|
||||||
@@ -31,9 +31,9 @@ func compareJson(expected, actual interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle slices (JSON arrays).
|
// Handle slices (JSON arrays).
|
||||||
expectedSlice, ok := expected.([]interface{})
|
expectedSlice, ok := expected.([]any)
|
||||||
if ok {
|
if ok {
|
||||||
actualSlice, ok := actual.([]interface{})
|
actualSlice, ok := actual.([]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("expected an array, but actual is: %T", actual)
|
return fmt.Errorf("expected an array, but actual is: %T", actual)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ var (
|
|||||||
|
|
||||||
type noopLogger struct{}
|
type noopLogger struct{}
|
||||||
|
|
||||||
func (n *noopLogger) Printf(format string, v ...interface{}) {
|
func (n *noopLogger) Printf(format string, v ...any) {
|
||||||
// NOOP
|
// NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -327,11 +327,8 @@ func (s *scenario) iMakeConcurrentRequestsToGotenberg(ctx context.Context, count
|
|||||||
s.concurrentResps = make([]*httptest.ResponseRecorder, 0, count)
|
s.concurrentResps = make([]*httptest.ResponseRecorder, 0, count)
|
||||||
errs := make([]error, 0)
|
errs := make([]error, 0)
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
for range count {
|
||||||
wg.Add(1)
|
wg.Go(func() {
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
resp, reqErr := doFormDataRequest(method, fmt.Sprintf("%s%s", base, endpoint), fields, files, headers)
|
resp, reqErr := doFormDataRequest(method, fmt.Sprintf("%s%s", base, endpoint), fields, files, headers)
|
||||||
if reqErr != nil {
|
if reqErr != nil {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
@@ -387,7 +384,7 @@ func (s *scenario) iMakeConcurrentRequestsToGotenberg(ctx context.Context, count
|
|||||||
mu.Lock()
|
mu.Lock()
|
||||||
s.concurrentResps = append(s.concurrentResps, rec)
|
s.concurrentResps = append(s.concurrentResps, rec)
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@@ -495,7 +492,7 @@ func (s *scenario) theGotenbergContainerShouldLogTheFollowingEntries(ctx context
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < 3; i++ {
|
for range 3 {
|
||||||
err = check()
|
err = check()
|
||||||
if err != nil && !invert {
|
if err != nil && !invert {
|
||||||
// We have to retry as not all logs may have been produced.
|
// We have to retry as not all logs may have been produced.
|
||||||
@@ -618,7 +615,7 @@ func (s *scenario) theBodyShouldMatchJSON(kind string, expectedDoc *godog.DocStr
|
|||||||
body = s.server.bodyCopy
|
body = s.server.bodyCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
var expected, actual interface{}
|
var expected, actual any
|
||||||
|
|
||||||
content := strings.ReplaceAll(expectedDoc.Content, "{version}", GotenbergVersion)
|
content := strings.ReplaceAll(expectedDoc.Content, "{version}", GotenbergVersion)
|
||||||
err := json.Unmarshal([]byte(content), &expected)
|
err := json.Unmarshal([]byte(content), &expected)
|
||||||
|
|||||||
Reference in New Issue
Block a user