bot

package
v1.6.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2017 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const (
	NORMAL_CHARACTER    = string('\u000F')
	BOLD_CHARACTER      = string('\u0002')
	UNDERLINE_CHARACTER = string('\u001F')
	ITALIC_CHARACTER    = string('\u001D')
	INVERSE_CHARACTER   = string('\u0016')
	COLOUR_CHARACTER    = string('\u0003')
)

Variables

View Source
var AddCommand = Command{
	Name: "add",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 1 {
			event.Connection.Privmsg(target, boldText("!music add <music link>"))
			return
		}
		url := parameters[0]

		_, err := bot.player.Add(url, event.User)
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}

		if bot.player.GetStatus() != player.PLAYING {
			bot.player.Play()
		}
	},
}
View Source
var CurrentCommand = Command{
	Name: "current",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		song, remaining := bot.player.GetCurrent()
		if song != nil {
			event.Connection.Privmsgf(target, "Current song: %s%s%s "+italicText("(%s remaining)"), BOLD_CHARACTER, formatSong(song), BOLD_CHARACTER, util.FormatDuration(remaining))
			event.Connection.Privmsgf(target, "Progress: %s", boldText(progressString(song.GetDuration(), remaining)))
		} else {
			event.Connection.Privmsg(target, italicText("Nothing currently playing"))
		}
	},
}
View Source
var FlushCommand = Command{
	Name: "flush",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		bot.player.EmptyQueue()
		bot.announceMessage(true, event, boldText(event.Nick)+" emptied the playlist")
	},
}
View Source
var HelpCommand = Command{
	Name: "help",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		var names []string
		for commandName := range bot.commands {
			names = append(names, boldText(commandName))
		}
		sort.Strings(names)
		event.Connection.Privmsgf(target, "Available commands: %s", strings.Join(names, ", "))
	},
}
View Source
var HistoryCommand = Command{
	Name: "history",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		items := bot.player.GetHistory()
		if len(items) == 0 {
			event.Connection.Privmsg(target, italicText("The history is empty"))
		}

		dur := time.Duration(0)
		for i, song := range items {
			if i < 10 {
				event.Connection.Privmsgf(target, "%d. %s", i+1, formatSong(song))
			}
			dur += song.GetDuration()
		}

		if len(items) > 10 {
			event.Connection.Privmsgf(target, italicText("And %d more.."), len(items)-10)
		}

		event.Connection.Privmsgf(target, "Total duration: %s%s", BOLD_CHARACTER, util.FormatDuration(dur))
	},
}
View Source
var InsertCommand = Command{
	Name: "insert",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 2 {
			event.Connection.Privmsg(target, boldText("Usage: !music insert <queueIndex> <music link>"))
			return
		}
		position, err := strconv.ParseInt(parameters[0], 10, 32)
		if err != nil {
			event.Connection.Privmsg(target, inverseText("Error parsing position"))
			return
		}

		_, err = bot.player.Insert(parameters[1], int(position), event.User)
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
	},
}
View Source
var JumpCommand = Command{
	Name: "jump",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 1 {
			event.Connection.Privmsg(target, boldText("Usage: !music jump <deltaQueueIndex> (positive index for forwards, negative index for backwards)"))
			return
		}

		index, err := strconv.ParseInt(parameters[0], 10, 32)
		if err != nil {
			event.Connection.Privmsg(target, inverseText("Error parsing jump index"))
			return
		}
		_, err = bot.player.Jump(int(index))
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
		bot.announceMessagef(true, event, "%s jumped to song at index %d", boldText(event.Nick), index)
	},
}
View Source
var LogCommand = Command{
	Name: "log",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)

		if bot.config.LogFile == "" {
			event.Connection.Privmsgf(target, "%sCannot show log, no logfile configured", ITALIC_CHARACTER)
			return
		}

		file, err := os.Open(bot.config.LogFile)
		if err != nil {
			logrus.Errorf("bot.LogCommand: Error opening file: [%s] %v", bot.config.LogFile, err)
			return
		}
		defer file.Close()

		var lines []string
		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			lines = append(lines, scanner.Text())
		}
		err = scanner.Err()
		if err != nil {
			logrus.Errorf("bot.LogCommand: Error scanning file: [%s] %v", bot.config.LogFile, err)
			return
		}

		for i := len(lines) - 11; i < len(lines); i++ {
			if i < 0 {
				continue
			}
			event.Connection.Privmsgf(target, "#%03d: %s", i+1, lines[i])
		}
	},
}
View Source
var NextCommand = Command{
	Name: "next",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		_, err := bot.player.Next()
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
		bot.announceMessage(true, event, boldText(event.Nick)+" skipped to the next song")
	},
}
View Source
var OpenCommand = Command{
	Name: "open",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 1 {
			event.Connection.Privmsg(target, boldText("Usage: !music open <music link>"))
			return
		}
		url := parameters[0]

		_, err := bot.player.Insert(url, 0, event.User)
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}

		bot.player.Play()
	},
}
View Source
var PauseCommand = Command{
	Name: "pause",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		err := bot.player.Pause()
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
		song, remaining := bot.player.GetCurrent()
		state := bot.player.GetStatus()
		switch state {
		case player.PAUSED:
			bot.announceMessage(false, event, boldText(event.Nick)+" paused the player")
		case player.PLAYING:
			bot.announceMessage(false, event, boldText(event.Nick)+" unpaused the player")
		}
		if song != nil {
			bot.announceMessagef(false, event, "Progress: %s", boldText(progressString(song.GetDuration(), remaining)))
		}
	},
}
View Source
var PlayCommand = Command{
	Name: "play",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		_, err := bot.player.Play()
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
		bot.announceMessage(true, event, boldText(event.Nick)+" started the player")
	},
}
View Source
var PreviousCommand = Command{
	Name: "previous",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		_, err := bot.player.Previous()
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
		bot.announceMessage(true, event, boldText(event.Nick)+" skipped to the previous song")
	},
}
View Source
var QueueCommand = Command{
	Name: "queue",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		items := bot.player.GetQueue()
		if len(items) == 0 {
			event.Connection.Privmsg(target, italicText("The queue is empty"))
		}

		dur := time.Duration(0)
		for i, song := range items {
			if i < 10 {
				event.Connection.Privmsgf(target, "%d. %s", i+1, formatSong(song))
			}
			dur += song.GetDuration()
		}

		if len(items) > 10 {
			event.Connection.Privmsgf(target, italicText("And %d more.."), len(items)-10)
		}

		event.Connection.Privmsgf(target, "Total duration: %s%s", BOLD_CHARACTER, util.FormatDuration(dur))
	},
}
View Source
var RemoveCommand = Command{
	Name: "remove",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 1 {
			event.Connection.Privmsg(target, boldText("Usage: !music remove <queueIndex> [<amountToRemove>]"))
			return
		}
		position, err := strconv.ParseInt(parameters[0], 10, 32)
		if err != nil {
			event.Connection.Privmsg(target, inverseText("Error parsing queue index"))
			return
		}

		amount := int64(1)
		if len(parameters) > 1 {
			amount, err = strconv.ParseInt(parameters[1], 10, 32)
			if err != nil {
				event.Connection.Privmsg(target, inverseText("Error parsing amount"))
				return
			}
		}

		err = bot.player.Remove(int(position), int(amount))
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}

		bot.announceMessagef(true, event, "%s removed %d songs at queue index %d", boldText(event.Nick), amount, position)
	},
}
View Source
var SearchAddCommand = Command{
	Name: "search-add",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 1 {
			event.Connection.Privmsgf(target, boldText("Usage: !music search-add [<track|album|playlist>] [<%s>] <search term>"), strings.ToLower(strings.Join(getPlayerNames(bot.player), "|")))
			return
		}

		results, err := searchSongs(bot.player, parameters, 1)
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
		if len(results) == 0 {
			event.Connection.Privmsg(target, italicText("Nothing found!"))
			return
		}
		for _, res := range results {
			for _, item := range res {
				_, err := bot.player.Add(item.GetURL(), event.User)
				if err != nil {
					event.Connection.Privmsg(target, inverseText(err.Error()))
					return
				}
				if bot.player.GetStatus() != player.PLAYING {
					bot.player.Play()
				}
				return
			}
		}
	},
}
View Source
var SearchCommand = Command{
	Name: "search",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 1 {
			event.Connection.Privmsgf(target, boldText("Usage: !music search [<track|album|playlist>] [<%s>] <search term>"), strings.ToLower(strings.Join(getPlayerNames(bot.player), "|")))
			return
		}

		results, err := searchSongs(bot.player, parameters, 5)
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
		if len(results) == 0 {
			event.Connection.Privmsg(target, italicText("Nothing found!"))
			return
		}
		baseNameWidth := 80
		for plyr, res := range results {
			for i, item := range res {
				resultName := formatSong(item)
				paddingLength := baseNameWidth - utf8.RuneCountInString(resultName)
				if paddingLength > 0 {
					resultName += strings.Repeat(" ", paddingLength)
				}

				event.Connection.Privmsgf(target, "[%s #%d] %s | %s", plyr, i+1, boldText(resultName), item.GetURL())
			}
		}
	},
}
View Source
var SeekCommand = Command{
	Name: "seek",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 1 {
			event.Connection.Privmsg(target, boldText("Usage: !music seek <secondsInSong> Or: !music seek <percentage>%"))
			return
		}
		seekStr := parameters[0]
		var seekSeconds int64
		if strings.HasSuffix(seekStr, "%") {
			percentage, err := strconv.ParseInt(seekStr[:len(seekStr)-1], 10, 32)
			if err != nil {
				event.Connection.Privmsg(target, inverseText("Error parsing seek percentage"))
				return
			}
			song, _ := bot.player.GetCurrent()
			if song == nil {
				event.Connection.Privmsg(target, inverseText("Nothing playing!"))
				return
			}
			duration := song.GetDuration().Nanoseconds() / 100 * percentage
			seekSeconds = duration / int64(time.Second)
		} else {
			var err error
			seekSeconds, err = strconv.ParseInt(seekStr, 10, 32)
			if err != nil {
				event.Connection.Privmsg(target, inverseText("Error parsing seek seconds"))
				return
			}
		}
		err := bot.player.Seek(int(seekSeconds))
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
			return
		}
		song, remaining := bot.player.GetCurrent()
		if song != nil {
			bot.announceMessagef(false, event, "Progress: %s", boldText(progressString(song.GetDuration(), remaining)))
		}
	},
}
View Source
var ShuffleCommand = Command{
	Name: "shuffle",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		bot.player.ShuffleQueue()
		bot.announceMessage(true, event, boldText(event.Nick)+" shuffled the playlist")
	},
}
View Source
var StatsCommand = Command{
	Name: "stats",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		bot.ircConn.Privmsgf(target, "%s Statistics!", GetMusicBotStringFormatted())

		stats := bot.player.GetStatistics()

		var timeByPlayer []string
		for player, time := range stats.TimeByPlayer {
			timeByPlayer = append(timeByPlayer, fmt.Sprintf("%s: %s%s%s", player, BOLD_CHARACTER, util.FormatDuration(time), BOLD_CHARACTER))
		}
		bot.ircConn.Privmsgf(target, "Total play time: %s%v%s (%s)", BOLD_CHARACTER, util.FormatDuration(stats.TotalTimePlayed), BOLD_CHARACTER, strings.Join(timeByPlayer, " | "))

		var playedByPlayer []string
		for player, count := range stats.SongsPlayedByPlayer {
			playedByPlayer = append(playedByPlayer, fmt.Sprintf("%s: %s%d%s", player, BOLD_CHARACTER, count, BOLD_CHARACTER))
		}
		bot.ircConn.Privmsgf(target, "Total songs played: %s%d%s (%s)", BOLD_CHARACTER, stats.TotalSongsPlayed, BOLD_CHARACTER, strings.Join(playedByPlayer, " | "))
		bot.ircConn.Privmsgf(target, "Total songs queued: %s%d", BOLD_CHARACTER, stats.TotalSongsQueued)
		bot.ircConn.Privmsgf(target, "Total times skipped: %s%d", BOLD_CHARACTER, stats.TotalTimesNext+stats.TotalTimesPrevious+stats.TotalTimesJump)
		bot.ircConn.Privmsgf(target, "Total times paused: %s%d", BOLD_CHARACTER, stats.TotalTimesPaused)

		var songQueuers []string
		pairs := util.GetSortedStringIntMap(stats.SongsAddedByUser)
		pos := 1
		for i := len(pairs) - 1; i >= 0; i-- {
			songQueuers = append(songQueuers, fmt.Sprintf("%d. %s: %s%d%s", pos, pairs[i].Key, BOLD_CHARACTER, pairs[i].Val, BOLD_CHARACTER))
			pos++
			if pos > 10 {
				break
			}
		}
		bot.ircConn.Privmsgf(target, "Top 10 song queuers: %s", strings.Join(songQueuers, " | "))
	},
}
View Source
var StopCommand = Command{
	Name: "stop",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		err := bot.player.Stop()
		if err != nil {
			event.Connection.Privmsg(target, inverseText(err.Error()))
		}
		bot.announceMessage(true, event, boldText(event.Nick)+" stopped the player")
	},
}
View Source
var VersionCommand = Command{
	Name: "version",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)

		bot.ircConn.Privmsgf(target, "%s %s (%s)", GetMusicBotStringFormatted(), util.VersionTag, util.GitCommit)
		bot.ircConn.Privmsgf(target, "Built: %s", util.BuildDate)
		bot.ircConn.Privmsgf(target, "Built on: %s", util.BuildHost)
		bot.ircConn.Privmsgf(target, "GO version: %s", util.GoVersion)
	},
}
View Source
var VolCommand = Command{
	Name: "vol",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		if len(parameters) < 1 {
			event.Connection.Privmsg(target, "!music vol <volume>")
			return
		}

		vol, err := strconv.Atoi(parameters[0])
		if err != nil {
			event.Connection.Privmsgf(target, "%s%v", INVERSE_CHARACTER, err)
			return
		}

		err = volumecontrol.SetVolume(vol)
		if err != nil {
			event.Connection.Privmsgf(target, "%s%v", INVERSE_CHARACTER, err)
			return
		}
	},
}
View Source
var VolDownCommand = Command{
	Name: "vol--",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		err := volumecontrol.DecreaseVolume(10)
		if err != nil {
			target, _, _ := bot.getTarget(event)
			event.Connection.Privmsgf(target, "%s%v", INVERSE_CHARACTER, err)
		}
	},
}
View Source
var VolUpCommand = Command{
	Name: "vol++",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		err := volumecontrol.IncreaseVolume(10)
		if err != nil {
			target, _, _ := bot.getTarget(event)
			event.Connection.Privmsgf(target, "%s%v", INVERSE_CHARACTER, err)
		}
	},
}
View Source
var WhitelistCommand = Command{
	Name: "whitelist",
	Function: func(bot *MusicBot, event *irc.Event, parameters []string) {
		target, _, _ := bot.getTarget(event)
		realname := event.User
		if len(parameters) < 1 {
			event.Connection.Privmsg(target, boldText("Usage: !music whitelist <show|add|remove> [user]"))
			return
		}

		subcommand := parameters[0]
		switch subcommand {
		case "show":
			message := "Current whitelist: "
			for _, name := range bot.whitelist {
				message += " " + underlineText(name)
			}
			event.Connection.Privmsg(target, message)
		case "add":
			if len(parameters) < 2 {
				event.Connection.Privmsg(target, boldText("Usage: !music whitelist add [user]"))
				return
			}
			user := parameters[1]
			if realname != bot.config.IRC.Master {
				event.Connection.Privmsgf(target, italicText("Only %s is allowed to edit the whitelist"), bot.config.IRC.Master)
				return
			}

			isWhitelisted, _ := bot.isUserWhitelisted(user)
			if isWhitelisted {
				event.Connection.Privmsgf(target, italicText("User %s is already in the whitelist"), user)
				return
			}
			bot.whitelist = append(bot.whitelist, user)

			err := config.WriteWhitelist(bot.config.IRC.WhiteListPath, bot.whitelist)
			if err != nil {
				logrus.Errorf("Whitelist: Error writing whitelist [%s], %v", bot.config.IRC.WhiteListPath, err)
				event.Connection.Privmsg(target, err.Error())
				return
			}
			logrus.Infof("Whitelist: User %s added to whitelist by %s", user, event.Nick)
			event.Connection.Privmsgf(target, italicText("User %s added to whitelist by %s"), user, event.Nick)
		case "remove":
			if len(parameters) < 2 {
				event.Connection.Privmsg(target, boldText("Usage: !music whitelist remove [user]"))
				return
			}
			user := parameters[1]
			if realname != bot.config.IRC.Master {
				event.Connection.Privmsgf(target, italicText("Only %s is allowed to edit the whitelist"), bot.config.IRC.Master)
				return
			}

			isWhitelisted, index := bot.isUserWhitelisted(user)
			if !isWhitelisted {
				event.Connection.Privmsgf(target, italicText("User %s is not in the whitelist"), user)
				return
			}

			bot.whitelist = append(bot.whitelist[:index], bot.whitelist[index+1:]...)
			err := config.WriteWhitelist(bot.config.IRC.WhiteListPath, bot.whitelist)
			if err != nil {
				logrus.Errorf("Whitelist: Error writing whitelist [%s], %v", bot.config.IRC.WhiteListPath, err)
				event.Connection.Privmsg(target, err.Error())
				return
			}
			logrus.Infof("Whitelist: User %s removed from whitelist by %s", user, event.Nick)
			event.Connection.Privmsgf(target, italicText("User %s removed from whitelist by %s"), user, event.Nick)
		}
	},
}

