Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin conflicts #76

Open
moggers87 opened this issue Feb 12, 2016 · 2 comments
Open

Plugin conflicts #76

moggers87 opened this issue Feb 12, 2016 · 2 comments

Comments

@moggers87
Copy link
Collaborator

We need some way of making a plugin "greedy" or maybe just ignore !command messages.

@tsyesika
Copy link
Owner

tsyesika commented Apr 14, 2018

It seems this effects many plugins not just beertime and 8ball. As discussed on IRC :)

I have a solution where an additional attribute can be included in the Info object. The attribute will reflect if a plugin is (going to be) called. On an empty Info object (which you use to register events) this will default to False, so by default events are not called if a plugin is called. This seems to be the most megbot-like solution, we're already using the Info object to tell events when to trigger or not.

The obvious problem is how do you handle it when you want both to be called when a plugin is called and when it isn't. It seems to me there are a few solutions to this:

  • Register your event twice: once with Info.triggered = False (the default) and one with Info.triggered = True
  • Allow attributes to take multiple values via tuples e.g. Info.triggered = (True, False) the downside to this is some attributes such as Info.nickmask are tuples, it's ambiguous and inconsistent. 👎
  • I think my preference would be allow them to take a callable which returns if it matches, example of this with the seen plugin below:
def init(connection):
    eventID = 'seenEvent'
    info = connection.libraries["IRCObjects"].Info()

    # this will peform an event on privmsg.
    info.action = "PRIVMSG"
    info.triggered = lambda t: True # Always match on this value.
    event = connection.core["Corehandler"].IRCEvent(info, on_PRIVMSG, eventID)
    connection.handler.register_event(event)

With this solution in place: beertime wouldn't conflict with anything as it'd leave this as default, nor would reply. The scene plugin can be made to always log as it does now with a small additional change. We also keep the idea of Info being created to reflect when you want your event called.

@moggers87 moggers87 changed the title Beertime and 8ball conflict Plugin conflicts Apr 14, 2018
@moggers87
Copy link
Collaborator Author

That means attaching plugin state onto the incoming Info object (otherwise how is the callable on Info.triggered?). I don't like that at all.

My personal preference would be if event handlers returned something, perhaps a truthy value:

def on_PRIV(conn, info):
    store.add_message(info)  # do something or other
    # implicit return None, which is falsey

def on_cmd(conn, info):
    who, what, when = store.get_user(info)
    info.channel.send("%s said %s on %s" % (who, what, when))
    return True

def init(connection):
    # register these event, order is important
    ## etc. etc. etc.

Then whatever is iterating over can do something like:

for callback in list_of_matching_callbacks:
   result = callback(conn, info)
   if result:
       break

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants