Comment cleanups

This commit is contained in:
Matthieu Grieger 2015-05-09 22:00:24 -07:00
parent 34431c9fa5
commit 20c2d82ff8
5 changed files with 59 additions and 50 deletions

View file

@ -16,6 +16,7 @@ import (
"time"
)
// ByAge is a type that holds file information for the cache items.
type ByAge []os.FileInfo
func (a ByAge) Len() int {
@ -28,11 +29,14 @@ func (a ByAge) Less(i, j int) bool {
return time.Since(a[i].ModTime()) < time.Since(a[j].ModTime())
}
// SongCache is a struct that holds the number of songs currently cached and
// their combined file size.
type SongCache struct {
NumSongs int
TotalFileSize int64
}
// NewSongCache creates an empty SongCache.
func NewSongCache() *SongCache {
newCache := &SongCache{
NumSongs: 0,
@ -41,13 +45,16 @@ func NewSongCache() *SongCache {
return newCache
}
// GetNumSongs returns the number of songs currently cached.
func (c *SongCache) GetNumSongs() int {
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
return len(songs)
}
// GetCurrentTotalFileSize calculates the total file size of the files within
// the cache and returns it.
func (c *SongCache) GetCurrentTotalFileSize() int64 {
var totalSize int64 = 0
var totalSize int64
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
for _, song := range songs {
totalSize += song.Size()
@ -55,6 +62,9 @@ func (c *SongCache) GetCurrentTotalFileSize() int64 {
return totalSize
}
// 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.
func (c *SongCache) CheckMaximumDirectorySize() {
for c.GetCurrentTotalFileSize() > (dj.conf.Cache.MaximumSize * 1048576) {
if err := c.ClearOldest(); err != nil {
@ -63,11 +73,14 @@ func (c *SongCache) CheckMaximumDirectorySize() {
}
}
// Update updates the SongCache struct.
func (c *SongCache) Update() {
c.NumSongs = c.GetNumSongs()
c.TotalFileSize = c.GetCurrentTotalFileSize()
}
// ClearExpired clears cache items that are older than the cache period set within
// the user configuration.
func (c *SongCache) ClearExpired() {
for range time.Tick(5 * time.Minute) {
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
@ -86,16 +99,15 @@ func (c *SongCache) ClearExpired() {
}
}
// ClearOldest deletes the oldest item in the cache.
func (c *SongCache) ClearOldest() error {
songs, _ := ioutil.ReadDir(fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir))
sort.Sort(ByAge(songs))
if dj.queue.Len() > 0 {
if (dj.queue.CurrentSong().Filename()) != songs[0].Name() {
return os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, songs[0].Name()))
} else {
return errors.New("Song is currently playing.")
}
} else {
return os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, songs[0].Name()))
return errors.New("Song is currently playing.")
}
return os.Remove(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, songs[0].Name()))
}

View file

@ -18,8 +18,9 @@ import (
"github.com/layeh/gumble/gumble"
)
// Called on text message event. Checks the message for a command string, and processes it accordingly if
// it contains a command.
// parseCommand views incoming chat messages and determines if there is a valid command within them.
// If a command exists, the arguments (if any) will be parsed and sent to the appropriate helper
// function to perform the command's task.
func parseCommand(user *gumble.User, username, command string) {
var com, argument string
split := strings.Split(command, "\n")
@ -157,7 +158,7 @@ func parseCommand(user *gumble.User, username, command string) {
}
}
// Performs add functionality. Checks input URL for YouTube format, and adds
// add performs !add functionality. Checks input URL for YouTube format, and adds
// the URL to the queue if the format matches.
func add(user *gumble.User, username, url string) {
if url == "" {
@ -238,7 +239,7 @@ func add(user *gumble.User, username, url string) {
}
}
// Performs skip functionality. Adds a skip to the skippers slice for the current song, and then
// skip performs !skip functionality. Adds a skip to the skippers slice for the current song, and then
// evaluates if a skip should be performed. Both skip and forceskip are implemented here.
func skip(user *gumble.User, username string, admin, playlistSkip bool) {
if dj.audioStream.IsPlaying() {
@ -306,12 +307,12 @@ func skip(user *gumble.User, username string, admin, playlistSkip bool) {
}
}
// Performs help functionality. Displays a list of valid commands.
// help performs !help functionality. Displays a list of valid commands.
func help(user *gumble.User) {
dj.SendPrivateMessage(user, HELP_HTML)
}
// Performs volume functionality. Checks input value against LowestVolume and HighestVolume from
// volume performs !volume functionality. Checks input value against LowestVolume and HighestVolume from
// config to determine if the volume should be applied. If in the correct range, the new volume
// is applied and is immediately in effect.
func volume(user *gumble.User, username, value string) {
@ -332,7 +333,7 @@ func volume(user *gumble.User, username, value string) {
}
}
// Performs move functionality. Determines if the supplied channel is valid and moves the bot
// move performs !move functionality. Determines if the supplied channel is valid and moves the bot
// to the channel if it is.
func move(user *gumble.User, channel string) {
if channel == "" {
@ -346,14 +347,14 @@ func move(user *gumble.User, channel string) {
}
}
// Performs reload functionality. Tells command submitter if the reload completed successfully.
// reload performs !reload functionality. Tells command submitter if the reload completed successfully.
func reload(user *gumble.User) {
if err := loadConfiguration(); err == nil {
dj.SendPrivateMessage(user, CONFIG_RELOAD_SUCCESS_MSG)
}
}
// 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.
func reset(username string) {
dj.queue.queue = dj.queue.queue[:0]
@ -369,7 +370,7 @@ func reset(username string) {
}
}
// Performs numsongs functionality. Uses the SongQueue traversal function to traverse the
// numSongs performs !numsongs functionality. Uses the SongQueue traversal function to traverse the
// queue with a function call that increments a counter. Once finished, the bot outputs
// the number of songs in the queue to chat.
func numSongs() {
@ -380,7 +381,7 @@ func numSongs() {
dj.client.Self.Channel.Send(fmt.Sprintf(NUM_SONGS_HTML, songCount), false)
}
// Performs nextsong functionality. Uses the SongQueue PeekNext function to peek at the next
// nextSong performs !nextsong functionality. Uses the SongQueue PeekNext function to peek at the next
// item if it exists. The user will then be sent a message containing the title and submitter
// of the next item if it exists.
func nextSong(user *gumble.User) {
@ -391,7 +392,7 @@ func nextSong(user *gumble.User) {
}
}
// Performs currentsong functionality. Sends the user who submitted the currentsong command
// currentSong performs !currentsong functionality. Sends the user who submitted the currentsong command
// information about the song currently playing.
func currentSong(user *gumble.User) {
if dj.audioStream.IsPlaying() {
@ -406,13 +407,13 @@ func currentSong(user *gumble.User) {
}
}
// Performs setcomment functionality. Sets the bot's comment to whatever text is supplied in the argument.
// setComment performs !setcomment functionality. Sets the bot's comment to whatever text is supplied in the argument.
func setComment(user *gumble.User, comment string) {
dj.client.Self.SetComment(comment)
dj.SendPrivateMessage(user, COMMENT_UPDATED_MSG)
}
// 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 at ~/.mumbledj/songs.
func numCached(user *gumble.User) {
if dj.conf.Cache.Enabled {
dj.cache.Update()
@ -422,7 +423,7 @@ func numCached(user *gumble.User) {
}
}
// Performs cachesize functionality. Displays the total file size of the cached audio files.
// cacheSize performs !cachesize functionality. Displays the total file size of the cached audio files.
func cacheSize(user *gumble.User) {
if dj.conf.Cache.Enabled {
dj.cache.Update()
@ -432,7 +433,7 @@ func cacheSize(user *gumble.User) {
}
}
// Performs kill functionality. First cleans the ~/.mumbledj/songs directory to get rid of any
// kill performs !kill functionality. First cleans the ~/.mumbledj/songs directory to get rid of any
// excess m4a files. The bot then safely disconnects from the server.
func kill() {
if err := deleteSongs(); err != nil {
@ -446,15 +447,14 @@ func kill() {
}
}
// Deletes songs from ~/.mumbledj/songs.
// deleteSongs deletes songs from ~/.mumbledj/songs.
func deleteSongs() error {
songsDir := fmt.Sprintf("%s/.mumbledj/songs", dj.homeDir)
if err := os.RemoveAll(songsDir); err != nil {
return errors.New("An error occurred while deleting the audio files.")
} else {
if err := os.Mkdir(songsDir, 0777); err != nil {
return errors.New("An error occurred while recreating the songs directory.")
}
return nil
}
if err := os.Mkdir(songsDir, 0777); err != nil {
return errors.New("An error occurred while recreating the songs directory.")
}
return nil
}

12
main.go
View file

@ -21,7 +21,8 @@ import (
"github.com/layeh/gumble/gumbleutil"
)
// MumbleDJ type declaration
// mumbledj is a struct that keeps track of all aspects of the bot's current
// state.
type mumbledj struct {
config gumble.Config
client *gumble.Client
@ -106,7 +107,7 @@ func (dj *mumbledj) OnUserChange(e *gumble.UserChangeEvent) {
}
}
// Checks if username has the permissions to execute a command. Permissions are specified in
// HasPermission checks if username has the permissions to execute a command. Permissions are specified in
// mumbledj.gcfg.
func (dj *mumbledj) HasPermission(username string, command bool) bool {
if dj.conf.Permissions.AdminsEnabled && command {
@ -116,12 +117,11 @@ func (dj *mumbledj) HasPermission(username string, command bool) bool {
}
}
return false
} else {
return true
}
return true
}
// Sends a private message to a user. Essentially just checks if a user is still in the server
// SendPrivateMessage sends a private message to a user. Essentially just checks if a user is still in the server
// before sending them the message.
func (dj *mumbledj) SendPrivateMessage(user *gumble.User, message string) {
if targetUser := dj.client.Self.Channel.Users.Find(user.Name); targetUser != nil {
@ -146,7 +146,7 @@ var dj = mumbledj{
cache: NewSongCache(),
}
// Main function, but only really performs startup tasks. Grabs and parses commandline
// main primarily performs startup tasks. Grabs and parses commandline
// args, sets up the gumble client and its listeners, and then connects to the server.
func main() {

View file

@ -14,7 +14,7 @@ import (
"code.google.com/p/gcfg"
)
// Golang struct representation of mumbledj.gcfg file structure for parsing.
// DjConfig is a Golang struct representation of mumbledj.gcfg file structure for parsing.
type DjConfig struct {
General struct {
CommandPrefix string
@ -77,8 +77,7 @@ type DjConfig struct {
func loadConfiguration() error {
if gcfg.ReadFileInto(&dj.conf, fmt.Sprintf("%s/.mumbledj/config/mumbledj.gcfg", dj.homeDir)) == nil {
return nil
} else {
fmt.Printf("%s/.mumbledj/config/mumbledj.gcfg\n", dj.homeDir)
return errors.New("Configuration load failed.")
}
fmt.Printf("%s/.mumbledj/config/mumbledj.gcfg\n", dj.homeDir)
return errors.New("Configuration load failed.")
}

View file

@ -18,30 +18,29 @@ type SongQueue struct {
queue []Song
}
// Initializes a new queue and returns the new SongQueue.
// NewSongQueue initializes a new queue and returns it.
func NewSongQueue() *SongQueue {
return &SongQueue{
queue: make([]Song, 0),
}
}
// Adds a Song to the SongQueue.
// AddSong adds a Song to the SongQueue.
func (q *SongQueue) AddSong(s Song) error {
beforeLen := q.Len()
q.queue = append(q.queue, s)
if len(q.queue) == beforeLen+1 {
return nil
} else {
return errors.New("Could not add Song to the SongQueue.")
}
return errors.New("Could not add Song to the SongQueue.")
}
// Returns the current Song.
// CurrentSong returns the current Song.
func (q *SongQueue) CurrentSong() Song {
return q.queue[0]
}
// Moves to the next Song in SongQueue. NextSong() removes the first Song in the queue.
// NextSong moves to the next Song in SongQueue. NextSong() removes the first Song in the queue.
func (q *SongQueue) NextSong() {
if q.CurrentSong().Playlist() != nil {
if s, err := q.PeekNext(); err == nil {
@ -55,21 +54,20 @@ func (q *SongQueue) NextSong() {
q.queue = q.queue[1:]
}
// Peeks at the next Song and returns it.
// PeekNext peeks at the next Song and returns it.
func (q *SongQueue) PeekNext() (Song, error) {
if q.Len() > 1 {
return q.queue[1], nil
} else {
return nil, errors.New("There isn't a Song coming up next.")
}
return nil, errors.New("There isn't a Song coming up next.")
}
// Returns the length of the SongQueue.
// Len returns the length of the SongQueue.
func (q *SongQueue) Len() int {
return len(q.queue)
}
// A traversal function for SongQueue. Allows a visit function to be passed in which performs
// Traverse is a traversal function for SongQueue. Allows a visit function to be passed in which performs
// the specified action on each queue item.
func (q *SongQueue) Traverse(visit func(i int, s Song)) {
for sQueue, queueSong := range q.queue {
@ -94,8 +92,8 @@ func (q *SongQueue) OnSongFinished() {
}
}
// Prepares next song and plays it if the download succeeds. Otherwise the function will print an error message
// to the channel and skip to the next song.
// PrepareAndPlayNextSong prepares next song and plays it if the download succeeds.
// Otherwise the function will print an error message to the channel and skip to the next song.
func (q *SongQueue) PrepareAndPlayNextSong() {
if err := q.CurrentSong().Download(); err == nil {
q.CurrentSong().Play()