Functions

func GetMusicBotStringFormatted added in v1.5.0

func GetMusicBotStringFormatted() (s string)

Types

type Color

type Color string
const (
	COLOUR_WHITE       Color = "00"
	COLOUR_BLACK       Color = "01"
	COLOUR_BLUE        Color = "02"
	COLOUR_GREEN       Color = "03"
	COLOUR_RED         Color = "04"
	COLOUR_BROWN       Color = "05"
	COLOUR_PURPLE      Color = "06"
	COLOUR_ORANGE      Color = "07"
	COLOUR_YELLOW      Color = "08"
	COLOUR_LIGHT_GREEN Color = "09"
	COLOUR_TEAL        Color = "10"
	COLOUR_CYAN        Color = "11"
	COLOUR_LIGHT_BLUE  Color = "12"
	COLOUR_PINK        Color = "13"
	COLOUR_GREY        Color = "14"
	COLOUR_LIGHT_GREY  Color = "15"
	COLOUR_DEFAULT     Color = "99"
	COLOUR_NONE        Color = ""
)

type Command

type Command struct {
	Name     string
	Function func(bot *MusicBot, event *irc.Event, parameters []string)
}

type MusicBot

type MusicBot struct {
	// contains filtered or unexported fields
}

func NewMusicBot

func NewMusicBot(conf *config.MusicBot) (mb *MusicBot, err error)

func (*MusicBot) Announce

func (m *MusicBot) Announce(message string)

func (*MusicBot) Announcef added in v1.5.0

func (m *MusicBot) Announcef(format string, a ...interface{})

func (*MusicBot) SetPlayer added in v1.5.0

func (m *MusicBot) SetPlayer(plr player.MusicPlayer)

func (*MusicBot) Start

func (m *MusicBot) Start() (err error)

func (*MusicBot) Stop

func (m *MusicBot) Stop() (err error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL