api.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package httpApi
  2. import (
  3. "html/template"
  4. log "github.com/alecthomas/log4go"
  5. "github.com/gin-gonic/gin"
  6. "github.com/torkelo/grafana-pro/backend/components"
  7. "github.com/torkelo/grafana-pro/backend/models"
  8. "github.com/torkelo/grafana-pro/backend/stores"
  9. )
  10. type HttpServer struct {
  11. port string
  12. shutdown chan bool
  13. store stores.Store
  14. renderer *components.PhantomRenderer
  15. }
  16. func NewHttpServer(port string, store stores.Store) *HttpServer {
  17. self := &HttpServer{}
  18. self.port = port
  19. self.store = store
  20. self.renderer = &components.PhantomRenderer{ImagesDir: "data/png", PhantomDir: "_vendor/phantomjs"}
  21. return self
  22. }
  23. func CacheHeadersMiddleware() gin.HandlerFunc {
  24. return func(c *gin.Context) {
  25. c.Writer.Header().Add("Cache-Control", "max-age=0, public, must-revalidate, proxy-revalidate")
  26. }
  27. }
  28. func (self *HttpServer) ListenAndServe() {
  29. log.Info("Starting Http Listener on port %v", self.port)
  30. defer func() { self.shutdown <- true }()
  31. r := gin.Default()
  32. r.Use(CacheHeadersMiddleware())
  33. templates := template.New("templates")
  34. templates.Delims("[[", "]]")
  35. templates.ParseFiles("./views/index.html")
  36. r.SetHTMLTemplate(templates)
  37. r.GET("/", self.index)
  38. r.GET("/api/dashboards/:id", self.getDashboard)
  39. r.GET("/api/search/", self.search)
  40. r.POST("/api/dashboard", self.postDashboard)
  41. r.GET("/api/render", self.renderToPng)
  42. r.Static("/public", "./public")
  43. r.Static("/app", "./public/app")
  44. r.Static("/img", "./public/img")
  45. r.Run(":" + self.port)
  46. }
  47. type IndexViewModel struct {
  48. Title string
  49. }
  50. func (self *HttpServer) index(c *gin.Context) {
  51. c.HTML(200, "index.html", &IndexViewModel{Title: "hello from go"})
  52. }
  53. type ErrorRsp struct {
  54. Message string `json:"message"`
  55. }
  56. func (self *HttpServer) getDashboard(c *gin.Context) {
  57. id := c.Params.ByName("id")
  58. dash, err := self.store.GetById(id)
  59. if err != nil {
  60. c.JSON(404, &ErrorRsp{Message: "Dashboard not found"})
  61. return
  62. }
  63. c.JSON(200, dash.Data)
  64. }
  65. func (self *HttpServer) renderToPng(c *gin.Context) {
  66. qs := c.Request.URL.Query()
  67. url := qs["url"][0]
  68. pngPath, err := self.renderer.RenderToPng(url)
  69. if err != nil {
  70. c.HTML(500, "error.html", nil)
  71. }
  72. c.File(pngPath)
  73. }
  74. func (self *HttpServer) search(c *gin.Context) {
  75. query := c.Params.ByName("q")
  76. results, err := self.store.Query(query)
  77. if err != nil {
  78. c.JSON(500, &ErrorRsp{Message: "Search error"})
  79. return
  80. }
  81. c.JSON(200, results)
  82. }
  83. func (self *HttpServer) postDashboard(c *gin.Context) {
  84. var command saveDashboardCommand
  85. if c.EnsureBody(&command) {
  86. err := self.store.Save(&models.Dashboard{Data: command.Dashboard})
  87. if err == nil {
  88. c.JSON(200, gin.H{"status": "saved"})
  89. return
  90. }
  91. }
  92. c.JSON(500, gin.H{"error": "bad request"})
  93. }