1
1
Fork
You've already forked MegBot
0

Plugin conflicts #76

Open
opened 2016年02月12日 19:20:09 +01:00 by moggers87 · 2 comments
moggers87 commented 2016年02月12日 19:20:09 +01:00 (Migrated from github.com)
Copy link

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

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

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.

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. :-1: - 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: ```python 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 commented 2018年04月14日 17:05:41 +02:00 (Migrated from github.com)
Copy link

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
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 in to join this conversation.
No Branch/Tag specified
master
tests-question-mark
too-tired-to-test
JT-keeper
master-backports
No results found.
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
tsyesika/MegBot#76
Reference in a new issue
tsyesika/MegBot
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?