Bug fix: Image caching (#172)
This commit is contained in:
178
src/internal/imgcache/cache.go
Normal file
178
src/internal/imgcache/cache.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package imgcache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Cache : Cache strcut
|
||||
type Cache struct {
|
||||
path string
|
||||
cacheURL string
|
||||
caching bool
|
||||
images map[string]string
|
||||
Queue []string
|
||||
Cache []string
|
||||
Image imageFunc
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
type imageFunc struct {
|
||||
GetURL func(string) string
|
||||
Caching func()
|
||||
Remove func()
|
||||
}
|
||||
|
||||
// New : New cahce
|
||||
func New(path, chacheURL string, caching bool) (c *Cache, err error) {
|
||||
|
||||
c = &Cache{}
|
||||
|
||||
c.images = make(map[string]string)
|
||||
c.path = path
|
||||
c.cacheURL = chacheURL
|
||||
c.caching = caching
|
||||
c.Queue = []string{}
|
||||
c.Cache = []string{}
|
||||
|
||||
var queue []string
|
||||
|
||||
c.Image.GetURL = func(src string) (cacheURL string) {
|
||||
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
src = strings.Trim(src, "\r\n")
|
||||
|
||||
if c.caching == false {
|
||||
return src
|
||||
}
|
||||
|
||||
u, err := url.Parse(src)
|
||||
if err != nil || len(filepath.Ext(u.Path)) == 0 {
|
||||
return src
|
||||
}
|
||||
|
||||
var filename = fmt.Sprintf("%s%s", strToMD5(src), filepath.Ext(u.Path))
|
||||
if cacheURL, ok := c.images[fmt.Sprintf("%s%s", strToMD5(src), filepath.Ext(u.Path))]; ok {
|
||||
return cacheURL
|
||||
}
|
||||
|
||||
if indexOfString(filename, c.Cache) == -1 {
|
||||
|
||||
if indexOfString(src, c.Queue) == -1 {
|
||||
c.Queue = append(c.Queue, src)
|
||||
}
|
||||
|
||||
} else {
|
||||
c.images[filename] = c.cacheURL + filename
|
||||
src = c.cacheURL + filename
|
||||
}
|
||||
|
||||
/*
|
||||
if _, err := os.Stat(c.path + filename); err != nil {
|
||||
//c.images[filename] = c.cacheURL + filename
|
||||
if indexOfString(src, c.Queue) == -1 {
|
||||
c.Queue = append(c.Queue, src)
|
||||
}
|
||||
} else {
|
||||
c.images[filename] = c.cacheURL + filename
|
||||
}
|
||||
*/
|
||||
|
||||
return src
|
||||
}
|
||||
|
||||
c.Image.Caching = func() {
|
||||
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
var filename string
|
||||
|
||||
for _, src := range c.Queue {
|
||||
|
||||
resp, err := http.Get(src)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
continue
|
||||
}
|
||||
|
||||
filename = fmt.Sprintf("%s%s%s%s", c.path, string(os.PathSeparator), strToMD5(src), filepath.Ext(src))
|
||||
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(file, resp.Body)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
u, err := url.Parse(src)
|
||||
if err == nil {
|
||||
c.images[fmt.Sprintf("%s%s", strToMD5(src), filepath.Ext(u.Path))] = c.cacheURL + filename
|
||||
}
|
||||
|
||||
queue = append(queue, src)
|
||||
|
||||
}
|
||||
|
||||
for _, q := range queue {
|
||||
c.Queue = removeStringFromSlice(q, c.Queue)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
c.Image.Remove = func() {
|
||||
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
files, err := ioutil.ReadDir(c.path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
|
||||
switch c.caching {
|
||||
|
||||
case true:
|
||||
if _, ok := c.images[file.Name()]; !ok {
|
||||
os.RemoveAll(c.path + file.Name())
|
||||
}
|
||||
|
||||
case false:
|
||||
os.RemoveAll(c.path + file.Name())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(c.path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
c.Cache = append(c.Cache, file.Name())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
34
src/internal/imgcache/tools.go
Normal file
34
src/internal/imgcache/tools.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package imgcache
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
func strToMD5(str string) string {
|
||||
md5Hasher := md5.New()
|
||||
md5Hasher.Write([]byte(str))
|
||||
return hex.EncodeToString(md5Hasher.Sum(nil))
|
||||
}
|
||||
|
||||
func indexOfString(str string, slice []string) int {
|
||||
|
||||
for i, v := range slice {
|
||||
if str == v {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func removeStringFromSlice(str string, slice []string) []string {
|
||||
|
||||
var i = indexOfString(str, slice)
|
||||
|
||||
if i != -1 {
|
||||
slice = append(slice[:i], slice[i+1:]...)
|
||||
}
|
||||
|
||||
return slice
|
||||
}
|
||||
Reference in New Issue
Block a user