<commit_before>package bot

import (
	"fmt"
	"log"
	"strings"
)

// Cmd holds the parsed user's input for easier handling of commands
type Cmd struct {
	Raw     string   // Raw is full string passed to the command
	Channel string   // Channel where the command was called
	Nick    string   // User who sent the message
	Message string   // Full string without the prefix
	Command string   // Command is the first argument passed to the bot
	FullArg string   // Full argument as a single string
	Args    []string // Arguments as array
}

// Passive Cmd have the basice information for passive commands to work on
type PassiveCmd struct {
	Raw     string // Raw message sent to the channel
	Channel string // Channel which the message was sent to
	Nick    string // Nick of the user which sent the message
}

type customCommand struct {
	Cmd         string
	CmdFunc     func(cmd *Cmd) (string, error)
	Description string
	ExampleArgs string
}

type incomingMessage struct {
	Channel        string
	Text           string
	SenderNick     string
	BotCurrentNick string
}

const (
	commandNotAvailable   = "Command %v not available."
	noCommandsAvailable   = "No commands available."
	errorExecutingCommand = "Error executing %s: %s"
	helpDescripton        = "Description: %s"
	helpUsage             = "Usage: %s%s %s"
	availableCommands     = "Available commands: %v"
	helpAboutCommand      = "Type: '%shelp <command>' to see details about a specific command."
	helpCommand           = "help"
)

type passiveCmdFunc func(cmd *PassiveCmd) (string, error)

var (
	commands        = make(map[string]*customCommand)
	passiveCommands = make(map[string]passiveCmdFunc)
)

// RegisterCommand adds a new command to the bot.
// The command(s) should be registered in the Ini() func of your package
// command: String which the user will use to execute the command, example: reverse
// decription: Description of the command to use in !help, example: Reverses a string
// exampleArgs: Example args to be displayed in !help <command>, example: string to be reversed
// cmdFunc: Function which will be executed. It will received a parsed command as a Cmd value
func RegisterCommand(command, description, exampleArgs string, cmdFunc func(cmd *Cmd) (string, error)) {
	commands[command] = &customCommand{
		Cmd:         command,
		CmdFunc:     cmdFunc,
		Description: description,
		ExampleArgs: exampleArgs,
	}
}

// RegisterPassiveCommand adds a new passive command to the bot.
// The command(s) should be registered in the Ini() func of your package
// Passive commands receives all the text posted to a channel without any parsing
// command: String used to identify the command, for internal use only (ex: logs)
// cmdFunc: Function which will be executed. It will received the raw message, channel and nick
func RegisterPassiveCommand(command string, cmdFunc func(cmd *PassiveCmd) (string, error)) {
	passiveCommands[command] = cmdFunc
}

func isPrivateMsg(channel, currentNick string) bool {
	return channel == currentNick
}

func messageReceived(channel, text, senderNick string, conn ircConnection) {
	if isPrivateMsg(channel, conn.GetNick()) {
		channel = senderNick // should reply in private
	}

	command := parse(text, channel, senderNick)
	if command == nil {
		handleMessage(&PassiveCmd{
			Raw:     text,
			Channel: channel,
			Nick:    senderNick,
		})
		return
	}

	if command.Command == helpCommand {
		help(command, channel, senderNick, conn)
	} else {
		handleCmd(command, conn)
	}

}

func handleMessage(c *PassiveCmd) {
	for k, v := range passiveCommands {
		log.Println("Executando: ", k)
		s, err := v(c)
		if err != nil {
			log.Println(err)
		}
		irccon.Privmsg(c.Channel, s)
	}
}

func handleCmd(c *Cmd, conn ircConnection) {
	cmd := commands[c.Command]

	if cmd == nil {
		log.Printf("Command not found %v", c.Command)
		return
	}

	log.Printf("HandleCmd %v %v", c.Command, c.FullArg)

	result, err := cmd.CmdFunc(c)

	if err != nil {
		errorMsg := fmt.Sprintf(errorExecutingCommand, c.Command, err.Error())
		log.Printf(errorMsg)
		conn.Privmsg(c.Channel, errorMsg)
	}

	if result != "" {
		conn.Privmsg(c.Channel, result)
	}
}

func help(c *Cmd, channel, senderNick string, conn ircConnection) {
	cmd := parse(CmdPrefix+c.FullArg, channel, senderNick)
	if cmd == nil {
		showAvailabeCommands(channel, conn)
		return
	}

	command := commands[cmd.Command]
	if command == nil {
		showAvailabeCommands(c.Channel, conn)
		return
	}

	showHelp(cmd, command, conn)
}

func showHelp(c *Cmd, help *customCommand, conn ircConnection) {
	if help.Description != "" {
		conn.Privmsg(c.Channel, fmt.Sprintf(helpDescripton, help.Description))
	}
	conn.Privmsg(c.Channel, fmt.Sprintf(helpUsage, CmdPrefix, c.Command, help.ExampleArgs))
}

func showAvailabeCommands(channel string, conn ircConnection) {
	cmds := make([]string, 0)
	for k := range commands {
		cmds = append(cmds, k)
	}
	conn.Privmsg(channel, fmt.Sprintf(helpAboutCommand, CmdPrefix))
	conn.Privmsg(channel, fmt.Sprintf(availableCommands, strings.Join(cmds, ", ")))
}
<commit_msg>Fixed passive commands description<commit_after>package bot

import (
	"fmt"
	"log"
	"strings"
)

