2015-02-18 00:43:20 +01:00
|
|
|
/*
|
|
|
|
* MumbleDJ
|
|
|
|
* By Matthieu Grieger
|
|
|
|
* cache.go
|
|
|
|
* Copyright (c) 2014, 2015 Matthieu Grieger (MIT License)
|
|
|
|
*/
|
|
|
|
|
2015-07-30 18:28:01 +02:00
|
|
|
package main
|
2015-02-18 00:43:20 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"sort"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// ByAge is a type that holds file information for the cache items.
|
2015-02-18 00:43:20 +01:00
|
|
|
type ByAge []os.FileInfo
|
|
|
|
|
|
|
|
func (a ByAge) Len() int {
|
|
|
|
return len(a)
|
|
|
|
}
|
|
|
|
func (a ByAge) Swap(i, j int) {
|
|
|
|
a[i], a[j] = a[j], a[i]
|
|
|
|
}
|
|
|
|
func (a ByAge) Less(i, j int) bool {
|
|
|
|
return time.Since(a[i].ModTime()) < time.Since(a[j].ModTime())
|
|
|
|
}
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// SongCache is a struct that holds the number of songs currently cached and
|
|
|
|
// their combined file size.
|
2015-02-18 00:43:20 +01:00
|
|
|
type SongCache struct {
|
|
|
|
NumSongs int
|
|
|
|
TotalFileSize int64
|
|
|
|
}
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// NewSongCache creates an empty SongCache.
|
2015-02-18 00:43:20 +01:00
|
|
|
func NewSongCache() *SongCache {
|
|
|
|
newCache := &SongCache{
|
|
|
|
NumSongs: 0,
|
|
|
|
TotalFileSize: 0,
|
|
|
|
}
|
|
|
|
return newCache
|
|
|
|
}
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// GetNumSongs returns the number of songs currently cached.
|
2015-02-18 00:43:20 +01:00
|
|
|
func (c *SongCache) GetNumSongs() int {
|
|
|
|
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
|
|
|
|
return len(songs)
|
|
|
|
}
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// GetCurrentTotalFileSize calculates the total file size of the files within
|
|
|
|
// the cache and returns it.
|
2015-02-18 00:43:20 +01:00
|
|
|
func (c *SongCache) GetCurrentTotalFileSize() int64 {
|
2015-05-10 07:00:24 +02:00
|
|
|
var totalSize int64
|
2015-02-18 00:43:20 +01:00
|
|
|
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
|
|
|
|
for _, song := range songs {
|
|
|
|
totalSize += song.Size()
|
|
|
|
}
|
|
|
|
return totalSize
|
|
|
|
}
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// CheckMaximumDirectorySize checks the cache directory to determine if the filesize
|
|
|
|
// of the songs within exceed the user-specified size limit. If so, the oldest files
|
|
|
|
// get cleared until it is no longer exceeding the limit.
|
2015-02-18 00:43:20 +01:00
|
|
|
func (c *SongCache) CheckMaximumDirectorySize() {
|
|
|
|
for c.GetCurrentTotalFileSize() > (dj.conf.Cache.MaximumSize * 1048576) {
|
|
|
|
if err := c.ClearOldest(); err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// Update updates the SongCache struct.
|
2015-02-18 00:43:20 +01:00
|
|
|
func (c *SongCache) Update() {
|
|
|
|
c.NumSongs = c.GetNumSongs()
|
|
|
|
c.TotalFileSize = c.GetCurrentTotalFileSize()
|
|
|
|
}
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// ClearExpired clears cache items that are older than the cache period set within
|
|
|
|
// the user configuration.
|
2015-02-18 00:43:20 +01:00
|
|
|
func (c *SongCache) ClearExpired() {
|
2015-04-09 03:47:39 +02:00
|
|
|
for range time.Tick(5 * time.Minute) {
|
2015-02-18 00:43:20 +01:00
|
|
|
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
|
|
|
|
for _, song := range songs {
|
|
|
|
hours := time.Since(song.ModTime()).Hours()
|
2015-02-19 00:09:06 +01:00
|
|
|
if hours >= dj.conf.Cache.ExpireTime {
|
|
|
|
if dj.queue.Len() > 0 {
|
2015-04-14 08:40:39 +02:00
|
|
|
if (dj.queue.CurrentSong().Filename()) != song.Name() {
|
2015-02-19 00:09:06 +01:00
|
|
|
os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, song.Name()))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, song.Name()))
|
|
|
|
}
|
2015-02-18 00:43:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-10 07:00:24 +02:00
|
|
|
// ClearOldest deletes the oldest item in the cache.
|
2015-02-18 00:43:20 +01:00
|
|
|
func (c *SongCache) ClearOldest() error {
|
|
|
|
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
|
|
|
|
sort.Sort(ByAge(songs))
|
2015-02-19 00:09:06 +01:00
|
|
|
if dj.queue.Len() > 0 {
|
2015-04-14 08:40:39 +02:00
|
|
|
if (dj.queue.CurrentSong().Filename()) != songs[0].Name() {
|
2015-02-19 00:09:06 +01:00
|
|
|
return os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, songs[0].Name()))
|
|
|
|
}
|
2015-05-10 07:00:24 +02:00
|
|
|
return errors.New("Song is currently playing.")
|
2015-02-18 00:43:20 +01:00
|
|
|
}
|
2015-05-10 07:00:24 +02:00
|
|
|
return os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, songs[0].Name()))
|
2015-02-18 00:43:20 +01:00
|
|
|
}
|