|
|
@ -1,15 +1,13 @@ |
|
|
|
package main |
|
|
|
|
|
|
|
import ( |
|
|
|
"bytes" |
|
|
|
"encoding/json" |
|
|
|
"errors" |
|
|
|
"io" |
|
|
|
"io/ioutil" |
|
|
|
"net/http" |
|
|
|
"os" |
|
|
|
"sort" |
|
|
|
"strings" |
|
|
|
|
|
|
|
tfgo "codeberg.org/jlelse/tinify" |
|
|
|
) |
|
|
|
|
|
|
|
type ImageCompression interface { |
|
|
@ -34,27 +32,32 @@ func (t *Tinify) Compress(url string) (location string, err error) { |
|
|
|
err = errors.New("file not supported") |
|
|
|
return |
|
|
|
} |
|
|
|
// Shrink
|
|
|
|
shrinkedUrl, e := t.shrink(url) |
|
|
|
tfgo.SetKey(t.key) |
|
|
|
s, e := tfgo.FromUrl(url) |
|
|
|
if e != nil { |
|
|
|
err = errors.New("failed to compress file") |
|
|
|
return |
|
|
|
} |
|
|
|
// Create temp file
|
|
|
|
e = s.Resize(&tfgo.ResizeOption{ |
|
|
|
Method: tfgo.ResizeMethodScale, |
|
|
|
Width: 2000, |
|
|
|
}) |
|
|
|
if e != nil { |
|
|
|
err = errors.New("failed to resize file") |
|
|
|
return |
|
|
|
} |
|
|
|
file, e := ioutil.TempFile("", "tiny-*."+fileExtension) |
|
|
|
if e != nil { |
|
|
|
err = errors.New("failed to create temporary file") |
|
|
|
return |
|
|
|
} |
|
|
|
defer func() { |
|
|
|
// Cleanup
|
|
|
|
_ = file.Close() |
|
|
|
_ = os.Remove(file.Name()) |
|
|
|
}() |
|
|
|
// Resize and download image
|
|
|
|
e = t.resize(shrinkedUrl, file) |
|
|
|
e = s.ToFile(file.Name()) |
|
|
|
if e != nil { |
|
|
|
err = errors.New("failed to resize file or save compressed file") |
|
|
|
err = errors.New("failed to save compressed file") |
|
|
|
return |
|
|
|
} |
|
|
|
hashFile, e := os.Open(file.Name()) |
|
|
@ -70,71 +73,3 @@ func (t *Tinify) Compress(url string) (location string, err error) { |
|
|
|
location, err = SelectedMediaStorage.Upload(fileName+"."+fileExtension, file) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func (t *Tinify) shrink(source string) (string, error) { |
|
|
|
type Source struct { |
|
|
|
Url string `json:"url"` |
|
|
|
} |
|
|
|
data := struct { |
|
|
|
Source Source `json:"source"` |
|
|
|
}{ |
|
|
|
Source: Source{ |
|
|
|
Url: source, |
|
|
|
}, |
|
|
|
} |
|
|
|
body := new(bytes.Buffer) |
|
|
|
err := json.NewEncoder(body).Encode(data) |
|
|
|
if err != nil { |
|
|
|
return "", err |
|
|
|
} |
|
|
|
req, err := http.NewRequest("POST", "https://api.tinify.com/shrink", body) |
|
|
|
if err != nil { |
|
|
|
return "", err |
|
|
|
} |
|
|
|
req.SetBasicAuth("api", t.key) |
|
|
|
req.Header.Set("Content-Type", "application/json") |
|
|
|
resp, err := http.DefaultClient.Do(req) |
|
|
|
if err != nil { |
|
|
|
return "", err |
|
|
|
} |
|
|
|
if resp.StatusCode != 201 { |
|
|
|
return "", errors.New("not 201 response code") |
|
|
|
} |
|
|
|
return resp.Header.Get("Location"), nil |
|
|
|
} |
|
|
|
|
|
|
|
func (t *Tinify) resize(output string, file *os.File) error { |
|
|
|
type Resize struct { |
|
|
|
Method string `json:"method"` |
|
|
|
Width int `json:"width"` |
|
|
|
} |
|
|
|
data := struct { |
|
|
|
Resize Resize `json:"resize"` |
|
|
|
}{ |
|
|
|
Resize: Resize{ |
|
|
|
Method: "scale", |
|
|
|
Width: 2000, |
|
|
|
}, |
|
|
|
} |
|
|
|
body := new(bytes.Buffer) |
|
|
|
err := json.NewEncoder(body).Encode(data) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
req, err := http.NewRequest("POST", output, body) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
req.SetBasicAuth("api", t.key) |
|
|
|
req.Header.Set("Content-Type", "application/json") |
|
|
|
resp, err := http.DefaultClient.Do(req) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
if resp.StatusCode != 200 { |
|
|
|
return errors.New("not 201 response code") |
|
|
|
} |
|
|
|
defer resp.Body.Close() |
|
|
|
_, err = io.Copy(file, resp.Body) |
|
|
|
return err |
|
|
|
} |