diff --git a/.travis.yml b/.travis.yml index fb08ba4..862a283 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ go: arch: - amd64 - arm64 - - ppc64le os: - windows diff --git a/config.json b/config.json index 35fc329..f142541 100644 --- a/config.json +++ b/config.json @@ -5,4 +5,4 @@ "IMG_PATH": "/path/to/pics", "EXHAUST_PATH": "", "ALLOWED_TYPES": ["jpg","png","jpeg","bmp","gif"] -} +} \ No newline at end of file diff --git a/encoder.go b/encoder.go index e79ffdb..07574bc 100644 --- a/encoder.go +++ b/encoder.go @@ -3,21 +3,24 @@ package main import ( "bytes" "errors" - "fmt" - "github.com/chai2010/webp" - "golang.org/x/image/bmp" "image" "image/gif" "image/jpeg" "image/png" "io/ioutil" - "log" "path" "strings" + + log "github.com/sirupsen/logrus" + + "github.com/chai2010/webp" + "golang.org/x/image/bmp" ) func WebpEncoder(p1, p2 string, quality float32, Log bool, c chan int) (err error) { // if convert fails, return error; success nil + + log.Debugf("target: %s with quality of %f", path.Base(p1), quality) var buf bytes.Buffer var img image.Image @@ -36,30 +39,31 @@ func WebpEncoder(p1, p2 string, quality float32, Log bool, c chan int) (err erro img, _ = bmp.Decode(bytes.NewReader(data)) } else if strings.Contains(contentType, "gif") { // TODO: need to support animated webp + log.Warn("Gif support is not perfect!") img, _ = gif.Decode(bytes.NewReader(data)) } if img == nil { msg := "image file " + path.Base(p1) + " is corrupted or not supported" - log.Println(msg) + log.Debug(msg) err = errors.New(msg) ChanErr(c) return } if err = webp.Encode(&buf, img, &webp.Options{Lossless: false, Quality: quality}); err != nil { - log.Println(err) + log.Error(err) ChanErr(c) return } if err = ioutil.WriteFile(p2, buf.Bytes(), 0755); err != nil { - log.Println(err) + log.Error(err) ChanErr(c) return } if Log { - fmt.Printf("Save to %s ok\n", p2) + log.Info("Save to " + p2 + " ok!\n") } ChanErr(c) diff --git a/go.mod b/go.mod index dc9e825..c5844a6 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,6 @@ go 1.13 require ( github.com/chai2010/webp v1.1.0 github.com/gofiber/fiber v1.4.0 + github.com/sirupsen/logrus v1.4.2 golang.org/x/image v0.0.0-20200119044424-58c23975cae1 ) diff --git a/helper.go b/helper.go index 7f7f29d..6ede512 100644 --- a/helper.go +++ b/helper.go @@ -2,6 +2,7 @@ package main import ( "fmt" + log "github.com/sirupsen/logrus" "net/http" "os" "path" @@ -38,6 +39,7 @@ func ImageExists(filename string) bool { if os.IsNotExist(err) { return false } + log.Debugf("file %s exists!", filename) return !info.IsDir() } @@ -45,7 +47,7 @@ func GenWebpAbs(RawImagePath string, ExhaustPath string, ImgFilename string, req // get file mod time STAT, err := os.Stat(RawImagePath) if err != nil { - fmt.Println(err.Error()) + log.Error(err.Error()) } ModifiedTime := STAT.ModTime().Unix() // webpFilename: abc.jpg.png -> abc.jpg.png1582558990.webp diff --git a/prefetch.go b/prefetch.go index 30d513b..f0f10bf 100644 --- a/prefetch.go +++ b/prefetch.go @@ -3,20 +3,23 @@ package main import ( "bufio" "fmt" - "log" "os" "path" "path/filepath" "strconv" "strings" + + log "github.com/sirupsen/logrus" ) func PrefetchImages(confImgPath string, ExhaustPath string, QUALITY string) { - fmt.Println(`Prefetch will convert all your images to webp, it may take some time and consume a lot of CPU resource. Do you want to proceed(Y/n)`) + fmt.Println(`Prefetch will convert all your images to webp, +it may take some time and consume a lot of CPU resource. Do you want to proceed(Y/n)`) + reader := bufio.NewReader(os.Stdin) char, _, _ := reader.ReadRune() //y Y enter // maximum ongoing prefetch is depending on your core of CPU - log.Printf("Prefetching using %d cores", jobs) + log.Infof("Prefetching using %d cores", jobs) var finishChan = make(chan int, jobs) for i := 0; i < jobs; i++ { finishChan <- 0 @@ -42,7 +45,7 @@ func PrefetchImages(confImgPath string, ExhaustPath string, QUALITY string) { return nil }) if err != nil { - log.Println(err) + log.Debug(err) } } diff --git a/router.go b/router.go index 1e2c5f8..5c3f4c6 100644 --- a/router.go +++ b/router.go @@ -1,13 +1,14 @@ package main import ( - "fmt" - "github.com/gofiber/fiber" + log "github.com/sirupsen/logrus" "os" "path" "path/filepath" "strconv" "strings" + + "github.com/gofiber/fiber" ) func Convert(ImgPath string, ExhaustPath string, AllowedTypes []string, QUALITY string) func(c *fiber.Ctx) { @@ -21,9 +22,11 @@ func Convert(ImgPath string, ExhaustPath string, AllowedTypes []string, QUALITY UA := c.Get("User-Agent") if strings.Contains(UA, "Safari") && !strings.Contains(UA, "Chrome") && !strings.Contains(UA, "Firefox") { + log.Info("A Safari use has arrived...") c.SendFile(RawImageAbs) return } + log.Debugf("Incoming connection from %s@%s with %s", UA, c.IP(), ImgFilename) // check ext // TODO: may remove this function. Check in Nginx. @@ -39,19 +42,25 @@ func Convert(ImgPath string, ExhaustPath string, AllowedTypes []string, QUALITY } } if !allowed { - c.Send("File extension not allowed!") - c.SendStatus(403) + msg := "File extension not allowed! " + ImgFilename + log.Warn(msg) + c.Send(msg) + if ImageExists(RawImageAbs) { + c.SendFile(RawImageAbs) + } return } // Check the original image for existence, if !ImageExists(RawImageAbs) { - c.Send("Image not found!") + msg := "Image not found!" + c.Send(msg) + log.Warn(msg) c.SendStatus(404) return } - cwd, WebpAbsPath := GenWebpAbs(RawImageAbs, ExhaustPath, ImgFilename, reqURI) + _, WebpAbsPath := GenWebpAbs(RawImageAbs, ExhaustPath, ImgFilename, reqURI) if ImageExists(WebpAbsPath) { finalFile = WebpAbsPath @@ -59,10 +68,10 @@ func Convert(ImgPath string, ExhaustPath string, AllowedTypes []string, QUALITY // we don't have abc.jpg.png1582558990.webp // delete the old pic and convert a new one. // /home/webp_server/exhaust/path/to/tsuki.jpg.1582558990.webp - destHalfFile := path.Clean(path.Join(cwd, "exhaust", path.Dir(reqURI), ImgFilename)) + destHalfFile := path.Clean(path.Join(WebpAbsPath, path.Dir(reqURI), ImgFilename)) matches, err := filepath.Glob(destHalfFile + "*") if err != nil { - fmt.Println(err.Error()) + log.Error(err.Error()) } else { // /home/webp_server/exhaust/path/to/tsuki.jpg.1582558100.webp <- older ones will be removed // /home/webp_server/exhaust/path/to/tsuki.jpg.1582558990.webp <- keep the latest one @@ -79,7 +88,7 @@ func Convert(ImgPath string, ExhaustPath string, AllowedTypes []string, QUALITY err = WebpEncoder(RawImageAbs, WebpAbsPath, float32(q), true, nil) if err != nil { - fmt.Println(err) + log.Error(err) c.SendStatus(400) c.Send("Bad file!") return diff --git a/scripts/webp_server.spec b/scripts/webp_server.spec index 10253de..68edd3d 100644 --- a/scripts/webp_server.spec +++ b/scripts/webp_server.spec @@ -1,5 +1,5 @@ Name: webp-server -Version: 0.0.4 +Version: 0.1.1 Release: 1%{?dist} Summary: Go version of WebP Server. A tool that will serve your JPG/PNGs as WebP format with compression, on-the-fly. diff --git a/update.go b/update.go index 137d3b7..507dbd2 100644 --- a/update.go +++ b/update.go @@ -4,17 +4,18 @@ import ( "encoding/json" "fmt" "io/ioutil" - "log" "net/http" "os" "path" "runtime" + + log "github.com/sirupsen/logrus" ) func autoUpdate() { defer func() { if err := recover(); err != nil { - log.Println("Download error.", err) + log.Error("Download error.", err) } }() @@ -23,16 +24,16 @@ func autoUpdate() { TagName string `json:"tag_name"` } var res Result + log.Debugf("Requesting to %s", api) resp1, _ := http.Get(api) data1, _ := ioutil.ReadAll(resp1.Body) _ = json.Unmarshal(data1, &res) - var gitVersion = res.TagName if gitVersion > version { - log.Printf("Time to update! New version %s found!", gitVersion) + log.Infof("Time to update! New version %s found", gitVersion) } else { - log.Println("No new version found.") + log.Debug("No new version found.") return } @@ -41,11 +42,10 @@ func autoUpdate() { filename += ".exe" } var releaseUrl = "https://github.com/webp-sh/webp_server_go/releases/latest/download/" + filename - log.Println("Downloading binary...") + log.Info("Downloading binary to update...") resp, _ := http.Get(releaseUrl) if resp.StatusCode != 200 { - log.Printf("%s-%s not found on release. "+ - "Contact developers to supply your version", runtime.GOOS, runtime.GOARCH) + log.Debug("%s-%s not found on release.", runtime.GOOS, runtime.GOARCH) return } data, _ := ioutil.ReadAll(resp.Body) @@ -54,7 +54,7 @@ func autoUpdate() { err := ioutil.WriteFile(path.Join("update", filename), data, 0755) if err == nil { - log.Println("Update complete. Please find your binary from update directory.") + log.Info("Update complete. Please find your binary from update directory.") } _ = resp.Body.Close() } diff --git a/webp-server.go b/webp-server.go index 73a9170..6edb880 100644 --- a/webp-server.go +++ b/webp-server.go @@ -4,12 +4,12 @@ import ( "encoding/json" "flag" "fmt" - "log" "os" "path" "runtime" "github.com/gofiber/fiber" + log "github.com/sirupsen/logrus" ) type Config struct { @@ -21,13 +21,14 @@ type Config struct { ExhaustPath string `json:"EXHAUST_PATH"` } -const version = "0.1.0" +const version = "0.1.1" var configPath string var prefetch bool var jobs int var dumpConfig bool var dumpSystemd bool +var verboseMode bool const sampleConfig = ` { @@ -36,7 +37,7 @@ const sampleConfig = ` "QUALITY": "80", "IMG_PATH": "/path/to/pics", "EXHAUST_PATH": "", - "ALLOWED_TYPES": ["jpg","png","jpeg","bmp","gif"] + "ALLOWED_TYPES": ["jpg","png","jpeg","bmp"] }` const sampleSystemd = ` [Unit] @@ -54,7 +55,6 @@ ExecReload=/bin/kill -HUP $MAINPID Restart=always RestartSec=3s - [Install] WantedBy=multi-user.target` @@ -67,6 +67,11 @@ func loadConfig(path string) Config { defer jsonObject.Close() decoder := json.NewDecoder(jsonObject) _ = decoder.Decode(&config) + _, err = os.Stat(config.ImgPath) + if err != nil { + log.Fatalf("Your image path %s is incorrect.Please check and confirm.", config.ImgPath) + } + return config } @@ -76,7 +81,27 @@ func init() { flag.IntVar(&jobs, "jobs", runtime.NumCPU(), "Prefetch thread, default is all.") flag.BoolVar(&dumpConfig, "dump-config", false, "Print sample config.json") flag.BoolVar(&dumpSystemd, "dump-systemd", false, "Print sample systemd service file.") + flag.BoolVar(&verboseMode, "v", false, "Verbose, print out debug info.") flag.Parse() + // Logrus + log.SetOutput(os.Stdout) + log.SetReportCaller(true) + Formatter := &log.TextFormatter{ + EnvironmentOverrideColors: true, + FullTimestamp: true, + TimestampFormat: "2006-01-02 15:04:05", + CallerPrettyfier: func(f *runtime.Frame) (string, string) { + return fmt.Sprintf("[%s()]", f.Function), "" + }, + } + log.SetFormatter(Formatter) + + if verboseMode { + log.SetLevel(log.DebugLevel) + log.Debug("Debug mode is enable!") + } else { + log.SetLevel(log.InfoLevel) + } } func main() { @@ -116,8 +141,7 @@ func main() { ListenAddress := HOST + ":" + PORT // Server Info - ServerInfo := "WebP Server " + version + " is running at " + ListenAddress - fmt.Println(ServerInfo) + log.Infof("WebP Server %s %s", version, ListenAddress) app.Get("/*", Convert(confImgPath, ExhaustPath, AllowedTypes, QUALITY)) app.Listen(ListenAddress)