diff options
Diffstat (limited to 'app/cache.go')
| -rw-r--r-- | app/cache.go | 132 |
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)) + } +} |