// Cmd holds the parsed user's input for easier handling of commands
type Cmd struct {
	Raw     string   // Raw is full string passed to the command
	Channel string   // Channel where the command was called
	Nick    string   // User who sent the message
	Message string   // Full string without the prefix
	Command string   // Command is the first argument passed to the bot
	FullArg string   // Full argument as a single string
	Args    []string // Arguments as array
}

// PassiveCmd holds the information which will be passed to passive commands when receiving a message on the channel
type PassiveCmd struct {
	Raw     string // Raw message sent to the channel
	Channel string // Channel which the message was sent to
	Nick    string // Nick of the user which sent the message
}

type customCommand struct {
	Cmd         string
	CmdFunc     func(cmd *Cmd) (string, error)
	Description string
	ExampleArgs string
}

type incomingMessage struct {
	Channel        string
	Text           string
	SenderNick     string
	BotCurrentNick string
}

const (
	commandNotAvailable   = "Command %v not available."
	noCommandsAvailable   = "No commands available."
	errorExecutingCommand = "Error executing %s: %s"
	helpDescripton        = "Description: %s"
	helpUsage             = "Usage: %s%s %s"
	availableCommands     = "Available commands: %v"
	helpAboutCommand      = "Type: '%shelp <command>' to see details about a specific command."
	helpCommand           = "help"
)

type passiveCmdFunc func(cmd *PassiveCmd) (string, error)

var (
	commands        = make(map[string]*customCommand)
	passiveCommands = make(map[string]passiveCmdFunc)
)

// RegisterCommand adds a new command to the bot.
// The command(s) should be registered in the Ini() func of your package
// command: String which the user will use to execute the command, example: reverse
// decription: Description of the command to use in !help, example: Reverses a string
// exampleArgs: Example args to be displayed in !help <command>, example: string to be reversed
// cmdFunc: Function which will be executed. It will received a parsed command as a Cmd value
func RegisterCommand(command, description, exampleArgs string, cmdFunc func(cmd *Cmd) (string, error)) {
	commands[command] = &customCommand{
		Cmd:         command,
		CmdFunc:     cmdFunc,
		Description: description,
		ExampleArgs: exampleArgs,
	}
}

// RegisterPassiveCommand adds a new passive command to the bot.
// The command(s) should be registered in the Ini() func of your package
// Passive commands receives all the text posted to a channel without any parsing
// command: String used to identify the command, for internal use only (ex: logs)
// cmdFunc: Function which will be executed. It will received the raw message, channel and nick
func RegisterPassiveCommand(command string, cmdFunc func(cmd *PassiveCmd) (string, error)) {
	passiveCommands[command] = cmdFunc
}

func isPrivateMsg(channel, currentNick string) bool {
	return channel == currentNick
}

func messageReceived(channel, text, senderNick string, conn ircConnection) {
	if isPrivateMsg(channel, conn.GetNick()) {
		channel = senderNick // should reply in private
	}

	command := parse(text, channel, senderNick)
	if command == nil {
		handleMessage(&PassiveCmd{
			Raw:     text,
			Channel: channel,
			Nick:    senderNick,
		})
		return
	}

	if command.Command == helpCommand {
		help(command, channel, senderNick, conn)
	} else {
		handleCmd(command, conn)
	}

}

func handleMessage(c *PassiveCmd) {
	for k, v := range passiveCommands {
		log.Println("Executando: ", k)
		s, err := v(c)
		if err != nil {
			log.Println(err)
		}
		irccon.Privmsg(c.Channel, s)
	}
}

func handleCmd(c *Cmd, conn ircConnection) {
	cmd := commands[c.Command]

	if cmd == nil {
		log.Printf("Command not found %v", c.Command)
		return
	}

	log.Printf("HandleCmd %v %v", c.Command, c.FullArg)

	result, err := cmd.CmdFunc(c)

	if err != nil {
		errorMsg := fmt.Sprintf(errorExecutingCommand, c.Command, err.Error())
		log.Printf(errorMsg)
		conn.Privmsg(c.Channel, errorMsg)
	}

	if result != "" {
		conn.Privmsg(c.Channel, result)
	}
}

func help(c *Cmd, channel, senderNick string, conn ircConnection) {
	cmd := parse(CmdPrefix+c.FullArg, channel, senderNick)
	if cmd == nil {
		showAvailabeCommands(channel, conn)
		return
	}

	command := commands[cmd.Command]
	if command == nil {
		showAvailabeCommands(c.Channel, conn)
		return
	}

	showHelp(cmd, command, conn)
}

func showHelp(c *Cmd, help *customCommand, conn ircConnection) {
	if help.Description != "" {
		conn.Privmsg(c.Channel, fmt.Sprintf(helpDescripton, help.Description))
	}
	conn.Privmsg(c.Channel, fmt.Sprintf(helpUsage, CmdPrefix, c.Command, help.ExampleArgs))
}

func showAvailabeCommands(channel string, conn ircConnection) {
	cmds := make([]string, 0)
	for k := range commands {
		cmds = append(cmds, k)
	}
	conn.Privmsg(channel, fmt.Sprintf(helpAboutCommand, CmdPrefix))
	conn.Privmsg(channel, fmt.Sprintf(availableCommands, strings.Join(cmds, ", ")))
}

{'fraction_non_alphanumeric': 0.09933970631713807, 'fraction_numerical': 0.00019710259189908348, 'mean_word_length': 3.8416030534351147, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2411960', 'n_tokens_mistral': 3173, 'n_tokens_neox': 3070, 'n_words': 1077}