diff --git a/.gitignore b/.gitignore index 2c8c1e5..807f10c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,4 @@ # vendor/ data/code/*.go data/images/*.png -code2img -.idea + diff --git a/cmd/code2img/main.go b/cmd/code2img/main.go new file mode 100644 index 0000000..fae604a --- /dev/null +++ b/cmd/code2img/main.go @@ -0,0 +1,81 @@ +// Copyright 2021 The golang.design Initiative authors. +// All rights reserved. Use of this source code is governed +// by a GNU GPL-3.0 license that can be found in the LICENSE file. +// +// Written by Changkun Ou + +package main + +import ( + "context" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" + "golang.design/x/code2img" +) + +func main() { + router := gin.Default() + router.Static("/api/v1/code2img/data/code", "./data/code") + router.Static("/api/v1/code2img/data/images", "./data/images") + router.POST("/api/v1/code2img", func(c *gin.Context) { + b := struct { + Code string `json:"code"` + }{} + if err := c.ShouldBindJSON(&b); err != nil { + c.String(http.StatusBadRequest, fmt.Sprintf("Error: %s", err)) + return + } + id := uuid.New().String() + gofile := "./data/code/" + id + ".go" + + err := ioutil.WriteFile(gofile, []byte(b.Code), os.ModePerm) + if err != nil { + log.Printf("[%s]: write file error %v", gofile, err) + c.String(http.StatusBadRequest, fmt.Sprintf("Error: %s", err)) + return + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + + buf, err := code2img.Render(ctx, b.Code) + if err != nil { + c.String(http.StatusBadRequest, fmt.Sprintf("Error: %s", err)) + return + } + imgfile := "./data/images/" + id + ".png" + if err := ioutil.WriteFile(imgfile, buf, os.ModePerm); err != nil { + log.Printf("[%s]: write screenshot error %v", imgfile, err) + return + } + c.String(http.StatusOK, "https://golang.design/api/v1/code2img/data/images/"+id+".png") + }) + + s := &http.Server{Addr: ":8080", Handler: router} + go func() { + if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed { + log.Fatalf("listen: %s\n", err) + } + }() + + quit := make(chan os.Signal) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit + log.Println("shutting down...") + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := s.Shutdown(ctx); err != nil { + log.Fatal("forced to shutdown: ", err) + } + log.Println("server exiting, good bye!") +} diff --git a/go.mod b/go.mod index 2339750..f9a4403 100644 --- a/go.mod +++ b/go.mod @@ -6,5 +6,5 @@ require ( github.com/chromedp/cdproto v0.0.0-20200116234248-4da64dd111ac github.com/chromedp/chromedp v0.5.3 github.com/gin-gonic/gin v1.6.3 - github.com/google/uuid v1.1.2 + github.com/google/uuid v1.2.0 ) diff --git a/go.sum b/go.sum index 1194fa3..0269001 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,8 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08 h1:V0an7KRw92wmJysvFvtqtKMAPmvS5O0jtB0nYo6t+gs= diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go index b174616..b404f4b 100644 --- a/vendor/github.com/google/uuid/hash.go +++ b/vendor/github.com/google/uuid/hash.go @@ -26,8 +26,8 @@ var ( // NewMD5 and NewSHA1. func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { h.Reset() - h.Write(space[:]) - h.Write(data) + h.Write(space[:]) //nolint:errcheck + h.Write(data) //nolint:errcheck s := h.Sum(nil) var uuid UUID copy(uuid[:], s) diff --git a/vendor/github.com/google/uuid/sql.go b/vendor/github.com/google/uuid/sql.go index f326b54..2e02ec0 100644 --- a/vendor/github.com/google/uuid/sql.go +++ b/vendor/github.com/google/uuid/sql.go @@ -9,7 +9,7 @@ import ( "fmt" ) -// Scan implements sql.Scanner so UUIDs can be read from databases transparently +// Scan implements sql.Scanner so UUIDs can be read from databases transparently. // Currently, database types that map to string and []byte are supported. Please // consult database-specific driver documentation for matching types. func (uuid *UUID) Scan(src interface{}) error { diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index 524404c..60d26bb 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -35,6 +35,12 @@ const ( var rander = rand.Reader // random function +type invalidLengthError struct{ len int } + +func (err invalidLengthError) Error() string { + return fmt.Sprintf("invalid UUID length: %d", err.len) +} + // Parse decodes s into a UUID or returns an error. Both the standard UUID // forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the @@ -68,7 +74,7 @@ func Parse(s string) (UUID, error) { } return uuid, nil default: - return uuid, fmt.Errorf("invalid UUID length: %d", len(s)) + return uuid, invalidLengthError{len(s)} } // s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx @@ -112,7 +118,7 @@ func ParseBytes(b []byte) (UUID, error) { } return uuid, nil default: - return uuid, fmt.Errorf("invalid UUID length: %d", len(b)) + return uuid, invalidLengthError{len(b)} } // s is now at least 36 bytes long // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go index c110465..86160fb 100644 --- a/vendor/github.com/google/uuid/version4.go +++ b/vendor/github.com/google/uuid/version4.go @@ -14,6 +14,14 @@ func New() UUID { return Must(NewRandom()) } +// NewString creates a new random UUID and returns it as a string or panics. +// NewString is equivalent to the expression +// +// uuid.New().String() +func NewString() string { + return Must(NewRandom()).String() +} + // NewRandom returns a Random (Version 4) UUID. // // The strength of the UUIDs is based on the strength of the crypto/rand diff --git a/vendor/modules.txt b/vendor/modules.txt index 26ad9e3..19a4234 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -78,7 +78,7 @@ github.com/gobwas/ws github.com/gobwas/ws/wsutil # github.com/golang/protobuf v1.3.3 github.com/golang/protobuf/proto -# github.com/google/uuid v1.1.2 +# github.com/google/uuid v1.2.0 ## explicit github.com/google/uuid # github.com/json-iterator/go v1.1.9