89 lines
1.9 KiB
Go
89 lines
1.9 KiB
Go
|
package srnd
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"errors"
|
||
|
"log"
|
||
|
"mime"
|
||
|
"os/exec"
|
||
|
"path/filepath"
|
||
|
"regexp"
|
||
|
"sort"
|
||
|
"strings"
|
||
|
stdtemplate "text/template"
|
||
|
)
|
||
|
|
||
|
var ErrNoThumbnailerFound = errors.New("no thumbnailer found")
|
||
|
|
||
|
type ThumbnailRule struct {
|
||
|
AcceptsMimeType string
|
||
|
CommandTemplate string
|
||
|
}
|
||
|
|
||
|
func (th *ThumbnailRule) GenerateThumbnail(infname, outfname string, env map[string]string) (err error) {
|
||
|
env["infile"] = infname
|
||
|
env["outfile"] = outfname
|
||
|
buff := new(bytes.Buffer)
|
||
|
err = stdtemplate.Must(stdtemplate.New("").Parse(th.CommandTemplate)).Execute(buff, env)
|
||
|
if err == nil {
|
||
|
args := strings.Split(buff.String(), " ")
|
||
|
cmd := exec.Command(args[0], args[1:]...)
|
||
|
var out []byte
|
||
|
out, err = cmd.CombinedOutput()
|
||
|
if err != nil {
|
||
|
log.Println(buff.String(), string(out))
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (th *ThumbnailRule) Accepts(mimetype string) bool {
|
||
|
return regexp.MustCompile(th.AcceptsMimeType).MatchString(mimetype)
|
||
|
}
|
||
|
|
||
|
func (th *ThumbnailConfig) Load(opts map[string]string) {
|
||
|
for k, v := range opts {
|
||
|
th.rules = append(th.rules, ThumbnailRule{
|
||
|
AcceptsMimeType: k,
|
||
|
CommandTemplate: v,
|
||
|
})
|
||
|
}
|
||
|
sort.Sort(th)
|
||
|
}
|
||
|
|
||
|
func (th *ThumbnailConfig) Len() int {
|
||
|
return len(th.rules)
|
||
|
}
|
||
|
|
||
|
func (th *ThumbnailConfig) Swap(i, j int) {
|
||
|
th.rules[i], th.rules[j] = th.rules[j], th.rules[i]
|
||
|
}
|
||
|
|
||
|
func (th *ThumbnailConfig) Less(i, j int) bool {
|
||
|
return th.rules[i].AcceptsMimeType < th.rules[j].AcceptsMimeType
|
||
|
}
|
||
|
|
||
|
func (th *ThumbnailConfig) FindRulesFor(mimetype string) (rules []ThumbnailRule) {
|
||
|
for _, rule := range th.rules {
|
||
|
if rule.Accepts(mimetype) {
|
||
|
rules = append(rules, rule)
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (th *ThumbnailConfig) GenerateThumbnail(infname, outfname string, env map[string]string) (err error) {
|
||
|
mimeType := mime.TypeByExtension(filepath.Ext(infname))
|
||
|
rules := th.FindRulesFor(mimeType)
|
||
|
for _, rule := range rules {
|
||
|
err = rule.GenerateThumbnail(infname, outfname, env)
|
||
|
if err == nil {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if len(rules) == 0 {
|
||
|
err = ErrNoThumbnailerFound
|
||
|
}
|
||
|
return
|
||
|
}
|