Example #1
0
func (p *helpPlugin) HandleMessage(msg *mup.Message) {
	if msg.BotText == "" || msg.Bang != "" && strings.HasPrefix(msg.Text, msg.Bang) {
		return
	}
	cmdname := schema.CommandName(msg.BotText)
	if cmdname != "" {
		infos, err := p.pluginsWith(cmdname, false)
		if err == nil && len(infos) == 0 {
			infos, err = p.pluginsWith(cmdname, true)
			if len(infos) > 0 {
				p.sendNotUsable(msg, &infos[0], "running", "")
				return
			}
		}
		if err != nil {
			p.plugger.Logf("Cannot list available commands: %v", err)
			p.plugger.Sendf(msg, "Cannot list available commands: %v", err)
			return
		}
		if len(infos) == 0 {
			p.sendNotKnown(msg, cmdname)
			return
		}
		addr := msg.Address()
		for _, info := range infos {
			for _, target := range info.Targets {
				if target.Contains(addr) {
					return
				}
			}
		}
		p.sendNotUsable(msg, &infos[0], "enabled", "here")
	}
}
Example #2
0
func (m *pluginManager) loop() error {
	defer m.die()

	if m.config.Plugins != nil && len(m.config.Plugins) == 0 {
		<-m.tomb.Dying()
		return nil
	}

	m.tomb.Go(m.tail)

	m.updateKnown()
	m.handleRefresh()
	var refresh <-chan time.Time
	if m.config.Refresh > 0 {
		ticker := time.NewTicker(m.config.Refresh)
		defer ticker.Stop()
		refresh = ticker.C
	}
	plugins := m.database.C("plugins")
	for {
		m.session.Refresh()
		select {
		case msg := <-m.incoming:
			if msg.Command == cmdPong {
				continue
			}
			cmdName := schema.CommandName(msg.BotText)
			for name, state := range m.plugins {
				if state.info.LastId >= msg.Id || state.plugger.Target(msg) == nil {
					continue
				}
				state.info.LastId = msg.Id
				state.handle(msg, cmdName)
				err := plugins.UpdateId(name, bson.D{{"$set", bson.D{{"lastid", msg.Id}}}})
				if err != nil {
					logf("Cannot update last message id for plugin %q: %v", name, err)
					// TODO How to recover properly from this?
				}
			}
		case req := <-m.requests:
			switch req := req.(type) {
			case pluginRequestStop:
				return nil
			case pluginRequestRefresh:
				m.handleRefresh()
				close(req.done)
			default:
				panic("unknown request received by plugin manager")
			}
		case <-refresh:
			m.handleRefresh()
		}
	}
	return nil
}
Example #3
0
func (s *S) TestCommandParse(c *C) {
	for _, test := range parseTests {
		c.Logf("Processing command line: %q", test.text)
		name := schema.CommandName(test.text)
		cmd := commands.Command(name)
		if cmd == nil {
			c.Fatalf("Cannot find command %q", name)
		}
		opts, err := cmd.Parse(test.text)
		if test.error != "" {
			c.Assert(err, ErrorMatches, test.error)
		} else {
			c.Assert(err, IsNil)
			c.Assert(opts, DeepEquals, test.opts)
		}
	}
}
Example #4
0
// Sendf formats a PRIVMSG coming from "nick!~user@host" and delivers to the plugin
// being tested for handling as a message, as a command, or both, depending on the
// plugin specification and implementation.
//
// The formatted message may be prefixed by "[<target>@<account>,<option>] " to define
// the channel or bot nick the message was addressed to, the account name it was
// observed on, and a list of comma-separated options. All fields are optional, and
// default to "[mup@test] ". The only supported option at the moment is "raw", which
// causes the message text to be taken as a raw IRC protocol message. When providing
// a target without an account the "@" may be omitted, and the comma may be omitted
// if there are no options.
//
// Sendf always delivers the message to the plugin, irrespective of which targets
// are currently setup, as it doesn't make sense to test the plugin with a message
// that it cannot observe.
func (t *PluginTester) Sendf(format string, args ...interface{}) {
	account, message := parseSendfText(fmt.Sprintf(format, args...))
	msg := ParseIncoming(account, "mup", "!", message)
	t.state.handle(msg, schema.CommandName(msg.BotText))
}