You've already forked speedtest-go
							
							Update PNG output to match PHP impl. better
This commit is contained in:
		@@ -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,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	smallLabelFace = truetype.NewFace(fontBold, &truetype.Options{
 | 
			
		||||
		Size:    20,
 | 
			
		||||
		DPI:     dpi,
 | 
			
		||||
		Hinting: font.HintingFull,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	orgFace = truetype.NewFace(fontBold, &truetype.Options{
 | 
			
		||||
	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:    10,
 | 
			
		||||
		DPI:     dpi,
 | 
			
		||||
		Hinting: font.HintingFull,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	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")
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user