summaryrefslogtreecommitdiff
path: root/app/cache.go
diff options
context:
space:
mode:
authorlost+skunk <[email protected]>2024-08-13 15:59:52 +0300
committerlost+skunk <[email protected]>2024-08-13 15:59:52 +0300
commit1537da9b16dfda1ecb2730b5d1de3b9005397618 (patch)
tree0cce5db0cb6393d369b7f8207d495645510276f2 /app/cache.go
parent4db018fb7f01669cb5e4c1da4b56ccfe3dbadd6f (diff)
downloadskunky-art-1537da9b16dfda1ecb2730b5d1de3b9005397618.tar.gz
skunky-art-1537da9b16dfda1ecb2730b5d1de3b9005397618.tar.bz2
skunky-art-1537da9b16dfda1ecb2730b5d1de3b9005397618.zip
темплейты в бинарнике и улучшенная система кеша
Diffstat (limited to 'app/cache.go')
-rw-r--r--app/cache.go132
1 files changed, 132 insertions, 0 deletions
diff --git a/app/cache.go b/app/cache.go
new file mode 100644
index 0000000..dedba83
--- /dev/null
+++ b/app/cache.go
@@ -0,0 +1,132 @@
+// TODO: реализовать кеширование JSON и почистить код
+package app
+
+import (
+ "crypto/sha1"
+ "encoding/hex"
+ "io"
+ "os"
+ "strings"
+ "sync"
+ "syscall"
+ "time"
+)
+
+type file struct {
+ Score int
+ Content []byte
+}
+
+var tempFS = make(map[[20]byte]*file)
+var mx = &sync.RWMutex{}
+
+func (s skunkyart) DownloadAndSendMedia(subdomain, path string) {
+ var url strings.Builder
+ url.WriteString("https://images-wixmp-")
+ url.WriteString(subdomain)
+ url.WriteString(".wixmp.com/")
+ url.WriteString(path)
+ url.WriteString("?token=")
+ url.WriteString(s.Args.Get("token"))
+
+ var response []byte
+
+ switch {
+ case CFG.Cache.Enabled:
+ fileName := sha1.Sum([]byte(subdomain + path))
+ filePath := CFG.Cache.Path + "/" + hex.EncodeToString(fileName[:])
+
+ mx.Lock()
+ if tempFS[fileName] == nil {
+ tempFS[fileName] = &file{}
+ }
+ f := *tempFS[fileName]
+ mx.Unlock()
+
+ if f.Content != nil {
+ f.Score += 2
+ } else {
+ file, err := os.Open(filePath)
+ if err != nil {
+ if dwnld := Download(url.String()); dwnld.Status == 200 && dwnld.Headers["Content-Type"][0][:5] == "image" {
+ f.Content = dwnld.Body
+ try(os.WriteFile(filePath, f.Content, 0700))
+ } else {
+ s.ReturnHTTPError(dwnld.Status)
+ return
+ }
+ } else {
+ file, e := io.ReadAll(file)
+ try(e)
+ f.Content = file
+ }
+
+ go func() {
+ defer restore()
+ for {
+ time.Sleep(1 * time.Minute)
+
+ mx.Lock()
+ if tempFS[fileName].Score <= 0 {
+ delete(tempFS, fileName)
+ mx.Unlock()
+ return
+ }
+ tempFS[fileName].Score--
+ mx.Unlock()
+ }
+ }()
+ }
+
+ mx.Lock()
+ tempFS[fileName] = &f
+ mx.Unlock()
+ response = f.Content
+ case CFG.Proxy:
+ dwnld := Download(url.String())
+ if dwnld.Status != 200 {
+ s.ReturnHTTPError(dwnld.Status)
+ return
+ }
+ response = dwnld.Body
+ default:
+ s.Writer.WriteHeader(403)
+ response = []byte("Sorry, butt proxy on this instance are disabled.")
+ }
+
+ s.Writer.Write(response)
+}
+
+func InitCacheSystem() {
+ c := &CFG.Cache
+ os.Mkdir(c.Path, 0700)
+ for {
+ dir, e := os.Open(c.Path)
+ try(e)
+ stat, e := dir.Stat()
+ try(e)
+
+ dirnames, e := dir.Readdirnames(-1)
+ try(e)
+ for _, a := range dirnames {
+ a = c.Path + "/" + a
+ if c.Lifetime != "" {
+ now := time.Now().UnixMilli()
+
+ f, _ := os.Stat(a)
+ stat := f.Sys().(*syscall.Stat_t)
+ time := statTime(stat)
+
+ if time+lifetimeParsed <= now {
+ try(os.RemoveAll(a))
+ }
+ }
+ if c.MaxSize != 0 && stat.Size() > c.MaxSize {
+ try(os.RemoveAll(a))
+ }
+ }
+
+ dir.Close()
+ time.Sleep(time.Second * time.Duration(c.UpdateInterval))
+ }
+}