Selaa lähdekoodia

workin on png rendering

Torkel Ödegaard 11 vuotta sitten
vanhempi
commit
380f707285

+ 1 - 1
.gitignore

@@ -2,7 +2,7 @@ node_modules
 coverage/
 .aws-config.json
 dist
-
+data/png
 public
 gin-bin
 # locally required config files

+ 1 - 1
_vendor/phantomjs/render.js

@@ -20,7 +20,7 @@ page.viewportSize = {
 };
 
 page.open(params.url, function (status) {
-  console.log('Loading a web page');
+  console.log('Loading a web page: ' + params.url);
 
   setTimeout(function() {
     console.log('rendering panel to ' + params.png);

+ 60 - 2
backend/components/phantom_renderer.go

@@ -1,9 +1,67 @@
 package components
 
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"io"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"time"
+
+	log "github.com/alecthomas/log4go"
+)
+
 type PhantomRenderer struct {
-	ImagesDir string
+	ImagesDir  string
+	PhantomDir string
 }
 
-func (renderer *PhantomRenderer) Render(url string) {
+func (self *PhantomRenderer) RenderToPng(url string) (string, error) {
+	log.Info("PhantomRenderer::renderToPng url %v", url)
+	binPath, _ := filepath.Abs(filepath.Join(self.PhantomDir, "phantomjs"))
+	scriptPath, _ := filepath.Abs(filepath.Join(self.PhantomDir, "render.js"))
+	pngPath, _ := filepath.Abs(filepath.Join(self.ImagesDir, getHash(url)))
+	pngPath = pngPath + ".png"
+
+	cmd := exec.Command(binPath, scriptPath, "url="+url, "width=100", "height=100", "png="+pngPath)
+	stdout, err := cmd.StdoutPipe()
+
+	if err != nil {
+		return "", err
+	}
+	stderr, err := cmd.StderrPipe()
+	if err != nil {
+		return "", err
+	}
+
+	err = cmd.Start()
+	if err != nil {
+		return "", err
+	}
+
+	go io.Copy(os.Stdout, stdout)
+	go io.Copy(os.Stdout, stderr)
+
+	done := make(chan error)
+	go func() {
+		cmd.Wait()
+		close(done)
+	}()
+
+	select {
+	case <-time.After(10 * time.Second):
+		if err := cmd.Process.Kill(); err != nil {
+			log.Error("failed to kill: %v", err)
+		}
+	case <-done:
+	}
+
+	return pngPath, nil
+}
 
+func getHash(text string) string {
+	hasher := md5.New()
+	hasher.Write([]byte(text))
+	return hex.EncodeToString(hasher.Sum(nil))
 }

+ 17 - 4
backend/components/phantom_renderer_test.go

@@ -2,6 +2,7 @@ package components
 
 import (
 	"io/ioutil"
+	"os"
 	"testing"
 
 	. "github.com/smartystreets/goconvey/convey"
@@ -9,14 +10,26 @@ import (
 
 func TestPhantomRender(t *testing.T) {
 
-	Convey("Can render url", func() {
+	Convey("Can render url", t, func() {
 		tempDir, _ := ioutil.TempDir("", "img")
-		renderer := &PhantomRenderer{ImagesDir: tempDir}
-		renderer.Render("http://www.google.com")
-		//So(err, ShouldBeNil)
+		renderer := &PhantomRenderer{ImagesDir: tempDir, PhantomDir: "../../_vendor/phantomjs/"}
+		png, err := renderer.RenderToPng("http://www.google.com")
+		So(err, ShouldBeNil)
+		So(exists(png), ShouldEqual, true)
 
 		//_, err = os.Stat(store.getFilePathForDashboard("hello"))
 		//So(err, ShouldBeNil)
 	})
 
 }
+
+func exists(path string) bool {
+	_, err := os.Stat(path)
+	if err == nil {
+		return true
+	}
+	if os.IsNotExist(err) {
+		return false
+	}
+	return false
+}

+ 16 - 0
backend/httpApi/api.go

@@ -5,6 +5,7 @@ import (
 
 	log "github.com/alecthomas/log4go"
 	"github.com/gin-gonic/gin"
+	"github.com/torkelo/grafana-pro/backend/components"
 	"github.com/torkelo/grafana-pro/backend/models"
 	"github.com/torkelo/grafana-pro/backend/stores"
 )
@@ -13,12 +14,14 @@ type HttpServer struct {
 	port     string
 	shutdown chan bool
 	store    stores.Store
+	renderer *components.PhantomRenderer
 }
 
 func NewHttpServer(port string, store stores.Store) *HttpServer {
 	self := &HttpServer{}
 	self.port = port
 	self.store = store
+	self.renderer = &components.PhantomRenderer{ImagesDir: "data/png", PhantomDir: "_vendor/phantomjs"}
 
 	return self
 }
@@ -48,6 +51,8 @@ func (self *HttpServer) ListenAndServe() {
 	r.GET("/api/search/", self.search)
 	r.POST("/api/dashboard", self.postDashboard)
 
+	r.GET("/api/render", self.renderToPng)
+
 	r.Static("/public", "./public")
 	r.Static("/app", "./public/app")
 	r.Static("/img", "./public/img")
@@ -79,6 +84,17 @@ func (self *HttpServer) getDashboard(c *gin.Context) {
 	c.JSON(200, dash.Data)
 }
 
+func (self *HttpServer) renderToPng(c *gin.Context) {
+	qs := c.Request.URL.Query()
+	url := qs["url"][0]
+	pngPath, err := self.renderer.RenderToPng(url)
+	if err != nil {
+		c.HTML(500, "error.html", nil)
+	}
+
+	c.File(pngPath)
+}
+
 func (self *HttpServer) search(c *gin.Context) {
 	query := c.Params.ByName("q")
 

+ 1 - 1
grafana

@@ -1 +1 @@
-Subproject commit f068b2c1d32d74af63e0b36aeed4ac0cc2bb8838
+Subproject commit 1bc277fd87469b1deb0e1b1571d7010f0f396d5a