Browse Source

feat(server side png rendering): added timezone parameter for server side rendering, refactoring PR #7264

Torkel Ödegaard 9 years ago
parent
commit
1a9aaa4138

+ 6 - 6
pkg/api/render.go

@@ -14,12 +14,12 @@ func RenderToPng(c *middleware.Context) {
 	queryParams := fmt.Sprintf("?%s", c.Req.URL.RawQuery)
 
 	renderOpts := &renderer.RenderOpts{
-		Path:       c.Params("*") + queryParams,
-		Width:      queryReader.Get("width", "800"),
-		Height:     queryReader.Get("height", "400"),
-		OrgId:      c.OrgId,
-		Timeout:    queryReader.Get("timeout", "30"),
-		TimeOffset: queryReader.Get("timeOffset", ""),
+		Path:     c.Params("*") + queryParams,
+		Width:    queryReader.Get("width", "800"),
+		Height:   queryReader.Get("height", "400"),
+		OrgId:    c.OrgId,
+		Timeout:  queryReader.Get("timeout", "30"),
+		Timezone: queryReader.Get("tz", ""),
 	}
 
 	pngPath, err := renderer.RenderToPng(renderOpts)

+ 16 - 19
pkg/components/renderer/renderer.go

@@ -6,41 +6,39 @@ import (
 	"os"
 	"os/exec"
 	"path/filepath"
-	"regexp"
 	"runtime"
 	"time"
 
 	"strconv"
 
+	"strings"
+
 	"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/middleware"
 	"github.com/grafana/grafana/pkg/setting"
 	"github.com/grafana/grafana/pkg/util"
-	"strings"
 )
 
 type RenderOpts struct {
-	Path       string
-	Width      string
-	Height     string
-	Timeout    string
-	OrgId      int64
-	TimeOffset string
+	Path     string
+	Width    string
+	Height   string
+	Timeout  string
+	OrgId    int64
+	Timezone string
 }
 
 var rendererLog log.Logger = log.New("png-renderer")
 
 func isoTimeOffsetToPosixTz(isoOffset string) string {
-	re := regexp.MustCompile(`^([+-])([0-1][0-9]|2[0-4])([0-5][0-9])$`)
-	results := re.FindStringSubmatch(isoOffset)
-	if results == nil {
-		return ""
+	// invert offset
+	if strings.HasPrefix(isoOffset, "UTC+") {
+		return strings.Replace(isoOffset, "UTC+", "UTC-", 1)
 	}
-	sign := "+"
-	if results[1] == "+" {
-		sign = "-"  // "+" is west and "-" is east in POSIX TZ
+	if strings.HasPrefix(isoOffset, "UTC-") {
+		return strings.Replace(isoOffset, "UTC-", "UTC+", 1)
 	}
-	return fmt.Sprintf("SOMEWHERE%s%s:%s", sign, results[2], results[3])
+	return isoOffset
 }
 
 func appendEnviron(baseEnviron []string, name string, value string) []string {
@@ -100,10 +98,9 @@ func RenderToPng(params *RenderOpts) (string, error) {
 		return "", err
 	}
 
-	tz := isoTimeOffsetToPosixTz(params.TimeOffset)
-	if tz != "" {
+	if params.Timezone != "" {
 		baseEnviron := os.Environ()
-		cmd.Env = appendEnviron(baseEnviron, "TZ", tz)
+		cmd.Env = appendEnviron(baseEnviron, "TZ", isoTimeOffsetToPosixTz(params.Timezone))
 	}
 
 	err = cmd.Start()

+ 0 - 10
public/app/features/dashboard/partials/shareModal.html

@@ -69,15 +69,6 @@
 	</div>
 </script>
 
-<script type="text/ng-template" id="renderImageOptions.html">
-	<div class="gf-form-group">
-		<gf-form-switch class="gf-form"
-			label="Use browser time offset in image" label-class="width-18" switch-class="max-width-6"
-			checked="options.browserTimeOffset" on-change="buildUrl()">
-		</gf-form-switch>
-	</div>
-</script>
-
 <script type="text/ng-template" id="shareLink.html">
 	<div class="share-modal-header">
 		<div class="share-modal-big-icon">
@@ -100,7 +91,6 @@
 					</div>
 				</div>
 			</div>
-			<div ng-include src="'renderImageOptions.html'"></div>
 			<div class="gf-form" ng-show="modeSharePanel">
 				<a href="{{imageUrl}}" target="_blank"><i class="fa fa-camera"></i> Direct link rendered image</a>
 			</div>

+ 4 - 9
public/app/features/dashboard/shareModalCtrl.js

@@ -1,17 +1,18 @@
 define(['angular',
   'lodash',
   'jquery',
+  'moment',
   'require',
   'app/core/config',
 ],
-function (angular, _, $, require, config) {
+function (angular, _, $, moment, require, config) {
   'use strict';
 
   var module = angular.module('grafana.controllers');
 
   module.controller('ShareModalCtrl', function($scope, $rootScope, $location, $timeout, timeSrv, templateSrv, linkSrv) {
 
-    $scope.options = { forCurrent: true, includeTemplateVars: true, browserTimeOffset: false, theme: 'current' };
+    $scope.options = { forCurrent: true, includeTemplateVars: true, theme: 'current' };
     $scope.editor = { index: $scope.tabIndex || 0};
 
     $scope.init = function() {
@@ -83,13 +84,7 @@ function (angular, _, $, require, config) {
       $scope.imageUrl = soloUrl.replace(config.appSubUrl + '/dashboard-solo/', config.appSubUrl + '/render/dashboard-solo/');
       $scope.imageUrl += '&width=1000';
       $scope.imageUrl += '&height=500';
-      if ($scope.options.browserTimeOffset) {
-        var offsetMinutes = new Date().getTimezoneOffset(); // Negative if ahead of UTC
-        var sign = offsetMinutes < 0 ? '+' : '-';
-        var hours = ('0' + Math.abs(offsetMinutes) / 60).slice(-2);
-        var minutes = ('0' + Math.abs(offsetMinutes) % 60).slice(-2);
-        $scope.imageUrl += '&timeOffset=' + encodeURIComponent(sign + hours + minutes);
-      }
+      $scope.imageUrl += '&tz=UTC' + encodeURIComponent(moment().format("Z"));
     };
 
   });