Resolve https://github.com/matthieugrieger/mumbledj/issues/152: Command messages are now set and configured in config.yaml

pull/153/head 3.0.1
Matthieu Grieger 2016-06-21 16:00:13 -07:00
parent cbc850da95
commit 7f1b9595c1
29 changed files with 203 additions and 68 deletions

View File

@ -1,6 +1,9 @@
MumbleDJ Changelog
==================
### June 21, 2016 -- `v3.0.1`
* Added all strings that are output by commands to `config.yaml` for easier translation and tweaking.
### June 20, 2016 -- `v3.0.0`
* Significantly simplified installation process, now installable via `go install`.
* Commands may now have multiple aliases, configurable via config file.

File diff suppressed because one or more lines are too long

View File

@ -65,9 +65,19 @@ func SetDefaultConfig() {
viper.SetDefault("admins.names", []string{"SuperUser"})
// Command defaults.
viper.SetDefault("commands.prefix", "!")
viper.SetDefault("commands.common_messages.no_tracks_error", "There are no tracks in the queue.")
viper.SetDefault("commands.common_messages.caching_disabled_error", "Caching is currently disabled.")
viper.SetDefault("commands.add.aliases", []string{"add", "a"})
viper.SetDefault("commands.add.is_admin", false)
viper.SetDefault("commands.add.description", "Adds a track or playlist from a media site to the queue.")
viper.SetDefault("commands.add.messages.no_url_error", "A URL must be supplied with the add command.")
viper.SetDefault("commands.add.messages.no_valid_tracks_error", "No valid tracks were found with the provided URL(s).")
viper.SetDefault("commands.add.messages.tracks_too_long_error", "Your track(s) were either too long or an error occurred while processing them. No track(s) have been added.")
viper.SetDefault("commands.add.messages.one_track_added", "<b>%s</b> added <b>1</b> track to the queue:<br><i>%s</i> from %s")
viper.SetDefault("commands.add.messages.many_tracks_added", "<b>%s</b> added <b>%d</b> tracks to the queue.")
viper.SetDefault("commands.add.messages.num_tracks_too_long", "<br><b>%d</b> tracks could not be added due to error or because they are too long.")
viper.SetDefault("commands.addnext.aliases", []string{"addnext", "an"})
viper.SetDefault("commands.addnext.is_admin", true)
@ -76,26 +86,35 @@ func SetDefaultConfig() {
viper.SetDefault("commands.cachesize.aliases", []string{"cachesize", "cs"})
viper.SetDefault("commands.cachesize.is_admin", true)
viper.SetDefault("commands.cachesize.description", "Outputs the file size of the cache in MiB if caching is enabled.")
viper.SetDefault("commands.cachesize.messages.current_size", "The current size of the cache is <b>%.2v MiB</b>.")
viper.SetDefault("commands.currenttrack.aliases", []string{"currenttrack", "currentsong", "current"})
viper.SetDefault("commands.currenttrack.is_admin", false)
viper.SetDefault("commands.currenttrack.description", "Outputs information about the current track in the queue if one exists.")
viper.SetDefault("commands.currenttrack.messages.current_track", "The current track is <i>%s</i>, added by <b>%s</b>.")
viper.SetDefault("commands.forceskip.aliases", []string{"forceskip", "fs"})
viper.SetDefault("commands.forceskip.is_admin", true)
viper.SetDefault("commands.forceskip.description", "Immediately skips the current track.")
viper.SetDefault("commands.forceskip.messages.track_skipped", "The current track has been forcibly skipped by <b>%s</b>.")
viper.SetDefault("commands.forceskipplaylist.aliases", []string{"forceskipplaylist", "fsp"})
viper.SetDefault("commands.forceskipplaylist.is_admin", true)
viper.SetDefault("commands.forceskipplaylist.description", "Immediately skips the current playlist.")
viper.SetDefault("commands.forceskipplaylist.messages.no_playlist_error", "The current track is not part of a playlist.")
viper.SetDefault("commands.forceskipplaylist.messages.playlist_skipped", "The current playlist has been forcibly skipped by <b>%s</b>.")
viper.SetDefault("commands.help.aliases", []string{"help", "h"})
viper.SetDefault("commands.help.is_admin", false)
viper.SetDefault("commands.help.description", "Outputs this list of commands.")
viper.SetDefault("commands.help.messages.commands_header", "<br><b>Commands:</b><br>")
viper.SetDefault("commands.help.messages.admin_commands.header", "<br><b>Admin Commands:</b><br>")
viper.SetDefault("commands.joinme.aliases", []string{"joinme", "join"})
viper.SetDefault("commands.joinme.is_admin", true)
viper.SetDefault("commands.joinme.description", "Moves MumbleDJ into your current channel if not playing audio to someone else.")
viper.SetDefault("commands.joinme.messages.others_are_listening_error", "Users in another channel are listening to me.")
viper.SetDefault("commands.joinme.messages.in_your_channel", "I am now in your channel!")
viper.SetDefault("commands.kill.aliases", []string{"kill", "k"})
viper.SetDefault("commands.kill.is_admin", true)
@ -104,66 +123,98 @@ func SetDefaultConfig() {
viper.SetDefault("commands.listtracks.aliases", []string{"listtracks", "listsongs", "list", "l"})
viper.SetDefault("commands.listtracks.is_admin", false)
viper.SetDefault("commands.listtracks.description", "Outputs a list of the tracks currently in the queue.")
viper.SetDefault("commands.listtracks.messages.invalid_integer_error", "An invalid integer was supplied.")
viper.SetDefault("commands.listtracks.messages.track_listing", "<b>%d</b>: <i>%s</i>, added by <b>%s</b>.<br>")
viper.SetDefault("commands.move.aliases", []string{"move", "m"})
viper.SetDefault("commands.move.is_admin", true)
viper.SetDefault("commands.move.description", "Moves the bot into the Mumble channel provided via argument.")
viper.SetDefault("commands.move.messages.no_channel_provided_error", "A destination channel must be supplied to move the bot.")
viper.SetDefault("commands.move.messages.channel_doesnt_exist_error", "The provided channel does not exist.")
viper.SetDefault("commands.move.messages.move_successful", "You have successfully moved the bot to <b>%s</b>.")
viper.SetDefault("commands.nexttrack.aliases", []string{"nexttrack", "nextsong", "next"})
viper.SetDefault("commands.nexttrack.is_admin", false)
viper.SetDefault("commands.nexttrack.description", "Outputs information about the next track in the queue if one exists.")
viper.SetDefault("commands.nexttrack.messages.current_track_only_error", "The current track is the only track in the queue.")
viper.SetDefault("commands.nexttrack.messages.next_track", "The next track is <i>%s</i>, added by <b>%s</b>.")
viper.SetDefault("commands.numcached.aliases", []string{"numcached", "nc"})
viper.SetDefault("commands.numcached.is_admin", true)
viper.SetDefault("commands.numcached.description", "Outputs the number of tracks cached on disk if caching is enabled.")
viper.SetDefault("commands.numcached.messages.num_cached", "There are currently <b>%d</b> items stored in the cache.")
viper.SetDefault("commands.numtracks.aliases", []string{"numtracks", "numsongs", "nt"})
viper.SetDefault("commands.numtracks.is_admin", false)
viper.SetDefault("commands.numtracks.description", "Outputs the number of tracks currently in the queue.")
viper.SetDefault("commands.numtracks.messages.one_track", "There is currently <b>1</b> track in the queue.")
viper.SetDefault("commands.numtracks.messages.plural_tracks", "There are currently <b>%d</b> tracks in the queue.")
viper.SetDefault("commands.pause.aliases", []string{"pause"})
viper.SetDefault("commands.pause.is_admin", false)
viper.SetDefault("commands.pause.description", "Pauses audio playback.")
viper.SetDefault("commands.pause.messages.no_audio_error", "Either the audio is already paused, or there are no tracks in the queue.")
viper.SetDefault("commands.pause.messages.paused", "<b>%s</b> has paused audio playback.")
viper.SetDefault("commands.reload.aliases", []string{"reload", "r"})
viper.SetDefault("commands.reload.is_admin", true)
viper.SetDefault("commands.reload.description", "Reloads the configuration file.")
viper.SetDefault("commands.reload.messages.reloaded", "The configuration file has been successfully reloaded.")
viper.SetDefault("commands.reset.aliases", []string{"reset", "re"})
viper.SetDefault("commands.reset.is_admin", true)
viper.SetDefault("commands.reset.description", "Resets the queue by removing all queue items.")
viper.SetDefault("commands.reset.messages.queue_reset", "<b>%s</b> has reset the queue.")
viper.SetDefault("commands.resume.aliases", []string{"resume"})
viper.SetDefault("commands.resume.is_admin", false)
viper.SetDefault("commands.resume.description", "Resumes audio playback.")
viper.SetDefault("commands.resume.messages.audio_error", "Either the audio is already playing, or there are no tracks in the queue.")
viper.SetDefault("commands.resume.messages.resumed", "<b>%s</b> has resumed audio playback.")
viper.SetDefault("commands.setcomment.aliases", []string{"setcomment", "comment", "sc"})
viper.SetDefault("commands.setcomment.is_admin", true)
viper.SetDefault("commands.setcomment.description", "Sets the comment displayed next to MumbleDJ's username in Mumble.")
viper.SetDefault("commands.setcomment.messages.comment_removed", "The comment for the bot has been successfully removed.")
viper.SetDefault("commands.setcomment.messages.comment_changed", "The comment for the bot has been successfully changed to the following: %s")
viper.SetDefault("commands.shuffle.aliases", []string{"shuffle", "shuf", "sh"})
viper.SetDefault("commands.shuffle.is_admin", true)
viper.SetDefault("commands.shuffle.description", "Randomizes the tracks currently in the queue.")
viper.SetDefault("commands.shuffle.messages.not_enough_tracks_error", "There are not enough tracks in the queue to execute a shuffle.")
viper.SetDefault("commands.shuffle.messages.shuffled", "The audio queue has been shuffled.")
viper.SetDefault("commands.skip.aliases", []string{"skip", "s"})
viper.SetDefault("commands.skip.is_admin", false)
viper.SetDefault("commands.skip.description", "Places a vote to skip the current track.")
viper.SetDefault("commands.skip.messages.already_voted_error", "You have already voted to skip this track.")
viper.SetDefault("commands.skip.messages.voted", "<b>%s</b> has voted to skip the current track.")
viper.SetDefault("commands.skipplaylist.aliases", []string{"skipplaylist", "sp"})
viper.SetDefault("commands.skipplaylist.is_admin", false)
viper.SetDefault("commands.skipplaylist.description", "Places a vote to skip the current playlist.")
viper.SetDefault("commands.skipplaylist.messages.no_playlist_error", "The current track is not part of a playlist.")
viper.SetDefault("commands.skipplaylist.messages.already_voted_error", "You have already voted to skip this playlist.")
viper.SetDefault("commands.skipplaylist.messages.voted", "<b>%s</b> has voted to skip the current playlist.")
viper.SetDefault("commands.toggleshuffle.aliases", []string{"toggleshuffle", "toggleshuf", "togshuf", "tsh"})
viper.SetDefault("commands.toggleshuffle.is_admin", true)
viper.SetDefault("commands.toggleshuffle.description", "Toggles automatic track shuffling on/off.")
viper.SetDefault("commands.toggleshuffle.messages.toggled_off", "Automatic shuffling has been toggled off.")
viper.SetDefault("commands.toggleshuffle.messages.toggled_on", "Automatic shuffling has been toggled on.")
viper.SetDefault("commands.version.aliases", []string{"version"})
viper.SetDefault("commands.version.is_admin", false)
viper.SetDefault("commands.version.description", "Outputs the current version of MumbleDJ.")
viper.SetDefault("commands.version.messages.version", "MumbleDJ version: <b>%s</b>")
viper.SetDefault("commands.volume.aliases", []string{"volume", "vol", "v"})
viper.SetDefault("commands.volume.is_admin", false)
viper.SetDefault("commands.volume.description", "Changes the volume if an argument is provided, outputs the current volume otherwise.")
viper.SetDefault("commands.volume.messages.parsing_error", "The requested volume could not be parsed.")
viper.SetDefault("commands.volume.messages.out_of_range_error", "Volumes must be between the values <b>%.2f</b> and <b>%.2f</b>.")
viper.SetDefault("commands.volume.messages.current_volume", "The current volume is <b>%.2f</b>.")
viper.SetDefault("commands.volume.messages.volume_changed", "<b>%s</b> has changed the volume to <b>%.2f</b>.")
}
// ReadConfigFile reads in the config file and updates the configuration accordingly.

View File

@ -55,7 +55,7 @@ func (c *AddCommand) Execute(user *gumble.User, args ...string) (string, bool, e
)
if len(args) == 0 {
return "", true, errors.New("A URL must be supplied with the add command")
return "", true, errors.New(viper.GetString("commands.add.messages.no_url_error"))
}
for _, arg := range args {
@ -68,7 +68,7 @@ func (c *AddCommand) Execute(user *gumble.User, args ...string) (string, bool, e
}
if len(allTracks) == 0 {
return "", true, errors.New("No valid tracks were found with the provided URL(s)")
return "", true, errors.New(viper.GetString("commands.add.messages.no_valid_tracks_error"))
}
numTooLong := 0
@ -83,15 +83,15 @@ func (c *AddCommand) Execute(user *gumble.User, args ...string) (string, bool, e
}
if numAdded == 0 {
return "", true, errors.New("Your track(s) were either too long or an error occurred while processing them. No track(s) have been added.")
return "", true, errors.New(viper.GetString("commands.add.messages.tracks_too_long_error"))
} else if numAdded == 1 {
return fmt.Sprintf("<b>%s</b> added <b>1</b> track to the queue:<br>\"%s\" from %s",
return fmt.Sprintf(viper.GetString("commands.add.messages.one_track_added"),
user.Name, lastTrackAdded.GetTitle(), lastTrackAdded.GetService()), false, nil
}
retString := fmt.Sprintf("<b>%s</b> added <b>%d</b> tracks to the queue.", user.Name, numAdded)
retString := fmt.Sprintf(viper.GetString("commands.add.messages.many_tracks_added"), user.Name, numAdded)
if numTooLong != 0 {
retString += fmt.Sprintf("<br><b>%d</b> tracks could not be added due to error or because they are too long.", numTooLong)
retString += fmt.Sprintf(viper.GetString("commands.add.messages.num_tracks_too_long"), numTooLong)
}
return retString, false, nil
}

View File

@ -55,7 +55,7 @@ func (c *AddNextCommand) Execute(user *gumble.User, args ...string) (string, boo
)
if len(args) == 0 {
return "", true, errors.New("A URL must be supplied with the addnext command")
return "", true, errors.New(viper.GetString("commands.add.messages.no_url_error"))
}
for _, arg := range args {
@ -68,7 +68,7 @@ func (c *AddNextCommand) Execute(user *gumble.User, args ...string) (string, boo
}
if len(allTracks) == 0 {
return "", true, errors.New("No valid tracks were found with the provided URL(s)")
return "", true, errors.New(viper.GetString("commands.add.messages.no_valid_tracks_error"))
}
numTooLong := 0
@ -84,15 +84,15 @@ func (c *AddNextCommand) Execute(user *gumble.User, args ...string) (string, boo
}
if numAdded == 0 {
return "", true, errors.New("Your track(s) were either too long or an error occurred while processing them. No track(s) have been added.")
return "", true, errors.New(viper.GetString("commands.add.messages.tracks_too_long_error"))
} else if numAdded == 1 {
return fmt.Sprintf("<b>%s</b> added <b>1</b> track to the queue:<br>\"%s\" from %s",
return fmt.Sprintf(viper.GetString("commands.add.messages.one_track_added"),
user.Name, lastTrackAdded.GetTitle(), lastTrackAdded.GetService()), false, nil
}
retString := fmt.Sprintf("<b>%s</b> added <b>%d</b> tracks to the queue.", user.Name, numAdded)
retString := fmt.Sprintf(viper.GetString("commands.add.messages.many_tracks_added"), user.Name, numAdded)
if numTooLong != 0 {
retString += fmt.Sprintf("<br><b>%d</b> tracks could not be added due to error or because they are too long.", numTooLong)
retString += fmt.Sprintf(viper.GetString("commands.add.messages.num_tracks_too_long"), numTooLong)
}
return retString, false, nil
}

View File

@ -47,9 +47,9 @@ func (c *CacheSizeCommand) Execute(user *gumble.User, args ...string) (string, b
const bytesInMiB = 1048576
if !viper.GetBool("cache.enabled") {
return "", true, errors.New("Caching is currently disabled")
return "", true, errors.New(viper.GetString("commands.common_messages.caching_disabled_error"))
}
DJ.Cache.UpdateStatistics()
return fmt.Sprintf("The current size of the cache is <b>%.2v MiB</b>.", DJ.Cache.TotalFileSize/bytesInMiB), true, nil
return fmt.Sprintf(viper.GetString("commands.cachesize.messages.current_size"), DJ.Cache.TotalFileSize/bytesInMiB), true, nil
}

View File

@ -52,9 +52,9 @@ func (c *CurrentTrackCommand) Execute(user *gumble.User, args ...string) (string
)
if currentTrack, err = DJ.Queue.CurrentTrack(); err != nil {
return "", true, errors.New("There are no tracks in the queue")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
return fmt.Sprintf("The current track is \"%s\", added by <b>%s</b>.",
return fmt.Sprintf(viper.GetString("commands.currenttrack.messages.current_track"),
currentTrack.GetTitle(), currentTrack.GetSubmitter()), true, nil
}

View File

@ -45,11 +45,11 @@ func (c *ForceSkipCommand) IsAdminCommand() bool {
// return "This is a private message!", true, nil
func (c *ForceSkipCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if DJ.Queue.Length() == 0 {
return "", true, errors.New("The queue is currently empty. There are no tracks to skip")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
DJ.Queue.Skip()
return fmt.Sprintf("The current track has been forcibly skipped by <b>%s</b>.",
return fmt.Sprintf(viper.GetString("commands.forceskip.messages.track_skipped"),
user.Name), false, nil
}

View File

@ -52,15 +52,15 @@ func (c *ForceSkipPlaylistCommand) Execute(user *gumble.User, args ...string) (s
)
if currentTrack, err = DJ.Queue.CurrentTrack(); err != nil {
return "", true, errors.New("The queue is currently empty. There are no playlists to skip")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
if playlist := currentTrack.GetPlaylist(); playlist == nil {
return "", true, errors.New("The current track is not part of a playlist")
return "", true, errors.New(viper.GetString("commands.forceskipplaylist.messages.no_playlist_error"))
}
DJ.Queue.SkipPlaylist()
return fmt.Sprintf("The current playlist has been forcibly skipped by <b>%s</b>.",
return fmt.Sprintf(viper.GetString("commands.forceskipplaylist.messages.playlist_skipped"),
user.Name), false, nil
}

View File

@ -58,7 +58,7 @@ func (c *HelpCommand) Execute(user *gumble.User, args ...string) (string, bool,
}
}
totalString = "<br><b>Commands:</b><br>" + regularCommands
totalString = viper.GetString("commands.help.messages.commands_header") + regularCommands
isAdmin := false
if viper.GetBool("admins.enabled") {
@ -68,7 +68,7 @@ func (c *HelpCommand) Execute(user *gumble.User, args ...string) (string, bool,
}
if isAdmin {
totalString += "<br><b>Admin Commands:</b><br>" + adminCommands
totalString += viper.GetString("commands.help.messages.admin_commands_header") + adminCommands
}
return totalString, true, nil

View File

@ -47,12 +47,12 @@ func (c *JoinMeCommand) IsAdminCommand() bool {
func (c *JoinMeCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if DJ.AudioStream != nil && DJ.AudioStream.State() == gumbleffmpeg.StatePlaying &&
len(DJ.Client.Self.Channel.Users) > 1 {
return "", true, errors.New("Users in another channel are listening to me.")
return "", true, errors.New(viper.GetString("commands.joinme.messages.others_are_listening_error"))
}
DJ.Client.Do(func() {
DJ.Client.Self.Move(user.Channel)
})
return "I am now in your channel!", true, nil
return viper.GetString("commands.joinme.messages.in_your_channel"), true, nil
}

View File

@ -49,7 +49,7 @@ func (c *ListTracksCommand) IsAdminCommand() bool {
// return "This is a private message!", true, nil
func (c *ListTracksCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if DJ.Queue.Length() == 0 {
return "", true, errors.New("There are no tracks currently in the queue")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
numTracksToList := DJ.Queue.Length()
@ -57,14 +57,14 @@ func (c *ListTracksCommand) Execute(user *gumble.User, args ...string) (string,
if parsedNum, err := strconv.Atoi(args[0]); err == nil {
numTracksToList = parsedNum
} else {
return "", true, errors.New("An invalid integer was supplied")
return "", true, errors.New(viper.GetString("commands.listtracks.messages.invalid_integer_error"))
}
}
var buffer bytes.Buffer
DJ.Queue.Traverse(func(i int, track interfaces.Track) {
if i < numTracksToList {
buffer.WriteString(fmt.Sprintf("<b>%d</b>: \"%s\", added by <b>%s</b>.<br>",
buffer.WriteString(fmt.Sprintf(viper.GetString("commands.listtracks.messages.track_listing"),
i+1, track.GetTitle(), track.GetSubmitter()))
}
})

View File

@ -46,7 +46,7 @@ func (c *MoveCommand) IsAdminCommand() bool {
// return "This is a private message!", true, nil
func (c *MoveCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if len(args) == 0 {
return "", true, errors.New("A destination channel must be supplied to move the bot")
return "", true, errors.New(viper.GetString("commands.move.messages.no_channel_provided_error"))
}
channel := ""
for _, arg := range args {
@ -58,8 +58,8 @@ func (c *MoveCommand) Execute(user *gumble.User, args ...string) (string, bool,
DJ.Client.Self.Move(DJ.Client.Channels.Find(channels...))
})
} else {
return "", true, errors.New("The provided channel does not exist")
return "", true, errors.New(viper.GetString("commands.move.messages.channel_doesnt_exist_error"))
}
return fmt.Sprintf("You have successfully moved the bot to <b>%s</b>.", channel), true, nil
return fmt.Sprintf(viper.GetString("commands.move.messages.move_successful"), channel), true, nil
}

View File

@ -47,14 +47,14 @@ func (c *NextTrackCommand) IsAdminCommand() bool {
func (c *NextTrackCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
length := DJ.Queue.Length()
if length == 0 {
return "", true, errors.New("There are no tracks in the queue")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
if length == 1 {
return "", true, errors.New("The current track is the only track in the queue")
return "", true, errors.New(viper.GetString("commands.nexttrack.messages.current_track_only_error"))
}
nextTrack, _ := DJ.Queue.PeekNextTrack()
return fmt.Sprintf("The next track is \"%s\", added by <b>%s</b>.",
return fmt.Sprintf(viper.GetString("commands.nexttrack.messages.next_track"),
nextTrack.GetTitle(), nextTrack.GetSubmitter()), true, nil
}

View File

@ -46,10 +46,10 @@ func (c *NumCachedCommand) IsAdminCommand() bool {
// return "This is a private message!", true, nil
func (c *NumCachedCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if !viper.GetBool("cache.enabled") {
return "", true, errors.New("Caching is currently disabled")
return "", true, errors.New(viper.GetString("commands.common_messages.caching_disabled_error"))
}
DJ.Cache.UpdateStatistics()
return fmt.Sprintf("There are currently <b>%d</b> items stored in the cache.",
return fmt.Sprintf(viper.GetString("commands.numcached.messages.num_cached"),
DJ.Cache.NumAudioFiles), true, nil
}

View File

@ -46,8 +46,8 @@ func (c *NumTracksCommand) IsAdminCommand() bool {
func (c *NumTracksCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
length := DJ.Queue.Length()
if length == 1 {
return "There is currently <b>1</b> track in the queue.", true, nil
return viper.GetString("commands.numtracks.messages.one_track"), true, nil
}
return fmt.Sprintf("There are currently <b>%d</b> tracks in the queue.", length), true, nil
return fmt.Sprintf(viper.GetString("commands.numtracks.messages.plural_tracks"), length), true, nil
}

View File

@ -8,6 +8,7 @@
package commands
import (
"errors"
"fmt"
"github.com/layeh/gumble/gumble"
@ -45,7 +46,7 @@ func (c *PauseCommand) IsAdminCommand() bool {
func (c *PauseCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
err := DJ.Queue.PauseCurrent()
if err != nil {
return "", true, err
return "", true, errors.New(viper.GetString("commands.pause.messages.no_audio_error"))
}
return fmt.Sprintf("<b>%s</b> has paused audio playback.", user.Name), false, nil
return fmt.Sprintf(viper.GetString("commands.pause.messages.paused"), user.Name), false, nil
}

View File

@ -47,6 +47,6 @@ func (c *ReloadCommand) Execute(user *gumble.User, args ...string) (string, bool
return "", true, err
}
return "The configuration in the configuration file has been reloaded successfully.",
return viper.GetString("commands.reload.messages.reloaded"),
true, nil
}

View File

@ -45,7 +45,7 @@ func (c *ResetCommand) IsAdminCommand() bool {
// return "This is a private message!", true, nil
func (c *ResetCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if DJ.Queue.Length() == 0 {
return "", true, errors.New("The queue is already empty")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
if DJ.AudioStream != nil {
@ -59,5 +59,5 @@ func (c *ResetCommand) Execute(user *gumble.User, args ...string) (string, bool,
return "", true, err
}
return fmt.Sprintf("<b>%s</b> has reset the queue.", user.Name), false, nil
return fmt.Sprintf(viper.GetString("commands.reset.messages.queue_reset"), user.Name), false, nil
}

View File

@ -8,6 +8,7 @@
package commands
import (
"errors"
"fmt"
"github.com/layeh/gumble/gumble"
@ -45,7 +46,7 @@ func (c *ResumeCommand) IsAdminCommand() bool {
func (c *ResumeCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
err := DJ.Queue.ResumeCurrent()
if err != nil {
return "", true, err
return "", true, errors.New(viper.GetString("commands.resume.messages.audio_error"))
}
return fmt.Sprintf("<b>%s</b> has resumed audio playback.", user.Name), false, nil
return fmt.Sprintf(viper.GetString("commands.resume.messages.resumed"), user.Name), false, nil
}

View File

@ -48,7 +48,7 @@ func (c *SetCommentCommand) Execute(user *gumble.User, args ...string) (string,
DJ.Client.Do(func() {
DJ.Client.Self.SetComment("")
})
return "The comment for the bot has been successfully removed.", true, nil
return viper.GetString("commands.setcomment.messages.comment_removed"), true, nil
}
var newComment string
@ -61,6 +61,6 @@ func (c *SetCommentCommand) Execute(user *gumble.User, args ...string) (string,
DJ.Client.Self.SetComment(newComment)
})
return fmt.Sprintf("The comment for the bot has been successfully changed to the following: %s",
return fmt.Sprintf(viper.GetString("commands.setcomment.messages.comment_changed"),
newComment), true, nil
}

View File

@ -45,13 +45,13 @@ func (c *ShuffleCommand) IsAdminCommand() bool {
func (c *ShuffleCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
length := DJ.Queue.Length()
if length == 0 {
return "", true, errors.New("There are no tracks currently in the queue")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
if length <= 2 {
return "", true, errors.New("There are not enough tracks in the queue to execute a shuffle")
return "", true, errors.New(viper.GetString("commands.shuffle.messages.not_enough_tracks_error"))
}
DJ.Queue.ShuffleTracks()
return "The audio queue has been shuffled.", false, nil
return viper.GetString("commands.shuffle.messages.shuffled"), false, nil
}

View File

@ -45,11 +45,11 @@ func (c *SkipCommand) IsAdminCommand() bool {
// return "This is a private message!", true, nil
func (c *SkipCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if DJ.Queue.Length() == 0 {
return "", true, errors.New("The queue is currently empty. There is no track to skip")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
if err := DJ.Skips.AddTrackSkip(user); err != nil {
return "", true, errors.New("You have already voted to skip this track")
return "", true, errors.New(viper.GetString("commands.skip.messages.already_voted_error"))
}
return fmt.Sprintf("<b>%s</b> has voted to skip the current track.", user.Name), false, nil
return fmt.Sprintf(viper.GetString("commands.skip.messages.voted"), user.Name), false, nil
}

View File

@ -52,15 +52,15 @@ func (c *SkipPlaylistCommand) Execute(user *gumble.User, args ...string) (string
)
if currentTrack, err = DJ.Queue.CurrentTrack(); err != nil {
return "", true, errors.New("The queue is currently empty. There is no playlist to skip")
return "", true, errors.New(viper.GetString("commands.common_messages.no_tracks_error"))
}
if playlist := currentTrack.GetPlaylist(); playlist == nil {
return "", true, errors.New("The current track is not part of a playlist")
return "", true, errors.New(viper.GetString("commands.skipplaylist.messages.no_playlist_error"))
}
if err := DJ.Skips.AddPlaylistSkip(user); err != nil {
return "", true, errors.New("You have already voted to skip this playlist")
return "", true, errors.New(viper.GetString("commands.skipplaylist.messages.already_voted_error"))
}
return fmt.Sprintf("<b>%s</b> has voted to skip the current playlist.", user.Name), false, nil
return fmt.Sprintf(viper.GetString("commands.skipplaylist.messages.voted"), user.Name), false, nil
}

View File

@ -43,8 +43,8 @@ func (c *ToggleShuffleCommand) IsAdminCommand() bool {
func (c *ToggleShuffleCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if viper.GetBool("queue.automatic_shuffle_on") {
viper.Set("queue.automatic_shuffle_on", false)
return "Automatic shuffling has been toggled off.", false, nil
return viper.GetString("commands.toggleshuffle.messages.toggled_off"), false, nil
}
viper.Set("queue.automatic_shuffle_on", true)
return "Automatic shuffling has been toggled on.", false, nil
return viper.GetString("commands.toggleshuffle.messages.toggled_on"), false, nil
}

View File

@ -43,5 +43,5 @@ func (c *VersionCommand) IsAdminCommand() bool {
// Example return statement:
// return "This is a private message!", true, nil
func (c *VersionCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
return fmt.Sprintf("MumbleDJ version: <b>%s</b>", DJ.Version), true, nil
return fmt.Sprintf(viper.GetString("commands.version.messages.version"), DJ.Version), true, nil
}

View File

@ -47,16 +47,16 @@ func (c *VolumeCommand) IsAdminCommand() bool {
func (c *VolumeCommand) Execute(user *gumble.User, args ...string) (string, bool, error) {
if len(args) == 0 {
// Send the user the current volume level.
return fmt.Sprintf("The current volume is <b>%.2f</b>.", DJ.Volume), true, nil
return fmt.Sprintf(viper.GetString("commands.volume.messages.current_volume"), DJ.Volume), true, nil
}
newVolume, err := strconv.ParseFloat(args[0], 32)
if err != nil {
return "", true, errors.New("An error occurred while parsing the requested volume")
return "", true, errors.New(viper.GetString("commands.volume.messages.parsing_error"))
}
if newVolume < viper.GetFloat64("volume.lowest") || newVolume > viper.GetFloat64("volume.highest") {
return "", true, fmt.Errorf("Volumes must be between the values <b>%.2f</b> and <b>%.2f</b>",
return "", true, fmt.Errorf(viper.GetString("commands.volume.messages.out_of_range_error"),
viper.GetFloat64("volume.lowest"), viper.GetFloat64("volume.highest"))
}
@ -67,6 +67,6 @@ func (c *VolumeCommand) Execute(user *gumble.User, args ...string) (string, bool
}
DJ.Volume = newVolume32
return fmt.Sprintf("<b>%s</b> has changed the volume to <b>%.2f</b>.",
return fmt.Sprintf(viper.GetString("commands.volume.messages.volume_changed"),
user.Name, newVolume32), false, nil
}

View File

@ -140,17 +140,31 @@ commands:
# NOTE: Only one character (the first) is used.
prefix: "!"
common_messages:
no_tracks_error: "There are no tracks in the queue."
caching_disabled_error: "Caching is currently disabled."
# Below is a list of the commands supported by MumbleDJ. Each command has
# three configurable options:
# aliases: A list of names that can be used to execute the command.
# is_admin: true = only admins can execute the command, false = anyone can execute the command.
# description: Description shown for the command when the help command is executed.
# messages: Various messages that may be sent as a text message from the command. Useful for translating
# strings to other languages. Do NOT remove strings that begin with "%" (such as "%s", "%d", etc.)
# as they substituted with runtime data. Removing these strings will cause the bot to misbehave.
add:
aliases:
- "add"
- "a"
is_admin: false
description: "Adds a track or playlist from a media site to the queue."
messages:
no_url_error: "A URL must be supplied with the add command."
no_valid_tracks_error: "No valid tracks were found with the provided URL(s)."
tracks_too_long_error: "Your track(s) were either too long or an error occurred while processing them. No track(s) have been added."
one_track_added: "<b>%s</b> added <b>1</b> track to the queue:<br><i>%s</i> from %s"
many_tracks_added: "<b>%s</b> added <b>%d</b> tracks to the queue."
num_tracks_too_long: "<br><b>%d</b> tracks could not be added due to error or because they are too long."
addnext:
aliases:
@ -158,6 +172,7 @@ commands:
- "an"
is_admin: true
description: "Adds a track or playlist from a media site as the next item in the queue."
# addnext uses the messages defined for add.
cachesize:
aliases:
@ -165,6 +180,8 @@ commands:
- "cs"
is_admin: true
description: "Outputs the file size of the cache in MiB if caching is enabled."
messages:
current_size: "The current size of the cache is <b>%.2v MiB</b>."
currenttrack:
aliases:
@ -173,6 +190,8 @@ commands:
- "current"
is_admin: false
description: "Outputs information about the current track in the queue if one exists."
messages:
current_track: "The current track is <i>%s</i>, added by <b>%s</b>."
forceskip:
aliases:
@ -180,6 +199,8 @@ commands:
- "fs"
is_admin: true
description: "Immediately skips the current track."
messages:
track_skipped: "The current track has been forcibly skipped by <b>%s</b>."
forceskipplaylist:
aliases:
@ -187,6 +208,9 @@ commands:
- "fsp"
is_admin: true
description: "Immediately skips the current playlist."
messages:
no_playlist_error: "The current track is not part of a playlist."
playlist_skipped: "The current playlist has been forcibly skipped by <b>%s</b>."
help:
aliases:
@ -194,6 +218,9 @@ commands:
- "h"
is_admin: false
description: "Outputs this list of commands."
messages:
commands_header: "<br><b>Commands:</b><br>"
admin_commands_header: "<br><b>Admin Commands:</b><br>"
joinme:
aliases:
@ -201,6 +228,9 @@ commands:
- "join"
is_admin: true
description: "Moves MumbleDJ into your current channel if not playing audio to someone else."
messages:
others_are_listening_error: "Users in another channel are listening to me."
in_your_channel: "I am now in your channel!"
kill:
aliases:
@ -217,6 +247,9 @@ commands:
- "l"
is_admin: false
description: "Outputs a list of the tracks currently in the queue."
messages:
invalid_integer_error: "An invalid integer was supplied."
track_listing: "<b>%d</b>: <i>%s</i>, added by <b>%s</b>.<br>"
move:
aliases:
@ -224,6 +257,10 @@ commands:
- "m"
is_admin: true
description: "Moves the bot into the Mumble channel provided via argument."
messages:
no_channel_provided_error: "A destination channel must be supplied to move the bot."
channel_doesnt_exist_error: "The provided channel does not exist."
move_successful: "You have successfully moved the bot to <b>%s</b>."
nexttrack:
aliases:
@ -232,6 +269,9 @@ commands:
- "next"
is_admin: false
description: "Outputs information about the next track in the queue if one exists."
messages:
current_track_only_error: "The current track is the only track in the queue."
next_track: "The next track is <i>%s</i>, added by <b>%s</b>."
numcached:
aliases:
@ -239,6 +279,8 @@ commands:
- "nc"
is_admin: true
description: "Outputs the number of tracks cached on disk if caching is enabled."
messages:
num_cached: "There are currently <b>%d</b> items stored in the cache."
numtracks:
aliases:
@ -247,12 +289,18 @@ commands:
- "nt"
is_admin: false
description: "Outputs the number of tracks currently in the queue."
messages:
one_track: "There is currently <b>1</b> track in the queue."
plural_tracks: "There are currently <b>%d</b> tracks in the queue."
pause:
aliases:
- "pause"
is_admin: false
description: "Pauses audio playback."
messages:
no_audio_error: "Either the audio is already paused, or there are no tracks in the queue."
paused: "<b>%s</b> has paused audio playback."
reload:
aliases:
@ -260,6 +308,8 @@ commands:
- "r"
is_admin: true
description: "Reloads the configuration file."
messages:
reloaded: "The configuration file has been successfully reloaded."
reset:
aliases:
@ -267,12 +317,17 @@ commands:
- "re"
is_admin: true
description: "Resets the queue by removing all queue items."
messages:
queue_reset: "<b>%s</b> has reset the queue."
resume:
aliases:
- "resume"
is_admin: false
description: "Resumes audio playback."
messages:
audio_error: "Either the audio is already playing, or there are no tracks in the queue."
resumed: "<b>%s</b> has resumed audio playback."
setcomment:
aliases:
@ -281,6 +336,9 @@ commands:
- "sc"
is_admin: true
description: "Sets the comment displayed next to MumbleDJ's username in Mumble."
messages:
comment_removed: "The comment for the bot has been successfully removed."
comment_changed: "The comment for the bot has been successfully changed to the following: %s"
shuffle:
aliases:
@ -289,6 +347,9 @@ commands:
- "sh"
is_admin: true
description: "Randomizes the tracks currently in the queue."
messages:
not_enough_tracks_error: "There are not enough tracks in the queue to execute a shuffle."
shuffled: "The audio queue has been shuffled."
skip:
aliases:
@ -296,6 +357,9 @@ commands:
- "s"
is_admin: false
description: "Places a vote to skip the current track."
messages:
already_voted_error: "You have already voted to skip this track."
voted: "<b>%s</b> has voted to skip the current track."
skipplaylist:
aliases:
@ -303,6 +367,10 @@ commands:
- "sp"
is_admin: false
description: "Places a vote to skip the current playlist."
messages:
no_playlist_error: "The current track is not part of a playlist."
already_voted_error: "You have already voted to skip this playlist."
voted: "<b>%s</b> has voted to skip the current playlist."
toggleshuffle:
aliases:
@ -312,6 +380,10 @@ commands:
- "tsh"
is_admin: true
description: "Toggles automatic track shuffling on/off."
messages:
toggled_off: "Automatic shuffling has been toggled off."
toggled_on: "Automatic shuffling has been toggled on."
version:
aliases:
@ -319,10 +391,17 @@ commands:
- "v"
is_admin: false
description: "Outputs the current version of MumbleDJ."
messages:
version: "MumbleDJ version: <b>%s</b>"
volume:
aliases:
- "volume"
- "vol"
is_admin: false
description: "Changes the volume if an argument is provided, outputs the current volume otherwise."
description: "Changes the volume if an argument is provided, outputs the current volume otherwise."
messages:
parsing_error: "The requested volume could not be parsed."
out_of_range_error: "Volumes must be between the values <b>%.2f</b> and <b>%.2f</b>."
current_volume: "The current volume is <b>%.2f</b>."
volume_changed: "<b>%s</b> has changed the volume to <b>%.2f</b>."

View File

@ -32,7 +32,7 @@ func init() {
services.DJ = DJ
bot.DJ = DJ
DJ.Version = "3.0.0"
DJ.Version = "3.0.1"
logrus.SetLevel(logrus.WarnLevel)
}