mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 08:05:43 -06:00
feat(server side png rendering): added timezone parameter for server side rendering, refactoring PR #7264
This commit is contained in:
parent
830491fa66
commit
1a9aaa4138
@ -19,7 +19,7 @@ func RenderToPng(c *middleware.Context) {
|
|||||||
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,17 +6,17 @@ 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 {
|
||||||
@ -25,22 +25,20 @@ type RenderOpts struct {
|
|||||||
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) {
|
|||||||
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 @@
|
|||||||
</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 @@
|
|||||||
</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>
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
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) {
|
|||||||
$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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user