You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.1 KiB
86 lines
2.1 KiB
package static |
|
|
|
import ( |
|
"io/fs" |
|
"os" |
|
"path/filepath" |
|
"sync" |
|
"time" |
|
|
|
"github.com/owncast/owncast/models" |
|
"github.com/owncast/owncast/services/config" |
|
log "github.com/sirupsen/logrus" |
|
) |
|
|
|
var ( |
|
emojiCacheMu sync.Mutex |
|
emojiCacheData = make([]models.CustomEmoji, 0) |
|
emojiCacheModTime time.Time |
|
) |
|
|
|
// UpdateEmojiList will update the cache (if required) and |
|
// return the modifiation time. |
|
func UpdateEmojiList(force bool) (time.Time, error) { |
|
var modTime time.Time |
|
|
|
emojiPathInfo, err := os.Stat(config.CustomEmojiPath) |
|
if err != nil { |
|
return modTime, err |
|
} |
|
|
|
modTime = emojiPathInfo.ModTime() |
|
|
|
if modTime.After(emojiCacheModTime) || force { |
|
emojiCacheMu.Lock() |
|
defer emojiCacheMu.Unlock() |
|
|
|
// double-check that another thread didn't update this while waiting. |
|
if modTime.After(emojiCacheModTime) || force { |
|
emojiCacheModTime = modTime |
|
if force { |
|
emojiCacheModTime = time.Now() |
|
} |
|
emojiFS := os.DirFS(config.CustomEmojiPath) |
|
|
|
emojiCacheData = make([]models.CustomEmoji, 0) |
|
|
|
walkFunction := func(path string, d os.DirEntry, err error) error { |
|
if d.IsDir() { |
|
return nil |
|
} |
|
|
|
emojiPath := filepath.Join(config.EmojiDir, path) |
|
fileName := d.Name() |
|
fileBase := fileName[:len(fileName)-len(filepath.Ext(fileName))] |
|
singleEmoji := models.CustomEmoji{Name: fileBase, URL: emojiPath} |
|
emojiCacheData = append(emojiCacheData, singleEmoji) |
|
return nil |
|
} |
|
|
|
if err := fs.WalkDir(emojiFS, ".", walkFunction); err != nil { |
|
log.Errorln("unable to fetch emojis: " + err.Error()) |
|
} |
|
} |
|
} |
|
|
|
return modTime, nil |
|
} |
|
|
|
// GetEmojiList returns a list of custom emoji from the emoji directory. |
|
func GetEmojiList() []models.CustomEmoji { |
|
_, err := UpdateEmojiList(false) |
|
if err != nil { |
|
return nil |
|
} |
|
|
|
// Lock to make sure this doesn't get updated in the middle of reading |
|
emojiCacheMu.Lock() |
|
defer emojiCacheMu.Unlock() |
|
|
|
// return a copy of cache data, ensures underlying slice isn't affected |
|
// by future update |
|
emojiData := make([]models.CustomEmoji, len(emojiCacheData)) |
|
copy(emojiData, emojiCacheData) |
|
|
|
return emojiData |
|
}
|
|
|