Store song cache in XDG_CACHE_HOME
This commit is contained in:
parent
6bea261d68
commit
cb9a410caf
1
Goopfile
1
Goopfile
|
@ -3,3 +3,4 @@ github.com/layeh/gumble/gumble #8b9989d9c4090874546c45ceaa6ff21e95705bc4
|
||||||
github.com/layeh/gumble/gumble_ffmpeg #c9fcce8fc4b71c7c53a5d3d9d48a1e001ad19a19
|
github.com/layeh/gumble/gumble_ffmpeg #c9fcce8fc4b71c7c53a5d3d9d48a1e001ad19a19
|
||||||
github.com/scalingdata/gcfg #37aabad69cfd3d20b8390d902a8b10e245c615ff
|
github.com/scalingdata/gcfg #37aabad69cfd3d20b8390d902a8b10e245c615ff
|
||||||
github.com/jmoiron/jsonq #7c27c8eb9f6831555a4209f6a7d579159e766a3c
|
github.com/jmoiron/jsonq #7c27c8eb9f6831555a4209f6a7d579159e766a3c
|
||||||
|
github.com/mildred/go-xdg #96b70c9133fdb4c32f9c551d50455152dea68d73
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -11,7 +11,6 @@ clean:
|
||||||
|
|
||||||
install:
|
install:
|
||||||
mkdir -p ~/.mumbledj/config
|
mkdir -p ~/.mumbledj/config
|
||||||
mkdir -p ~/.mumbledj/songs
|
|
||||||
if [ -f ~/.mumbledj/config/mumbledj.gcfg ]; then mv ~/.mumbledj/config/mumbledj.gcfg ~/.mumbledj/config/mumbledj_backup.gcfg; fi;
|
if [ -f ~/.mumbledj/config/mumbledj.gcfg ]; then mv ~/.mumbledj/config/mumbledj.gcfg ~/.mumbledj/config/mumbledj_backup.gcfg; fi;
|
||||||
cp -u config.gcfg ~/.mumbledj/config/mumbledj.gcfg
|
cp -u config.gcfg ~/.mumbledj/config/mumbledj.gcfg
|
||||||
sed -i 's/YouTube = \"/YouTube = \"'$(YOUTUBE_API_KEY)'/' ~/.mumbledj/config/mumbledj.gcfg
|
sed -i 's/YouTube = \"/YouTube = \"'$(YOUTUBE_API_KEY)'/' ~/.mumbledj/config/mumbledj.gcfg
|
||||||
|
|
|
@ -66,7 +66,7 @@ Command | Description | Arguments | Admin | Example
|
||||||
**setcomment** | Sets the comment for the bot. If no argument is given, the current comment will be removed. | None OR new_comment | Yes | `!setcomment Hello! I am a bot. Type !help for the available commands.`
|
**setcomment** | Sets the comment for the bot. If no argument is given, the current comment will be removed. | None OR new_comment | Yes | `!setcomment Hello! I am a bot. Type !help for the available commands.`
|
||||||
**numcached** | Outputs the number of songs currently cached on disk. | None | Yes | `!numcached`
|
**numcached** | Outputs the number of songs currently cached on disk. | None | Yes | `!numcached`
|
||||||
**cachesize** | Outputs the total file size of the cache in MB. | None | Yes | `!cachesize`
|
**cachesize** | Outputs the total file size of the cache in MB. | None | Yes | `!cachesize`
|
||||||
**kill** | Safely cleans the bot environment and disconnects from the server. Please use this command to stop the bot instead of force closing, as the kill command deletes any remaining songs in the `~/.mumbledj/songs` directory. | None | Yes | `!kill`
|
**kill** | Safely cleans the bot environment and disconnects from the server. Please use this command to stop the bot instead of force closing, as the kill command deletes any remaining songs in the song cache directory. | None | Yes | `!kill`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
16
cache.go
16
cache.go
|
@ -47,7 +47,7 @@ func NewSongCache() *SongCache {
|
||||||
|
|
||||||
// GetNumSongs returns the number of songs currently cached.
|
// GetNumSongs returns the number of songs currently cached.
|
||||||
func (c *SongCache) GetNumSongs() int {
|
func (c *SongCache) GetNumSongs() int {
|
||||||
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
|
songs, _ := ioutil.ReadDir(dj.songCacheDir)
|
||||||
return len(songs)
|
return len(songs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ func (c *SongCache) GetNumSongs() int {
|
||||||
// the cache and returns it.
|
// the cache and returns it.
|
||||||
func (c *SongCache) GetCurrentTotalFileSize() int64 {
|
func (c *SongCache) GetCurrentTotalFileSize() int64 {
|
||||||
var totalSize int64
|
var totalSize int64
|
||||||
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
|
songs, _ := ioutil.ReadDir(dj.songCacheDir)
|
||||||
for _, song := range songs {
|
for _, song := range songs {
|
||||||
totalSize += song.Size()
|
totalSize += song.Size()
|
||||||
}
|
}
|
||||||
|
@ -83,16 +83,16 @@ func (c *SongCache) Update() {
|
||||||
// the user configuration.
|
// the user configuration.
|
||||||
func (c *SongCache) ClearExpired() {
|
func (c *SongCache) ClearExpired() {
|
||||||
for range time.Tick(5 * time.Minute) {
|
for range time.Tick(5 * time.Minute) {
|
||||||
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
|
songs, _ := ioutil.ReadDir(dj.songCacheDir)
|
||||||
for _, song := range songs {
|
for _, song := range songs {
|
||||||
hours := time.Since(song.ModTime()).Hours()
|
hours := time.Since(song.ModTime()).Hours()
|
||||||
if hours >= dj.conf.Cache.ExpireTime {
|
if hours >= dj.conf.Cache.ExpireTime {
|
||||||
if dj.queue.Len() > 0 {
|
if dj.queue.Len() > 0 {
|
||||||
if (dj.queue.CurrentSong().Filename()) != song.Name() {
|
if (dj.queue.CurrentSong().Filename()) != song.Name() {
|
||||||
os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, song.Name()))
|
os.Remove(fmt.Sprintf("%s/%s", dj.songCacheDir, song.Name()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, song.Name()))
|
os.Remove(fmt.Sprintf("%s/%s", dj.songCacheDir, song.Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,13 +101,13 @@ func (c *SongCache) ClearExpired() {
|
||||||
|
|
||||||
// ClearOldest deletes the oldest item in the cache.
|
// ClearOldest deletes the oldest item in the cache.
|
||||||
func (c *SongCache) ClearOldest() error {
|
func (c *SongCache) ClearOldest() error {
|
||||||
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
|
songs, _ := ioutil.ReadDir(dj.songCacheDir)
|
||||||
sort.Sort(ByAge(songs))
|
sort.Sort(ByAge(songs))
|
||||||
if dj.queue.Len() > 0 {
|
if dj.queue.Len() > 0 {
|
||||||
if (dj.queue.CurrentSong().Filename()) != songs[0].Name() {
|
if (dj.queue.CurrentSong().Filename()) != songs[0].Name() {
|
||||||
return os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, songs[0].Name()))
|
return os.Remove(fmt.Sprintf("%s/%s", dj.songCacheDir, songs[0].Name()))
|
||||||
}
|
}
|
||||||
return errors.New("Song is currently playing.")
|
return errors.New("Song is currently playing.")
|
||||||
}
|
}
|
||||||
return os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, songs[0].Name()))
|
return os.Remove(fmt.Sprintf("%s/%s", dj.songCacheDir, songs[0].Name()))
|
||||||
}
|
}
|
||||||
|
|
21
commands.go
21
commands.go
|
@ -11,6 +11,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -355,7 +356,7 @@ func reload(user *gumble.User) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset performs !reset functionality. Clears the song queue, stops playing audio, and deletes all
|
// reset performs !reset functionality. Clears the song queue, stops playing audio, and deletes all
|
||||||
// remaining songs in the ~/.mumbledj/songs directory.
|
// remaining songs in the song cache directory.
|
||||||
func reset(username string) {
|
func reset(username string) {
|
||||||
dj.queue.queue = dj.queue.queue[:0]
|
dj.queue.queue = dj.queue.queue[:0]
|
||||||
if dj.audioStream.IsPlaying() {
|
if dj.audioStream.IsPlaying() {
|
||||||
|
@ -413,7 +414,7 @@ func setComment(user *gumble.User, comment string) {
|
||||||
dj.SendPrivateMessage(user, COMMENT_UPDATED_MSG)
|
dj.SendPrivateMessage(user, COMMENT_UPDATED_MSG)
|
||||||
}
|
}
|
||||||
|
|
||||||
// numCached performs !numcached functionality. Displays the number of songs currently cached on disk at ~/.mumbledj/songs.
|
// numCached performs !numcached functionality. Displays the number of songs currently cached on disk.
|
||||||
func numCached(user *gumble.User) {
|
func numCached(user *gumble.User) {
|
||||||
if dj.conf.Cache.Enabled {
|
if dj.conf.Cache.Enabled {
|
||||||
dj.cache.Update()
|
dj.cache.Update()
|
||||||
|
@ -433,7 +434,7 @@ func cacheSize(user *gumble.User) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// kill performs !kill functionality. First cleans the ~/.mumbledj/songs directory to get rid of any
|
// kill performs !kill functionality. First cleans the song cache directory to get rid of any
|
||||||
// excess m4a files. The bot then safely disconnects from the server.
|
// excess m4a files. The bot then safely disconnects from the server.
|
||||||
func kill() {
|
func kill() {
|
||||||
if err := deleteSongs(); err != nil {
|
if err := deleteSongs(); err != nil {
|
||||||
|
@ -447,14 +448,16 @@ func kill() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteSongs deletes songs from ~/.mumbledj/songs.
|
// deleteSongs deletes songs from the song cache.
|
||||||
func deleteSongs() error {
|
func deleteSongs() error {
|
||||||
songsDir := fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir)
|
songs, err := ioutil.ReadDir(dj.songCacheDir)
|
||||||
if err := os.RemoveAll(songsDir); err != nil {
|
if err != nil {
|
||||||
return errors.New("An error occurred while deleting the audio files.")
|
return errors.New(fmt.Sprintf("An error occured while clearing %q: %v", dj.songCacheDir, err))
|
||||||
}
|
}
|
||||||
if err := os.Mkdir(songsDir, 0777); err != nil {
|
for _, file := range songs {
|
||||||
return errors.New("An error occurred while recreating the songs directory.")
|
if err2 := os.Remove(fmt.Sprintf("%s/%s", dj.songCacheDir, file.Name())); err2 != nil {
|
||||||
|
return errors.New(fmt.Sprintf("An error occurred while removing %q: %v", file.Name(), err2))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
5
main.go
5
main.go
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/layeh/gumble/gumble"
|
"github.com/layeh/gumble/gumble"
|
||||||
"github.com/layeh/gumble/gumble_ffmpeg"
|
"github.com/layeh/gumble/gumble_ffmpeg"
|
||||||
"github.com/layeh/gumble/gumbleutil"
|
"github.com/layeh/gumble/gumbleutil"
|
||||||
|
"github.com/mildred/go-xdg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// mumbledj is a struct that keeps track of all aspects of the bot's current
|
// mumbledj is a struct that keeps track of all aspects of the bot's current
|
||||||
|
@ -34,6 +35,7 @@ type mumbledj struct {
|
||||||
queue *SongQueue
|
queue *SongQueue
|
||||||
audioStream *gumble_ffmpeg.Stream
|
audioStream *gumble_ffmpeg.Stream
|
||||||
homeDir string
|
homeDir string
|
||||||
|
songCacheDir string
|
||||||
playlistSkips map[string][]string
|
playlistSkips map[string][]string
|
||||||
cache *SongCache
|
cache *SongCache
|
||||||
}
|
}
|
||||||
|
@ -190,6 +192,9 @@ func main() {
|
||||||
if currentUser, err := user.Current(); err == nil {
|
if currentUser, err := user.Current(); err == nil {
|
||||||
dj.homeDir = currentUser.HomeDir
|
dj.homeDir = currentUser.HomeDir
|
||||||
}
|
}
|
||||||
|
if songCacheDir, err := xdg.Cache.EnsureDir("mumbledj/songs"); err == nil {
|
||||||
|
dj.songCacheDir = songCacheDir
|
||||||
|
}
|
||||||
|
|
||||||
if err := loadConfiguration(); err == nil {
|
if err := loadConfiguration(); err == nil {
|
||||||
fmt.Println("Configuration successfully loaded!")
|
fmt.Println("Configuration successfully loaded!")
|
||||||
|
|
|
@ -51,12 +51,12 @@ type AudioPlaylist struct {
|
||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
// Download downloads the song via youtube-dl if it does not already exist on disk.
|
// Download downloads the song via youtube-dl if it does not already exist on disk.
|
||||||
// All downloaded songs are stored in ~/.mumbledj/songs and should be automatically cleaned.
|
// All downloaded songs are stored in the song cache and should be automatically cleaned.
|
||||||
func (dl *AudioTrack) Download() error {
|
func (dl *AudioTrack) Download() error {
|
||||||
|
|
||||||
// Checks to see if song is already downloaded
|
// Checks to see if song is already downloaded
|
||||||
if _, err := os.Stat(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, dl.Filename())); os.IsNotExist(err) {
|
if _, err := os.Stat(fmt.Sprintf("%s/%s", dj.songCacheDir, dl.Filename())); os.IsNotExist(err) {
|
||||||
cmd := exec.Command("youtube-dl", "--verbose", "--no-mtime", "--output", fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, dl.Filename()), "--format", dl.format, "--prefer-ffmpeg", dl.url)
|
cmd := exec.Command("youtube-dl", "--verbose", "--no-mtime", "--output", fmt.Sprintf("%s/%s", dj.songCacheDir, dl.Filename()), "--format", dl.format, "--prefer-ffmpeg", dl.url)
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if dj.conf.Cache.Enabled {
|
if dj.conf.Cache.Enabled {
|
||||||
|
@ -82,7 +82,7 @@ func (dl *AudioTrack) Play() {
|
||||||
offsetDuration, _ := time.ParseDuration(fmt.Sprintf("%ds", dl.offset))
|
offsetDuration, _ := time.ParseDuration(fmt.Sprintf("%ds", dl.offset))
|
||||||
dj.audioStream.Offset = offsetDuration
|
dj.audioStream.Offset = offsetDuration
|
||||||
}
|
}
|
||||||
dj.audioStream.Source = gumble_ffmpeg.SourceFile(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, dl.Filename()))
|
dj.audioStream.Source = gumble_ffmpeg.SourceFile(fmt.Sprintf("%s/%s", dj.songCacheDir, dl.Filename()))
|
||||||
if err := dj.audioStream.Play(); err != nil {
|
if err := dj.audioStream.Play(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,10 +101,10 @@ func (dl *AudioTrack) Play() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes the song from ~/.mumbledj/songs if the cache is disabled.
|
// Delete deletes the song from the song cache if the cache is disabled.
|
||||||
func (dl *AudioTrack) Delete() error {
|
func (dl *AudioTrack) Delete() error {
|
||||||
if dj.conf.Cache.Enabled == false {
|
if dj.conf.Cache.Enabled == false {
|
||||||
filePath := fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, dl.Filename())
|
filePath := fmt.Sprintf("%s/%s", dj.songCacheDir, dl.Filename())
|
||||||
if _, err := os.Stat(filePath); err == nil {
|
if _, err := os.Stat(filePath); err == nil {
|
||||||
if err := os.Remove(filePath); err == nil {
|
if err := os.Remove(filePath); err == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
Reference in a new issue