From 890bc10096657f1dda49595cd7351a3fb9586a0c Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Mon, 21 Dec 2020 00:17:35 +0800 Subject: [PATCH] Update PNG output to match PHP impl. better --- results/telemetry.go | 97 +++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/results/telemetry.go b/results/telemetry.go index cc9f3ff..24072cb 100644 --- a/results/telemetry.go +++ b/results/telemetry.go @@ -42,11 +42,15 @@ var ( ipv6Regex = regexp.MustCompile(`(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))`) hostnameRegex = regexp.MustCompile(`"hostname":"([^\\\\"]|\\\\")*"`) - fontLight, fontBold *truetype.Font - labelFace, valueFace, smallLabelFace, orgFace, watermarkFace font.Face + fontLight, fontBold *truetype.Font + pingJitterLabelFace, upDownLabelFace, pingJitterValueFace, upDownValueFace, smallLabelFace, ispFace, watermarkFace font.Face - canvasWidth, canvasHeight = 800, 600 + canvasWidth, canvasHeight = 500, 286 dpi = 150.0 + topOffset = 10 + middleOffset = topOffset + 5 + bottomOffset = middleOffset - 10 + ispOffset = bottomOffset + 8 colorLabel = image.NewUniform(color.RGBA{40, 40, 40, 255}) colorDownload = image.NewUniform(color.RGBA{96, 96, 170, 255}) colorUpload = image.NewUniform(color.RGBA{96, 96, 96, 255}) @@ -99,32 +103,44 @@ func Initialize(c *config.Config) { fontBold = f } - labelFace = truetype.NewFace(fontBold, &truetype.Options{ - Size: 26, + pingJitterLabelFace = truetype.NewFace(fontBold, &truetype.Options{ + Size: 12, DPI: dpi, Hinting: font.HintingFull, }) - valueFace = truetype.NewFace(fontLight, &truetype.Options{ - Size: 36, + upDownLabelFace = truetype.NewFace(fontBold, &truetype.Options{ + Size: 14, + DPI: dpi, + Hinting: font.HintingFull, + }) + + pingJitterValueFace = truetype.NewFace(fontLight, &truetype.Options{ + Size: 16, + DPI: dpi, + Hinting: font.HintingFull, + }) + + upDownValueFace = truetype.NewFace(fontLight, &truetype.Options{ + Size: 18, DPI: dpi, Hinting: font.HintingFull, }) smallLabelFace = truetype.NewFace(fontBold, &truetype.Options{ - Size: 20, + Size: 10, DPI: dpi, Hinting: font.HintingFull, }) - orgFace = truetype.NewFace(fontBold, &truetype.Options{ - Size: 16, + ispFace = truetype.NewFace(fontBold, &truetype.Options{ + Size: 8, DPI: dpi, Hinting: font.HintingFull, }) watermarkFace = truetype.NewFace(fontLight, &truetype.Options{ - Size: 14, + Size: 6, DPI: dpi, Hinting: font.HintingFull, }) @@ -215,7 +231,7 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) { drawer := &font.Drawer{ Dst: canvas, - Face: labelFace, + Face: pingJitterLabelFace, } drawer.Src = colorLabel @@ -223,40 +239,41 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) { // labels p := drawer.MeasureString(labelPing) x := canvasWidth/4 - p.Round()/2 - drawer.Dot = freetype.Pt(x, canvasHeight/10) + drawer.Dot = freetype.Pt(x, canvasHeight/10+topOffset) drawer.DrawString(labelPing) p = drawer.MeasureString(labelJitter) x = canvasWidth*3/4 - p.Round()/2 - drawer.Dot = freetype.Pt(x, canvasHeight/10) + drawer.Dot = freetype.Pt(x, canvasHeight/10+topOffset) drawer.DrawString(labelJitter) + drawer.Face = upDownLabelFace p = drawer.MeasureString(labelDownload) x = canvasWidth/4 - p.Round()/2 - drawer.Dot = freetype.Pt(x, canvasHeight/2) + drawer.Dot = freetype.Pt(x, canvasHeight/2-middleOffset) drawer.DrawString(labelDownload) p = drawer.MeasureString(labelUpload) x = canvasWidth*3/4 - p.Round()/2 - drawer.Dot = freetype.Pt(x, canvasHeight/2) + drawer.Dot = freetype.Pt(x, canvasHeight/2-middleOffset) drawer.DrawString(labelUpload) drawer.Face = smallLabelFace drawer.Src = colorMeasure p = drawer.MeasureString(labelMbps) x = canvasWidth/4 - p.Round()/2 - drawer.Dot = freetype.Pt(x, canvasHeight*8/10) + drawer.Dot = freetype.Pt(x, canvasHeight*8/10-middleOffset) drawer.DrawString(labelMbps) p = drawer.MeasureString(labelMbps) x = canvasWidth*3/4 - p.Round()/2 - drawer.Dot = freetype.Pt(x, canvasHeight*8/10) + drawer.Dot = freetype.Pt(x, canvasHeight*8/10-middleOffset) drawer.DrawString(labelMbps) msLength := drawer.MeasureString(labelMS) // ping value - drawer.Face = valueFace + drawer.Face = pingJitterValueFace pingValue := strings.Split(record.Ping, ".")[0] p = drawer.MeasureString(pingValue) @@ -271,13 +288,12 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) { drawer.DrawString(labelMS) // jitter value - drawer.Face = valueFace - jitterValue := strings.Split(record.Jitter, ".")[0] - p = drawer.MeasureString(jitterValue) + drawer.Face = pingJitterValueFace + p = drawer.MeasureString(record.Jitter) x = canvasWidth*3/4 - (p.Round()+msLength.Round())/2 drawer.Dot = freetype.Pt(x, canvasHeight*11/40) drawer.Src = colorJitter - drawer.DrawString(jitterValue) + drawer.DrawString(record.Jitter) drawer.Face = smallLabelFace x = x + p.Round() drawer.Dot = freetype.Pt(x, canvasHeight*11/40) @@ -285,17 +301,17 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) { drawer.DrawString(labelMS) // download value - drawer.Face = valueFace + drawer.Face = upDownValueFace p = drawer.MeasureString(record.Download) x = canvasWidth/4 - p.Round()/2 - drawer.Dot = freetype.Pt(x, canvasHeight*27/40) + drawer.Dot = freetype.Pt(x, canvasHeight*27/40-middleOffset) drawer.Src = colorDownload drawer.DrawString(record.Download) // upload value p = drawer.MeasureString(record.Upload) x = canvasWidth*3/4 - p.Round()/2 - drawer.Dot = freetype.Pt(x, canvasHeight*27/40) + drawer.Dot = freetype.Pt(x, canvasHeight*27/40-middleOffset) drawer.Src = colorUpload drawer.DrawString(record.Upload) @@ -310,28 +326,33 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) { drawer.Src = colorWatermark p = drawer.MeasureString(watermark) x = canvasWidth - p.Round() - 5 - drawer.Dot = freetype.Pt(x, canvasHeight-10) + drawer.Dot = freetype.Pt(x, canvasHeight-bottomOffset) drawer.DrawString(watermark) + // timestamp + ts := record.Timestamp.Format("2006-01-02 15:04:05") + p = drawer.MeasureString(ts) + drawer.Dot = freetype.Pt(8, canvasHeight-bottomOffset) + drawer.DrawString(ts) + // separator for i := canvas.Bounds().Min.X; i < canvas.Bounds().Max.X; i++ { - canvas.Set(i, canvasHeight-ctx.PointToFixed(14).Round()-10, colorSeparator) + canvas.Set(i, canvasHeight-ctx.PointToFixed(6).Round()-bottomOffset, colorSeparator) } // ISP info - drawer.Face = orgFace + drawer.Face = ispFace drawer.Src = colorISP - drawer.Dot = freetype.Pt(6, canvasHeight-ctx.PointToFixed(14).Round()-15) - if result.RawISPInfo.Organization != "" { - removeRegexp := regexp.MustCompile(`AS\d+\s`) - org := removeRegexp.ReplaceAllString(result.RawISPInfo.Organization, "") - if result.RawISPInfo.Country != "" { - org += ", " + result.RawISPInfo.Country + drawer.Dot = freetype.Pt(8, canvasHeight-ctx.PointToFixed(6).Round()-ispOffset) + var ispString string + if strings.Contains(result.ProcessedString, "-") { + str := strings.SplitN(result.ProcessedString, "-", 2) + if strings.Contains(str[0], "(") { + str = strings.SplitN(str[0], "(", 2) } - drawer.DrawString(org) - } else { - drawer.DrawString(result.ProcessedString) + ispString = str[0] } + drawer.DrawString("ISP: " + ispString) w.Header().Set("Content-Disposition", "inline; filename="+uuid+".png") w.Header().Set("Content-Type", "image/png")