mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
255 lines
7.2 KiB
Go
255 lines
7.2 KiB
Go
/*
|
|
Package config contains all the logic allowing us to instantiate the application's configuration.
|
|
|
|
The application's configuration is loaded from a YAML file named gotenberg.yml.
|
|
It should be located where the user starts the application from the CLI.
|
|
*/
|
|
package config
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"text/template"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
type (
|
|
// AppConfig gathers all data required to instantiate the application.
|
|
AppConfig struct {
|
|
// Port is the port which the application will listen to.
|
|
Port string
|
|
// Logs contains the logging configuration.
|
|
Logs struct {
|
|
// Level is the level of messages which will be logged.
|
|
Level logrus.Level
|
|
// Formatter defines the logging format when a TTY is not attached.
|
|
Formatter logrus.Formatter
|
|
}
|
|
// CommandsConfig is... an instance of CommandsConfig.
|
|
CommandsConfig *CommandsConfig
|
|
}
|
|
|
|
// CommandsConfig gathers all commands' configurations as defined
|
|
// by the user in the gotenberg.yml file.
|
|
CommandsConfig struct {
|
|
// Markdown is the command's configuration for converting
|
|
// an Markdown file to PDF.
|
|
Markdown *CommandConfig
|
|
// HTML is the command's configuration for converting
|
|
// an HTML file to PDF.
|
|
HTML *CommandConfig
|
|
// Office is the command's configuration for converting
|
|
// an Office document to PDF.
|
|
Office *CommandConfig
|
|
// Merge is the command's configuration for merging
|
|
// multiple PDF files into one PDF file.
|
|
Merge *CommandConfig
|
|
}
|
|
|
|
// CommandConfig is a command's configuration.
|
|
CommandConfig struct {
|
|
// Timeout is the duration in seconds after which the command's process will be killed
|
|
// if it does not finish before.
|
|
Timeout int
|
|
// Template is the data-driven template of the command.
|
|
Template *template.Template
|
|
}
|
|
)
|
|
|
|
// NewAppConfig instantiates the application's configuration.
|
|
// If something bad happens here, the application should not start.
|
|
func NewAppConfig(configurationFilePath string) (*AppConfig, error) {
|
|
fileConfig, err := loadFileConfig(configurationFilePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
c := &AppConfig{}
|
|
c.Port = fileConfig.Port
|
|
|
|
if err := makeLogs(c, fileConfig); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := makeCommandsConfig(c, fileConfig); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return c, nil
|
|
}
|
|
|
|
// fileConfig gathers all data coming from the configuration file gotenberg.yml.
|
|
type fileConfig struct {
|
|
Port string `yaml:"port"`
|
|
Logs struct {
|
|
Level string `yaml:"level"`
|
|
Format string `yaml:"format"`
|
|
} `yaml:"logs"`
|
|
Commands struct {
|
|
Markdown struct {
|
|
Timeout int `yaml:"timeout"`
|
|
Template string `yaml:"template"`
|
|
} `yaml:"markdown"`
|
|
HTML struct {
|
|
Timeout int
|
|
Template string
|
|
} `yaml:"html"`
|
|
Office struct {
|
|
Timeout int `yaml:"timeout"`
|
|
Template string `yaml:"template"`
|
|
} `yaml:"office"`
|
|
Merge struct {
|
|
Timeout int `yaml:"timeout"`
|
|
Template string `yaml:"template"`
|
|
} `yaml:"merge"`
|
|
} `yaml:"commands"`
|
|
}
|
|
|
|
// loadFileConfig instantiates a fileConfig instance by loading
|
|
// the configuration file gotenberg.yml.
|
|
func loadFileConfig(configurationFilePath string) (*fileConfig, error) {
|
|
c := &fileConfig{}
|
|
|
|
data, err := ioutil.ReadFile(configurationFilePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := yaml.Unmarshal(data, &c); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return c, nil
|
|
}
|
|
|
|
// makeLogs is a simple wrapper which populates all data related
|
|
// to application's logging.
|
|
func makeLogs(appConfig *AppConfig, fileConfig *fileConfig) error {
|
|
lvl, err := getLoggingLevelFromFileConfig(fileConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
formatter, err := getLoggingFormatterFromFileConfig(fileConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
appConfig.Logs.Level = lvl
|
|
appConfig.Logs.Formatter = formatter
|
|
|
|
return nil
|
|
}
|
|
|
|
// levels associates logging levels as defined in the configuration file gotenberg.yml
|
|
// with its counterpart from the logrus library.
|
|
var levels = map[string]logrus.Level{
|
|
"DEBUG": logrus.DebugLevel,
|
|
"INFO": logrus.InfoLevel,
|
|
"WARN": logrus.WarnLevel,
|
|
"ERROR": logrus.ErrorLevel,
|
|
"FATAL": logrus.FatalLevel,
|
|
"PANIC": logrus.PanicLevel,
|
|
}
|
|
|
|
type wrongLoggingLevelError struct{}
|
|
|
|
const wrongLoggingLevelErrorMessage = "Accepted values for logging level: DEBUG, INFO, WARN, ERROR, FATAL, PANIC"
|
|
|
|
func (e *wrongLoggingLevelError) Error() string {
|
|
return wrongLoggingLevelErrorMessage
|
|
}
|
|
|
|
// getLoggingLevelFromFileConfig returns a logrus level if a matching was found
|
|
// with the one defined by the user.
|
|
// If no match, throws an error.
|
|
func getLoggingLevelFromFileConfig(c *fileConfig) (logrus.Level, error) {
|
|
l, ok := levels[c.Logs.Level]
|
|
if !ok {
|
|
return 999, &wrongLoggingLevelError{}
|
|
}
|
|
|
|
return l, nil
|
|
}
|
|
|
|
// levels associates logging formats as defined in the configuration file gotenberg.yml
|
|
// with its counterpart from the logrus library.
|
|
var formatters = map[string]logrus.Formatter{
|
|
"text": &logrus.TextFormatter{},
|
|
"json": &logrus.JSONFormatter{},
|
|
}
|
|
|
|
type wrongLoggingFormatError struct{}
|
|
|
|
const wrongLoggingFormatErrorMessage = "Accepted value for logging format: text, json"
|
|
|
|
func (e *wrongLoggingFormatError) Error() string {
|
|
return wrongLoggingFormatErrorMessage
|
|
}
|
|
|
|
// getLoggingLevelFromFileConfig returns a logrus Formatter if a matching was found
|
|
// with the format defined by the user.
|
|
// If no match, throws an error.
|
|
func getLoggingFormatterFromFileConfig(c *fileConfig) (logrus.Formatter, error) {
|
|
f, ok := formatters[c.Logs.Format]
|
|
if !ok {
|
|
return nil, &wrongLoggingFormatError{}
|
|
}
|
|
|
|
return f, nil
|
|
}
|
|
|
|
// makeCommandsConfigs is a simple wrapper which populates all data related
|
|
// to commands' configurations.
|
|
func makeCommandsConfig(appConfig *AppConfig, fileConfig *fileConfig) error {
|
|
appConfig.CommandsConfig = &CommandsConfig{}
|
|
appConfig.CommandsConfig.Markdown = &CommandConfig{}
|
|
appConfig.CommandsConfig.HTML = &CommandConfig{}
|
|
appConfig.CommandsConfig.Office = &CommandConfig{}
|
|
appConfig.CommandsConfig.Merge = &CommandConfig{}
|
|
|
|
appConfig.CommandsConfig.Markdown.Timeout = fileConfig.Commands.Markdown.Timeout
|
|
appConfig.CommandsConfig.HTML.Timeout = fileConfig.Commands.HTML.Timeout
|
|
appConfig.CommandsConfig.Office.Timeout = fileConfig.Commands.Office.Timeout
|
|
appConfig.CommandsConfig.Merge.Timeout = fileConfig.Commands.Merge.Timeout
|
|
|
|
tmplMarkdown, err := getCommandTemplate(fileConfig.Commands.Markdown.Template, "Markdown")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tmplHTML, err := getCommandTemplate(fileConfig.Commands.HTML.Template, "HTML")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tmplOffice, err := getCommandTemplate(fileConfig.Commands.Office.Template, "Office")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tmplMerge, err := getCommandTemplate(fileConfig.Commands.Merge.Template, "Merge")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
appConfig.CommandsConfig.Markdown.Template = tmplMarkdown
|
|
appConfig.CommandsConfig.HTML.Template = tmplHTML
|
|
appConfig.CommandsConfig.Office.Template = tmplOffice
|
|
appConfig.CommandsConfig.Merge.Template = tmplMerge
|
|
|
|
return nil
|
|
}
|
|
|
|
// getCommandTemplate is a simple helper for parsing a command template as defined by the user.
|
|
// If the user gives us a wrong template, throws an error.
|
|
func getCommandTemplate(command string, commandName string) (*template.Template, error) {
|
|
t, err := template.New(commandName).Parse(command)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return t, nil
|
|
}
|