mirror of
https://github.com/grafana/grafana.git
synced 2024-11-23 09:26:43 -06:00
Enable image rendering to use browser time offset
This commit is contained in:
parent
e5a6c523d7
commit
1bc55a2d38
@ -14,11 +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"),
|
||||
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", ""),
|
||||
}
|
||||
|
||||
pngPath, err := renderer.RenderToPng(renderOpts)
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
@ -15,18 +16,44 @@ import (
|
||||
"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
|
||||
Path string
|
||||
Width string
|
||||
Height string
|
||||
Timeout string
|
||||
OrgId int64
|
||||
TimeOffset 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 ""
|
||||
}
|
||||
sign := "+"
|
||||
if results[1] == "+" {
|
||||
sign = "-" // "+" is west and "-" is east in POSIX TZ
|
||||
}
|
||||
return fmt.Sprintf("SOMEWHERE%s%s:%s", sign, results[2], results[3])
|
||||
}
|
||||
|
||||
func appendEnviron(baseEnviron []string, name string, value string) []string {
|
||||
results := make([]string, 0)
|
||||
prefix := fmt.Sprintf("%s=", name)
|
||||
for _, v := range baseEnviron {
|
||||
if !strings.HasPrefix(v, prefix) {
|
||||
results = append(results, v)
|
||||
}
|
||||
}
|
||||
return append(results, fmt.Sprintf("%s=%s", name, value))
|
||||
}
|
||||
|
||||
func RenderToPng(params *RenderOpts) (string, error) {
|
||||
rendererLog.Info("Rendering", "path", params.Path)
|
||||
|
||||
@ -73,6 +100,12 @@ func RenderToPng(params *RenderOpts) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
tz := isoTimeOffsetToPosixTz(params.TimeOffset)
|
||||
if tz != "" {
|
||||
baseEnviron := os.Environ()
|
||||
cmd.Env = appendEnviron(baseEnviron, "TZ", tz)
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -69,6 +69,15 @@
|
||||
</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">
|
||||
@ -91,6 +100,7 @@
|
||||
</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>
|
||||
|
@ -10,7 +10,7 @@ function (angular, _, require, config) {
|
||||
|
||||
module.controller('ShareModalCtrl', function($scope, $rootScope, $location, $timeout, timeSrv, templateSrv, linkSrv) {
|
||||
|
||||
$scope.options = { forCurrent: true, includeTemplateVars: true, theme: 'current' };
|
||||
$scope.options = { forCurrent: true, includeTemplateVars: true, browserTimeOffset: false, theme: 'current' };
|
||||
$scope.editor = { index: $scope.tabIndex || 0};
|
||||
|
||||
$scope.init = function() {
|
||||
@ -82,6 +82,13 @@ 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);
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user