renderer.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package renderer
  2. import (
  3. "crypto/md5"
  4. "encoding/hex"
  5. "io"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. "time"
  10. "github.com/torkelo/grafana-pro/pkg/log"
  11. "github.com/torkelo/grafana-pro/pkg/setting"
  12. )
  13. type RenderOpts struct {
  14. Url string
  15. Width string
  16. Height string
  17. }
  18. func RenderToPng(params *RenderOpts) (string, error) {
  19. log.Info("PhantomRenderer::renderToPng url %v", params.Url)
  20. binPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, "phantomjs"))
  21. scriptPath, _ := filepath.Abs(filepath.Join(setting.PhantomDir, "render.js"))
  22. pngPath, _ := filepath.Abs(filepath.Join(setting.ImagesDir, getHash(params.Url)))
  23. pngPath = pngPath + ".png"
  24. cmd := exec.Command(binPath, scriptPath, "url="+params.Url, "width="+params.Width, "height="+params.Height, "png="+pngPath)
  25. stdout, err := cmd.StdoutPipe()
  26. if err != nil {
  27. return "", err
  28. }
  29. stderr, err := cmd.StderrPipe()
  30. if err != nil {
  31. return "", err
  32. }
  33. err = cmd.Start()
  34. if err != nil {
  35. return "", err
  36. }
  37. go io.Copy(os.Stdout, stdout)
  38. go io.Copy(os.Stdout, stderr)
  39. done := make(chan error)
  40. go func() {
  41. cmd.Wait()
  42. close(done)
  43. }()
  44. select {
  45. case <-time.After(10 * time.Second):
  46. if err := cmd.Process.Kill(); err != nil {
  47. log.Error(4, "failed to kill: %v", err)
  48. }
  49. case <-done:
  50. }
  51. return pngPath, nil
  52. }
  53. func getHash(text string) string {
  54. hasher := md5.New()
  55. hasher.Write([]byte(text))
  56. return hex.EncodeToString(hasher.Sum(nil))
  57. }