All pastes #1828886 Raw Edit

Miscellany

public python v1 · immutable
#1828886 ·published 2010-03-08 19:00 UTC
rendered paste body
#### This is an example plugin that sends a message to a channel every 60 seconds,# includes commands to stop, start, and reset the spammer, and a command to# schedule a one-off event#### these are the default plugin modulesimport supybot.utils as utilsfrom supybot.commands import *import supybot.plugins as pluginsimport supybot.ircutils as ircutilsimport supybot.callbacks as callbacks# these are the extra modules we'll be usingimport timeimport supybot.ircmsgs as ircmsgsimport supybot.schedule as scheduleclass Spam(callbacks.Plugin):    """Add the help for "@plugin help Spam" here    This should describe *how* to use this plugin."""    def __init__(self, irc):        # these two lines are required if you have a custom __init__()        self.__parent = super(Spam, self)        self.__parent.__init__(irc)        # this is the channel we want to spam, and how frequently we want to do it.        # It would be nicer to put it in a supybot config variable instead, but for        # this demonstration, defining it in the plugin itself is fine.        self.spamChannel = '#testytest'        self.spamTime = 60        # scheduler events are global, so we want to test to make sure the event doesn't        # already exist.  That is, even if the plugin is reloaded, the event sticks        # around.  That means that you also have to be a little careful with your        # event names, especially if you have multiple plugins adding events.  It also        # means that events will stick around even if the plugin they originated in        # is unloaded.  I don't know how to delete them automatically on an unload, but        # it's not normally an issue.  Just make sure to stop the event before unloading        # the plugin if that's what you want.        try:            schedule.removeEvent('mySpamEvent')        except KeyError:            pass        # now that we know there's no event by that name scheduled, we can create one.        # but first, we need to define a local helper function that will do the thing        # that we want.  You can put the full contents into here, but I prefer to use        # separate methods, as it makes the code easier to get around in.  We need        # the helper function because when you add events, you can't include arguments.        def myEventCaller():            self.spamEvent(irc)        # and now we can schedule the actual event        # schedule.addPeriodicEvent(f, t, name=None, now=True)        # f is the method, t is the time in seconds, name gives it a name and is optional        # (but highly recommended, so that you can refer to the event in the future.        # otherwise, it's easy to accumulate duplicate events), and 'now' specifies        # whether to perform the action immediately, or to wait until time is up to        # perform it for the first time.  Default is True.        schedule.addPeriodicEvent(myEventCaller, self.spamTime, 'mySpamEvent')        self.irc = irc    # make sure to have a capital letter or underscore or something, as it's not a method    # that we want turned into an IRC command    def spamEvent(self, irc):        # we need to use queueMsg() rather than reply(), because when the event is        # scheduled on loading the plugin (as opposed to scheduling it with one of the        # commands that we'll define next), it recieves its irc object from __init__().        # When the bot is started, the irc object that comes from __init__() doesn't        # include a reply() method, because it's not loading in response to a command;        # it's loading on the bot startup.  If you don't want your event to be scheduled        # automatically and so don't schedule it from __init__(), but only from an IRC        # command, then it's safe to use irc.reply(), as there are no circumstances        # under which the irc object won't have a reply() method.        irc.queueMsg(ircmsgs.privmsg(self.spamChannel, 'I\'m spamming the channel!'))    def start(self, irc, msg, args):        """takes no arguments        A command to start the spammer."""        # don't forget to redefine the event wrapper        def myEventCaller():            self.spamEvent(irc)        try:            schedule.addPeriodicEvent(myEventCaller, self.spamTime, 'mySpamEvent', False)        except AssertionError:            irc.reply('Error: the spammer was already running!')        else:            irc.reply('Spammer started!')    start = wrap(start)    def stop(self, irc, msg, args):        """takes no arguments        A command to stop the spammer."""        try:            schedule.removeEvent('mySpamEvent')        except KeyError:            irc.reply('Error: the spammer wasn\'t running!')        else:            irc.reply('Spammer stopped.')    stop = wrap(stop)    def reset(self, irc, msg, args):        """takes no arguments        Resets the spammer.  Can be useful if something changes and you want the        spam to reflect that.  For example, if you defined the spamChannel as a        supybot config, and changed it while the spammer was running, it would still        keep going on the same channel until you reset it."""        def myEventCaller():            self.spamEvent(irc)        try:            schedule.removeEvent('mySpamEvent')        except KeyError:            irc.reply('Spammer wasn\'t running')        schedule.addPeriodicEvent(myEventCaller, self.spamTime, 'mySpamEvent', False)        irc.reply('Spammer reset sucessfully!')    reset = wrap(reset)    # Here's an example of a one-off event, scheduled by an IRC command    def sayhi(self, irc, msg, args, delay):        """<time delay>        Says hi after the specified delay"""        def myEventCaller():            self.Hello(irc)        # for a one-off event, the time is an absolute time, not relative.  So we need        # to get the current time and add to it however long we want to wait        t = time.time() + delay        # since we don't specify a name, we won't be able to reference the events in        # the future, but that's ok, because these are one-off events, so even if you        # do call it multiple times, it'll just reply that same number of times and        # then stop.  But in some circumstances you might want to name them.  Just        # remember that it'll give an AssertionError if you try to create two events        # with the same name        schedule.addEvent(myEventCaller, t)        irc.reply('"hi" scheduled for %d seconds from now!' % delay)    sayhi = wrap(sayhi, ['positiveInt'])    def Hello(self, irc):        # since the irc object is coming from an IRC command, rather than from __init__(),        # it's guaranteed to have a reply() method, so it's safe to use that.  It        # might be better to to use queueMsg() instead, regardless, but I don't know        # enough about the supybot internals to say whether one is prefered over        # the other        irc.reply('hi!')Class = Spam