Add support for image compression
parent
962818c931
commit
9ca7da9ae5
17
config.go
17
config.go
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
var (
|
||||
BlogUrl string
|
||||
MediaEndpointUrl string
|
||||
IgnoredWebmentionUrls []string
|
||||
SyndicationTargets []SyndicationTarget
|
||||
SelectedStorage Storage
|
||||
|
@ -16,7 +17,7 @@ var (
|
|||
SelectedCdn Cdn
|
||||
SelectedSocials Socials
|
||||
SelectedNotificationServices NotificationServices
|
||||
MediaEndpointUrl string
|
||||
SelectedImageCompression ImageCompression
|
||||
)
|
||||
|
||||
type SyndicationTarget struct {
|
||||
|
@ -39,6 +40,7 @@ type config struct {
|
|||
TelegramBotToken string `env:"TELEGRAM_BOT_TOKEN"`
|
||||
IgnoredWebmentionUrls []string `env:"WEBMENTION_IGNORED" envSeparator:","`
|
||||
SyndicationTargets []string `env:"SYNDICATION" envSeparator:","`
|
||||
TinifyKey string `env:"TINIFY_KEY"`
|
||||
}
|
||||
|
||||
func initConfig() (err error) {
|
||||
|
@ -138,5 +140,18 @@ func initConfig() (err error) {
|
|||
if SelectedNotificationServices == nil {
|
||||
log.Println("No notification services configured")
|
||||
}
|
||||
// Find configured image compression service (optional)
|
||||
SelectedImageCompression = func() ImageCompression {
|
||||
// Tinify
|
||||
if len(cfg.TinifyKey) > 0 {
|
||||
return &Tinify{
|
||||
key: cfg.TinifyKey,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
if SelectedImageCompression == nil {
|
||||
log.Println("no image compression configured")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -5,6 +5,7 @@ go 1.13
|
|||
require (
|
||||
github.com/caarlos0/env/v6 v6.1.0
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20190904012038-b33efeebc785+incompatible
|
||||
github.com/gwpp/tinify-go v0.0.0-20170613055357-77b9df15f343
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.7
|
||||
willnorris.com/go/webmention v0.0.0-20191104072158-c7fb13569b62
|
||||
|
|
2
go.sum
2
go.sum
|
@ -8,6 +8,8 @@ github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20190904012038-b33efeeb
|
|||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20190904012038-b33efeebc785+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/gwpp/tinify-go v0.0.0-20170613055357-77b9df15f343 h1:QbWv77mi5YeTWR3FxLqx5eeC2H0fUL07Kj2Uhza9/A8=
|
||||
github.com/gwpp/tinify-go v0.0.0-20170613055357-77b9df15f343/go.mod h1:FP1q8rlReJYgAj3zqyQfD745uokKzl0baffXAcxDcl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
tfgo "github.com/gwpp/tinify-go/tinify"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ImageCompression interface {
|
||||
Compress(url string) (location string, err error)
|
||||
}
|
||||
|
||||
// Tinify
|
||||
type Tinify struct {
|
||||
// API Key
|
||||
key string
|
||||
}
|
||||
|
||||
func (t Tinify) Compress(url string) (location string, err error) {
|
||||
fileExtension := func() string {
|
||||
spliced := strings.Split(url, ".")
|
||||
return spliced[len(spliced)-1]
|
||||
}()
|
||||
supportedTypes := []string{"jpg", "jpeg", "png"}
|
||||
sort.Strings(supportedTypes)
|
||||
i := sort.SearchStrings(supportedTypes, strings.ToLower(fileExtension))
|
||||
if !(i < len(supportedTypes) && supportedTypes[i] == strings.ToLower(fileExtension)) {
|
||||
err = errors.New("file not supported")
|
||||
return
|
||||
}
|
||||
tfgo.SetKey(t.key)
|
||||
s, e := tfgo.FromUrl(url)
|
||||
if e != nil {
|
||||
err = errors.New("failed to compress file")
|
||||
return
|
||||
}
|
||||
file, e := ioutil.TempFile("", "tiny-*."+fileExtension)
|
||||
if e != nil {
|
||||
err = errors.New("failed to create temporary file")
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
_ = os.Remove(file.Name())
|
||||
}()
|
||||
e = s.ToFile(file.Name())
|
||||
if e != nil {
|
||||
err = errors.New("failed to save compressed file")
|
||||
return
|
||||
}
|
||||
hashFile, e := os.Open(file.Name())
|
||||
defer func() { _ = hashFile.Close() }()
|
||||
if e != nil {
|
||||
err = errors.New("failed to open temporary file")
|
||||
return
|
||||
}
|
||||
fileName, err := getSHA256(hashFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
location, err = SelectedMediaStorage.Upload(fileName+"."+fileExtension, file)
|
||||
return
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
@ -44,14 +41,13 @@ func HandleMedia(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
hashFile, _, _ := r.FormFile("file")
|
||||
h := sha256.New()
|
||||
defer func() { _ = hashFile.Close() }()
|
||||
if _, err := io.Copy(h, hashFile); err != nil {
|
||||
fileName, err := getSHA256(hashFile)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte("Failed to calculate hash of file"))
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
fileName := fmt.Sprintf("%x", h.Sum(nil))
|
||||
fileExtension := filepath.Ext(header.Filename)
|
||||
if len(fileExtension) == 0 {
|
||||
// Find correct file extension if original filename does not contain one
|
||||
|
@ -67,9 +63,15 @@ func HandleMedia(w http.ResponseWriter, r *http.Request) {
|
|||
location, err := SelectedMediaStorage.Upload(fileName, file)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte("Failed to upload file"))
|
||||
_, _ = w.Write([]byte("Failed to upload original file"))
|
||||
return
|
||||
}
|
||||
if SelectedImageCompression != nil {
|
||||
compressedLocation, err := SelectedImageCompression.Compress(location)
|
||||
if err == nil && len(compressedLocation) > 0 {
|
||||
location = compressedLocation
|
||||
}
|
||||
}
|
||||
w.Header().Add("Location", location)
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
} else {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -33,3 +36,12 @@ func (b BunnyCdnStorage) Upload(fileName string, file multipart.File) (location
|
|||
}
|
||||
return b.baseLocation + fileName, nil
|
||||
}
|
||||
|
||||
func getSHA256(file multipart.File) (filename string, err error) {
|
||||
h := sha256.New()
|
||||
if _, e := io.Copy(h, file); e != nil {
|
||||
err = errors.New("failed to calculate hash of file")
|
||||
return
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue