package main // This file caches images in memory so we are not loading them from disk every time we need them // It also does the same for images that need to be grabbed from HTTP. import ( "crypto/sha256" "fmt" "github.com/diamondburned/gotk4/pkg/gdk/v4" "github.com/diamondburned/gotk4/pkg/gtk/v4" "io" "net/http" "os" "path/filepath" "github.com/kirsle/configdir" ) // global or app-level map/cache var textureCache = make(map[string]gdk.Paintabler) func ensureCache() (string, error) { cachePath := configdir.LocalCache("lambda-im") err := configdir.MakePath(cachePath) // Ensure it exists. if err != nil { return "", err } return cachePath, nil } func getTexture(path string) gdk.Paintabler { if tex, exists := textureCache[path]; exists { return tex } tex, err := gdk.NewTextureFromFilename(path) // load once if err != nil { panic(err) } textureCache[path] = tex return tex } func newPictureFromPath(path string) *gtk.Picture { tex := getTexture(path) img := gtk.NewPictureForPaintable(tex) return img } func newImageFromPath(path string) *gtk.Image { tex := getTexture(path) img := gtk.NewImageFromPaintable(tex) return img } func newPictureFromWeb(url string) *gtk.Picture { pa, _ := ensureCache() // step 1: get a sha256 sum of the URL sum := fmt.Sprintf("%x", sha256.Sum256([]byte(url))) p, ok := textureCache[sum] if ok { return gtk.NewPictureForPaintable(p) } // step 2: download it resp, err := http.Get(url) if err != nil { return nil } b, err := io.ReadAll(resp.Body) if err != nil { return nil } fullpath := filepath.Join(pa, sum) // step 3: save it err = os.WriteFile(fullpath, b, 0644) if err != nil { return nil } return newPictureFromPath(fullpath) } func newImageFromWeb(url string) *gtk.Image { pa, _ := ensureCache() // step 1: get a sha256 sum of the URL sum := fmt.Sprintf("%x", sha256.Sum256([]byte(url))) p, ok := textureCache[sum] if ok { return gtk.NewImageFromPaintable(p) } // step 2: download it resp, err := http.Get(url) if err != nil { return nil } b, err := io.ReadAll(resp.Body) if err != nil { return nil } fullpath := filepath.Join(pa, sum) // step 3: save it err = os.WriteFile(fullpath, b, 0644) if err != nil { return nil } return newImageFromPath(fullpath) }