diff --git a/contrib/backends/srndv2/src/srnd/thumbnails.go b/contrib/backends/srndv2/src/srnd/thumbnails.go new file mode 100644 index 0000000..b0678be --- /dev/null +++ b/contrib/backends/srndv2/src/srnd/thumbnails.go @@ -0,0 +1,88 @@ +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 +}