mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-14 11:22:15 +01:00
128 lines
2.5 KiB
Go
128 lines
2.5 KiB
Go
package process
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os/exec"
|
|
"text/template"
|
|
"time"
|
|
|
|
"github.com/gulien/gotenberg/app/config"
|
|
gfile "github.com/gulien/gotenberg/app/handlers/converter/file"
|
|
)
|
|
|
|
var commandsConfig *config.CommandsConfig
|
|
|
|
func Load(config *config.CommandsConfig) {
|
|
commandsConfig = config
|
|
}
|
|
|
|
type conversionData struct {
|
|
FilePath string
|
|
ResultFilePath string
|
|
}
|
|
|
|
type impossibleConversionError struct{}
|
|
|
|
func (e *impossibleConversionError) Error() string {
|
|
return "Impossible conversion"
|
|
}
|
|
|
|
func ExecConversion(workingDir string, file *gfile.File) (string, error) {
|
|
cmdData := &conversionData{
|
|
FilePath: file.Path,
|
|
ResultFilePath: fmt.Sprintf("%s%s", gfile.MakeFilePath(workingDir), gfile.PDFExt),
|
|
}
|
|
|
|
var (
|
|
cmdTemplate *template.Template
|
|
cmdTimeout int
|
|
)
|
|
|
|
switch file.Type {
|
|
case gfile.HTMLType:
|
|
cmdTemplate = commandsConfig.HTML.Template
|
|
cmdTimeout = commandsConfig.HTML.Timeout
|
|
break
|
|
case gfile.OfficeType:
|
|
cmdTemplate = commandsConfig.Office.Template
|
|
cmdTimeout = commandsConfig.Office.Timeout
|
|
break
|
|
default:
|
|
return "", &impossibleConversionError{}
|
|
}
|
|
|
|
var data bytes.Buffer
|
|
if err := cmdTemplate.Execute(&data, cmdData); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
err := execCommand(data.String(), cmdTimeout)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return cmdData.ResultFilePath, nil
|
|
}
|
|
|
|
type mergeData struct {
|
|
FilesPaths []string
|
|
ResultFilePath string
|
|
}
|
|
|
|
func ExecMerge(workingDir string, filesPaths []string) (string, error) {
|
|
cmdData := &mergeData{
|
|
FilesPaths: filesPaths,
|
|
ResultFilePath: fmt.Sprintf("%s%s", gfile.MakeFilePath(workingDir), gfile.PDFExt),
|
|
}
|
|
|
|
cmdTemplate := commandsConfig.Merge.Template
|
|
cmdTimeout := commandsConfig.Merge.Timeout
|
|
|
|
var data bytes.Buffer
|
|
if err := cmdTemplate.Execute(&data, cmdData); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
err := execCommand(data.String(), cmdTimeout)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return cmdData.ResultFilePath, nil
|
|
}
|
|
|
|
type commandTimeoutError struct{}
|
|
|
|
func (e *commandTimeoutError) Error() string {
|
|
return "The command has reached timeout"
|
|
}
|
|
|
|
func execCommand(command string, timeout int) error {
|
|
cmd := exec.Command("/bin/sh", "-c", command)
|
|
if err := cmd.Start(); err != nil {
|
|
return err
|
|
}
|
|
|
|
done := make(chan error, 1)
|
|
go func() {
|
|
done <- cmd.Wait()
|
|
}()
|
|
|
|
// wait for the process to finish or kill it after a timeout.
|
|
select {
|
|
case <-time.After(time.Duration(timeout) * time.Second):
|
|
if err := cmd.Process.Kill(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return &commandTimeoutError{}
|
|
case err := <-done:
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|