diff --git a/controllers/emoji.go b/controllers/emoji.go index 486b1f0f6..d0a42c203 100644 --- a/controllers/emoji.go +++ b/controllers/emoji.go @@ -4,9 +4,11 @@ import ( "encoding/json" "io/ioutil" "net/http" + "os" "path" "path/filepath" "strings" + "time" "github.com/owncast/owncast/config" "github.com/owncast/owncast/models" @@ -17,28 +19,44 @@ import ( // to need it to be. The config is getting a bit bloated. const emojiDir = "/img/emoji" // Relative to webroot -// GetCustomEmoji returns a list of custom emoji via the API. -func GetCustomEmoji(w http.ResponseWriter, r *http.Request) { - emojiList := make([]models.CustomEmoji, 0) +var emojiCache = make([]models.CustomEmoji, 0) +var emojiCacheTimestamp time.Time +// getCustomEmojiList returns a list of custom emoji either from the cache or from the emoji directory. +func getCustomEmojiList() []models.CustomEmoji { fullPath := filepath.Join(config.WebRoot, emojiDir) - files, err := ioutil.ReadDir(fullPath) + emojiDirInfo, err := os.Stat(fullPath) if err != nil { log.Errorln(err) - // Throw HTTP 500 - return + } + if emojiDirInfo.ModTime() != emojiCacheTimestamp { + log.Traceln("Emoji cache invalid") + emojiCache = make([]models.CustomEmoji, 0) } - // Memoize this result somewhere? Right now it iterates through the - // filesystem every time the API is hit. Should you need to restart - // the server to add emoji? - for _, f := range files { - name := strings.TrimSuffix(f.Name(), path.Ext(f.Name())) - emojiPath := filepath.Join(emojiDir, f.Name()) - singleEmoji := models.CustomEmoji{Name: name, Emoji: emojiPath} - emojiList = append(emojiList, singleEmoji) + if len(emojiCache) == 0 { + files, err := ioutil.ReadDir(fullPath) + if err != nil { + log.Errorln(err) + return emojiCache + } + for _, f := range files { + name := strings.TrimSuffix(f.Name(), path.Ext(f.Name())) + emojiPath := filepath.Join(emojiDir, f.Name()) + singleEmoji := models.CustomEmoji{Name: name, Emoji: emojiPath} + emojiCache = append(emojiCache, singleEmoji) + } + + emojiCacheTimestamp = emojiDirInfo.ModTime() } + return emojiCache +} + +// GetCustomEmoji returns a list of custom emoji via the API. +func GetCustomEmoji(w http.ResponseWriter, r *http.Request) { + emojiList := getCustomEmojiList() + if err := json.NewEncoder(w).Encode(emojiList); err != nil { InternalErrorHandler(w, err) }