Commit 1a9aaa41 by Torkel Ödegaard

feat(server side png rendering): added timezone parameter for server side…

feat(server side png rendering): added timezone parameter for server side rendering, refactoring PR #7264
parent 830491fa
...@@ -14,12 +14,12 @@ func RenderToPng(c *middleware.Context) { ...@@ -14,12 +14,12 @@ func RenderToPng(c *middleware.Context) {
queryParams := fmt.Sprintf("?%s", c.Req.URL.RawQuery) queryParams := fmt.Sprintf("?%s", c.Req.URL.RawQuery)
renderOpts := &renderer.RenderOpts{ renderOpts := &renderer.RenderOpts{
Path: c.Params("*") + queryParams, Path: c.Params("*") + queryParams,
Width: queryReader.Get("width", "800"), Width: queryReader.Get("width", "800"),
Height: queryReader.Get("height", "400"), Height: queryReader.Get("height", "400"),
OrgId: c.OrgId, OrgId: c.OrgId,
Timeout: queryReader.Get("timeout", "30"), Timeout: queryReader.Get("timeout", "30"),
TimeOffset: queryReader.Get("timeOffset", ""), Timezone: queryReader.Get("tz", ""),
} }
pngPath, err := renderer.RenderToPng(renderOpts) pngPath, err := renderer.RenderToPng(renderOpts)
......
...@@ -6,41 +6,39 @@ import ( ...@@ -6,41 +6,39 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp"
"runtime" "runtime"
"time" "time"
"strconv" "strconv"
"strings"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
"strings"
) )
type RenderOpts struct { type RenderOpts struct {
Path string Path string
Width string Width string
Height string Height string
Timeout string Timeout string
OrgId int64 OrgId int64
TimeOffset string Timezone string
} }
var rendererLog log.Logger = log.New("png-renderer") var rendererLog log.Logger = log.New("png-renderer")
func isoTimeOffsetToPosixTz(isoOffset string) string { func isoTimeOffsetToPosixTz(isoOffset string) string {
re := regexp.MustCompile(`^([+-])([0-1][0-9]|2[0-4])([0-5][0-9])$`) // invert offset
results := re.FindStringSubmatch(isoOffset) if strings.HasPrefix(isoOffset, "UTC+") {
if results == nil { return strings.Replace(isoOffset, "UTC+", "UTC-", 1)
return ""
} }
sign := "+" if strings.HasPrefix(isoOffset, "UTC-") {
if results[1] == "+" { return strings.Replace(isoOffset, "UTC-", "UTC+", 1)
sign = "-" // "+" is west and "-" is east in POSIX TZ
} }
return fmt.Sprintf("SOMEWHERE%s%s:%s", sign, results[2], results[3]) return isoOffset
} }
func appendEnviron(baseEnviron []string, name string, value string) []string { func appendEnviron(baseEnviron []string, name string, value string) []string {
...@@ -100,10 +98,9 @@ func RenderToPng(params *RenderOpts) (string, error) { ...@@ -100,10 +98,9 @@ func RenderToPng(params *RenderOpts) (string, error) {
return "", err return "", err
} }
tz := isoTimeOffsetToPosixTz(params.TimeOffset) if params.Timezone != "" {
if tz != "" {
baseEnviron := os.Environ() baseEnviron := os.Environ()
cmd.Env = appendEnviron(baseEnviron, "TZ", tz) cmd.Env = appendEnviron(baseEnviron, "TZ", isoTimeOffsetToPosixTz(params.Timezone))
} }
err = cmd.Start() err = cmd.Start()
......
...@@ -69,15 +69,6 @@ ...@@ -69,15 +69,6 @@
</div> </div>
</script> </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"> <script type="text/ng-template" id="shareLink.html">
<div class="share-modal-header"> <div class="share-modal-header">
<div class="share-modal-big-icon"> <div class="share-modal-big-icon">
...@@ -100,7 +91,6 @@ ...@@ -100,7 +91,6 @@
</div> </div>
</div> </div>
</div> </div>
<div ng-include src="'renderImageOptions.html'"></div>
<div class="gf-form" ng-show="modeSharePanel"> <div class="gf-form" ng-show="modeSharePanel">
<a href="{{imageUrl}}" target="_blank"><i class="fa fa-camera"></i> Direct link rendered image</a> <a href="{{imageUrl}}" target="_blank"><i class="fa fa-camera"></i> Direct link rendered image</a>
</div> </div>
......
define(['angular', define(['angular',
'lodash', 'lodash',
'jquery', 'jquery',
'moment',
'require', 'require',
'app/core/config', 'app/core/config',
], ],
function (angular, _, $, require, config) { function (angular, _, $, moment, require, config) {
'use strict'; 'use strict';
var module = angular.module('grafana.controllers'); var module = angular.module('grafana.controllers');
module.controller('ShareModalCtrl', function($scope, $rootScope, $location, $timeout, timeSrv, templateSrv, linkSrv) { 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.editor = { index: $scope.tabIndex || 0};
$scope.init = function() { $scope.init = function() {
...@@ -83,13 +84,7 @@ function (angular, _, $, require, config) { ...@@ -83,13 +84,7 @@ function (angular, _, $, require, config) {
$scope.imageUrl = soloUrl.replace(config.appSubUrl + '/dashboard-solo/', config.appSubUrl + '/render/dashboard-solo/'); $scope.imageUrl = soloUrl.replace(config.appSubUrl + '/dashboard-solo/', config.appSubUrl + '/render/dashboard-solo/');
$scope.imageUrl += '&width=1000'; $scope.imageUrl += '&width=1000';
$scope.imageUrl += '&height=500'; $scope.imageUrl += '&height=500';
if ($scope.options.browserTimeOffset) { $scope.imageUrl += '&tz=UTC' + encodeURIComponent(moment().format("Z"));
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);
}
}; };
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment