Commits

Jason R. Coombs committed 9069a75

Instead of persistent=True, let's have a method execute_every

Comments (0)

Files changed (2)

 2012-01-13 Jason R. Coombs <jaraco@jaraco.com>
-    * Add support for repeated delayed commands (persistent).
-	* Fix the global event handler priority bug #3165329.
+    * Add support for periodic commands in irclib (.execute_every).
+    * Fix the global event handler priority bug #3165329.
 
 2008-09-11  Keltus <keltus@users.sourceforge.net>
     * ircbot.py: Reverted a leftover testing fragment that broke ircbot.py
     * irclib.py: Reverted changes in irclib that don't really belong in the core lib
     * irclib.py: Add support for ssl
     * irclib.py: Add support for ipv6
-	* python-irclib now requires python 2.3 and above (for ssl and ipv6)
+    * python-irclib now requires python 2.3 and above (for ssl and ipv6)
 
 2006-03-09  Keltus <keltus@users.sourceforge.net>
-	* README: Minor update
+    * README: Minor update
 
 2005-12-24  Keltus <keltus@users.sourceforge.net>
-	* Released version 0.4.6.
+    * Released version 0.4.6.
 
-	* irclib.py (VERSION):
-	* python-irclib.spec.in:
-	Preparations for version 0.4.6.
+    * irclib.py (VERSION):
+    * python-irclib.spec.in:
+    Preparations for version 0.4.6.
 
 2005-12-23  Keltus <keltus@users.sourceforge.net>
-	* dccsend:
-	* dccreceive:
-	* irclib.py:
-	* ircbot.py:
-	* irccat:
-	* irccat2:
-	* servermap:
-	* testbot.py:
-	Code modernization - String methods used instead of deprecated
-	string functions, keyword 'in' used for membership testing instead
-	of 'has_key' method, etc.
+    * dccsend:
+    * dccreceive:
+    * irclib.py:
+    * ircbot.py:
+    * irccat:
+    * irccat2:
+    * servermap:
+    * testbot.py:
+    Code modernization - String methods used instead of deprecated
+    string functions, keyword 'in' used for membership testing instead
+    of 'has_key' method, etc.
 
 2005-12-06  Keltus <keltus@users.sourceforge.net>
-	* irclib.py (ServerConnection.process_data): Reversed fix from
-	2005-05-28. This is strange because there was a bug before and
-	now it's gone. Either python changed something, or the IRC
-	networks changed something. Confirmed by peter.
+    * irclib.py (ServerConnection.process_data): Reversed fix from
+    2005-05-28. This is strange because there was a bug before and
+    now it's gone. Either python changed something, or the IRC
+    networks changed something. Confirmed by peter.
 
 2005-11-03  Keltus <keltus@users.sourceforge.net>
-	* irclib.py (numeric_events): Renamed numeric code 332 from topic
-	to currenttopic (the message when "/topic <chan>" is sent), so it
-	doesn't collide with TOPIC (the message when the topic is set).
+    * irclib.py (numeric_events): Renamed numeric code 332 from topic
+    to currenttopic (the message when "/topic <chan>" is sent), so it
+    doesn't collide with TOPIC (the message when the topic is set).
 
 2005-08-27  Keltus <keltus@users.sourceforge.net>
-	* irclib.py (ServerConnection.disconnect): Fixed infinitely
-	recursive calls when disconnecting with a failed connection. Bug
-	reported by Erik Max Francis.
+    * irclib.py (ServerConnection.disconnect): Fixed infinitely
+    recursive calls when disconnecting with a failed connection. Bug
+    reported by Erik Max Francis.
 
 2005-08-18  Keltus <keltus@users.sourceforge.net>
-	* irclib.py: Made ServerConnection.disconnect more consistant and
-	changed some functions to use it instead of quit. Previously,
-	disconnect would ignore the quit message, but now it sends a quit
-	message and disconnect. Suggestion by Erik Max Francis.
-	* ircbot.py: Changed to use ServerConnection.disconnect instead of
-	ServerConnection.quit as well.
+    * irclib.py: Made ServerConnection.disconnect more consistant and
+    changed some functions to use it instead of quit. Previously,
+    disconnect would ignore the quit message, but now it sends a quit
+    message and disconnect. Suggestion by Erik Max Francis.
+    * ircbot.py: Changed to use ServerConnection.disconnect instead of
+    ServerConnection.quit as well.
 
 2005-05-28  Keltus <keltus@users.sourceforge.net>
-	* irclib.py (ServerConnection.process_data): Fixed quit arguments
-	to return a list rather than a list of a list. Patch from peter.
+    * irclib.py (ServerConnection.process_data): Fixed quit arguments
+    to return a list rather than a list of a list. Patch from peter.
 
 2005-05-18  Keltus <keltus@users.sourceforge.net>
-	* Released version 0.4.5.
+    * Released version 0.4.5.
 
-	* irclib.py (ServerConnection.__init__): Added self.socket = None
-	to be able to process events when ServerConnection is not
-	connected to a socket. Patch from alst.
+    * irclib.py (ServerConnection.__init__): Added self.socket = None
+    to be able to process events when ServerConnection is not
+    connected to a socket. Patch from alst.
 
-	* irclib.py (VERSION):
-	* python-irclib.spec.in:
-	Preparations for version 0.4.5.
+    * irclib.py (VERSION):
+    * python-irclib.spec.in:
+    Preparations for version 0.4.5.
 
 2005-04-26  Keltus <keltus@users.sourceforge.net>
-	* irclib.py (IRC.__doc__): Corrected server.process_forever() to
-	irc.process_forever(). Suggestion by olecom.
+    * irclib.py (IRC.__doc__): Corrected server.process_forever() to
+    irc.process_forever(). Suggestion by olecom.
 
 2005-04-17  Keltus <keltus@users.sourceforge.net>
-	* irclib.py (ServerConnection.process_data): Moved event
-	translation code.
-	* irclib.py (ServerConnection): Reverted the 2005-01-28 change
-	because it breaks jump_server().
-	* irclib.py: minor comment changes
+    * irclib.py (ServerConnection.process_data): Moved event
+    translation code.
+    * irclib.py (ServerConnection): Reverted the 2005-01-28 change
+    because it breaks jump_server().
+    * irclib.py: minor comment changes
 
 2005-04-03  Keltus <keltus@users.sourceforge.net>
-	* irclib.py (protocol_events): Added "pong" and "invite" events.
-	Patch from Adam Mikuta.
-	* irclib.py (ServerConnection.part): Added message parameter.
-	Patch from Adam Mikuta.
+    * irclib.py (protocol_events): Added "pong" and "invite" events.
+    Patch from Adam Mikuta.
+    * irclib.py (ServerConnection.part): Added message parameter.
+    Patch from Adam Mikuta.
 
 2005-02-23  Keltus <keltus@users.sourceforge.net>
-	* Released version 0.4.4.
+    * Released version 0.4.4.
 
-	* irclib.py (VERSION):
-	* python-irclib.spec.in:
-	Preparations for version 0.4.4.
+    * irclib.py (VERSION):
+    * python-irclib.spec.in:
+    Preparations for version 0.4.4.
 
 2005-01-28  Keltus <keltus@users.sourceforge.net>
-	* irclib.py: (ServerConnection): Moved
-	self.irclibobj._remove_connection call from	close() to
-	disconnect(). Patch from Alexey Nezhdanov.
+    * irclib.py: (ServerConnection): Moved
+    self.irclibobj._remove_connection call from close() to
+    disconnect(). Patch from Alexey Nezhdanov.
 
 2005-01-25  Keltus <keltus@users.sourceforge.net>
-	* irclib.py (ServerConnection.connect): closes socket if a
-	connection does not occur
-	* irclib.py (ServerConnection.connect): "Changing server" ->
-	"Changing servers" (more ubiquitous quit phrase)
+    * irclib.py (ServerConnection.connect): closes socket if a
+    connection does not occur
+    * irclib.py (ServerConnection.connect): "Changing server" ->
+    "Changing servers" (more ubiquitous quit phrase)
 
 2005-01-23  Keltus <keltus@users.sourceforge.net>
 
-	* irclib.py: Removed depreciated apply functions. python-irclib is
-	now compatible with Python 1.6 and above.
-	* testbot.py: Removed redundant extra start() call
+    * irclib.py: Removed depreciated apply functions. python-irclib is
+    now compatible with Python 1.6 and above.
+    * testbot.py: Removed redundant extra start() call
 
 2005-01-20  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.4.3.
-	* Makefile: Removed more GNU make specific constructs.
+    * Released version 0.4.3.
+    * Makefile: Removed more GNU make specific constructs.
 
 2005-01-19  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Makefile: Don't require GNU make.
+    * Makefile: Don't require GNU make.
 
 2005-01-19  Keltus  <keltus@users.sourceforge.net>
 
-	* ircbot.py (IRCDict.__iter__): Added __iter__ method for IRCDict.
+    * ircbot.py (IRCDict.__iter__): Added __iter__ method for IRCDict.
 
 2005-01-17  Joel Rosdahl  <joel@rosdahl.net>
 
-	* ircbot.py (IRCDict.__contains__): Added __contains__method for
-	IRCDict. Patch from Keltus.
-	(SingleServerIRCBot.on_ctcp): Corrected default decoding of CTCP
-	DCC CHAT. Patch from Keltus.
+    * ircbot.py (IRCDict.__contains__): Added __contains__method for
+    IRCDict. Patch from Keltus.
+    (SingleServerIRCBot.on_ctcp): Corrected default decoding of CTCP
+    DCC CHAT. Patch from Keltus.
 
-	* irclib.py (VERSION):
-	* python-irclib.spec.in:
-	Preparations for version 0.4.3.
+    * irclib.py (VERSION):
+    * python-irclib.spec.in:
+    Preparations for version 0.4.3.
 
-	* debian: Removed Debian package directory since python-irclib is
-	in Debian now.
+    * debian: Removed Debian package directory since python-irclib is
+    in Debian now.
 
-	* ircbot.py (SingleServerIRCBot._on_namreply): Improved comment
-	about arguments to the function. Patch from Keltus.
-	(Channel.has_allow_external_messages): Renamed from
-	has_message_from_outside_protection. Patch from Keltus.
+    * ircbot.py (SingleServerIRCBot._on_namreply): Improved comment
+    about arguments to the function. Patch from Keltus.
+    (Channel.has_allow_external_messages): Renamed from
+    has_message_from_outside_protection. Patch from Keltus.
 
-	* irclib.py (ServerConnection.quit): Added comment about how some
-	IRC servers' treat QUIT messages. Patch from Keltus.
+    * irclib.py (ServerConnection.quit): Added comment about how some
+    IRC servers' treat QUIT messages. Patch from Keltus.
 
-	* ircbot.py (SingleServerIRCBot.jump_server): Improved jump_server
-	behaviour. Patch from Keltus.
+    * ircbot.py (SingleServerIRCBot.jump_server): Improved jump_server
+    behaviour. Patch from Keltus.
 
 2004-08-04  Joel Rosdahl  <joel@rosdahl.net>
 
-	* irclib.py (ServerConnection.process_data): Added "bonus" action
-	event that is triggered on CTCP ACTION messages.
+    * irclib.py (ServerConnection.process_data): Added "bonus" action
+    event that is triggered on CTCP ACTION messages.
 
 2004-07-09  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.4.2.
+    * Released version 0.4.2.
 
-	* debian/rules: Remove built *.pyc files before making package.
+    * debian/rules: Remove built *.pyc files before making package.
 
-	* irclib.py (DEBUG):
-	* debian/changelog:
-	* python-irclib.spec.in:
-	Preparations for version 0.4.2.
+    * irclib.py (DEBUG):
+    * debian/changelog:
+    * python-irclib.spec.in:
+    Preparations for version 0.4.2.
 
-	* irclib.py (ServerNotConnectedError): New exception.
-	(ServerConnection.send_raw): Fix bug #922446, "Raise
-	IllegalStateException in send_raw when disconnected".
+    * irclib.py (ServerNotConnectedError): New exception.
+    (ServerConnection.send_raw): Fix bug #922446, "Raise
+    IllegalStateException in send_raw when disconnected".
 
 2003-10-30  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.4.1.
+    * Released version 0.4.1.
 
-	* debian/examples: Added dccreceive and dccsend as example files
-	in Debian.
+    * debian/examples: Added dccreceive and dccsend as example files
+    in Debian.
 
-	* python-irclib.spec.in: Likewise.
+    * python-irclib.spec.in: Likewise.
 
 2003-10-29  Joel Rosdahl  <joel@rosdahl.net>
 
-	* debian: Added Debian packaging files.
+    * debian: Added Debian packaging files.
 
-	* setup.py.in: Create setup.py from setup.py.in.
+    * setup.py.in: Create setup.py from setup.py.in.
 
-	* python-irclib.spec.in: RPM spec file from Gary Benson.
+    * python-irclib.spec.in: RPM spec file from Gary Benson.
 
-	* testbot.py (TestBot.on_nicknameinuse): New method.
+    * testbot.py (TestBot.on_nicknameinuse): New method.
 
-	* irclib.py (ServerConnection.process_data): Record nickname when
-	welcome message is sent to trap nickname change triggered in a
-	nicknameinuse callback.
+    * irclib.py (ServerConnection.process_data): Record nickname when
+    welcome message is sent to trap nickname change triggered in a
+    nicknameinuse callback.
 
-	* ircbot.py (SingleServerIRCBot._on_join): Use
-	Connection.get_nickname instead of relying on self._nickname.
-	(SingleServerIRCBot._on_kick): Likewise.
-	(SingleServerIRCBot._on_part): And here too.
-	(SingleServerIRCBot._on_nick): No need to remember nickname change
-	here.
+    * ircbot.py (SingleServerIRCBot._on_join): Use
+    Connection.get_nickname instead of relying on self._nickname.
+    (SingleServerIRCBot._on_kick): Likewise.
+    (SingleServerIRCBot._on_part): And here too.
+    (SingleServerIRCBot._on_nick): No need to remember nickname change
+    here.
 
 2003-08-31  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.4.0.
+    * Released version 0.4.0.
 
-	Implemented DCC support (based on patches from Adam Langley and
-	Marco Bettio):
+    Implemented DCC support (based on patches from Adam Langley and
+    Marco Bettio):
 
-	* irclib.py (IRC.dcc): New method.
-	(DCCConnectionError): New class.
-	(DCCConnection): New class.
-	(SimpleIRCClient.__init__): Added dcc_connections attribute.
-	(SimpleIRCClient._dcc_disconnect): New method.
-	(SimpleIRCClient.connect): Added localaddress and
-	localport parameters. The socket will be bound accordingly before
-	connecting.
-	(SimpleIRCClient.dcc_connect): New method.
-	(SimpleIRCClient.dcc_listen): New method.
-	(ip_numstr_to_quad): New function.
-	(ip_quad_to_numstr): New function.
+    * irclib.py (IRC.dcc): New method.
+    (DCCConnectionError): New class.
+    (DCCConnection): New class.
+    (SimpleIRCClient.__init__): Added dcc_connections attribute.
+    (SimpleIRCClient._dcc_disconnect): New method.
+    (SimpleIRCClient.connect): Added localaddress and
+    localport parameters. The socket will be bound accordingly before
+    connecting.
+    (SimpleIRCClient.dcc_connect): New method.
+    (SimpleIRCClient.dcc_listen): New method.
+    (ip_numstr_to_quad): New function.
+    (ip_quad_to_numstr): New function.
 
-	* ircbot.py (SingleServerIRCBot.on_ctcp): Relay DCC CHAT CTCPs to
-	the on_dccchat method.
+    * ircbot.py (SingleServerIRCBot.on_ctcp): Relay DCC CHAT CTCPs to
+    the on_dccchat method.
 
-	* testbot.py: Added support for accepting DCC chats and for
-	initiating DCC chats via a "dcc" command.
+    * testbot.py: Added support for accepting DCC chats and for
+    initiating DCC chats via a "dcc" command.
 
-	* dccreceive: New example program.
+    * dccreceive: New example program.
 
-	* dccsend: New example program.
+    * dccsend: New example program.
 
-	* Makefile: Added dccreceive and dccsend to dist files.
+    * Makefile: Added dccreceive and dccsend to dist files.
 
-	Other changes:
+    Other changes:
 
-	* setup.py: Added.
+    * setup.py: Added.
 
-	* irclib.py (ServerConnection.connect, ServerConnection.user):
-	Send USER command according to RFC 2812.
-	(ServerConnection.connect): Added localaddress and
-	localport parameters. The socket will be bound accordingly before
-	connecting.
-	(ServerConnection.process_data): Ignore empty lines from the
-	server. (Patch by Jason Wies.)
-	(ServerConnection._get_socket): Simplified.
-	(ServerConnection.remove_global_handler): Added. (Patch from
-	Brandon Beck.)
+    * irclib.py (ServerConnection.connect, ServerConnection.user):
+    Send USER command according to RFC 2812.
+    (ServerConnection.connect): Added localaddress and
+    localport parameters. The socket will be bound accordingly before
+    connecting.
+    (ServerConnection.process_data): Ignore empty lines from the
+    server. (Patch by Jason Wies.)
+    (ServerConnection._get_socket): Simplified.
+    (ServerConnection.remove_global_handler): Added. (Patch from
+    Brandon Beck.)
 
-	* ircbot.py (SingleServerIRCBot.on_ctcp): Prepend VERSION reply
-	with VERSION. (Patch from Andrew Gaul.)
+    * ircbot.py (SingleServerIRCBot.on_ctcp): Prepend VERSION reply
+    with VERSION. (Patch from Andrew Gaul.)
 
-	* Makefile: Added setup.py to dist files. Also create zip archive.
+    * Makefile: Added setup.py to dist files. Also create zip archive.
 
-	* README: Added requirements and installation sections.
+    * README: Added requirements and installation sections.
 
 2002-03-01  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.3.4.
+    * Released version 0.3.4.
 
-	Corrected problems spotted by Markku H�nninen <hmm@iki.fi>:
+    Corrected problems spotted by Markku H�nninen <hmm@iki.fi>:
 
-	* irccat2 (IRCCat.on_welcome): Added missing connection argument.
-	(IRCCat.on_join): Likewise.
-	(IRCCat.on_disconnect): Likewise.
+    * irccat2 (IRCCat.on_welcome): Added missing connection argument.
+    (IRCCat.on_join): Likewise.
+    (IRCCat.on_disconnect): Likewise.
 
-	* irclib.py (ServerConnection.ison): Bug fix: Join nicks by space
-	instead of commas.
+    * irclib.py (ServerConnection.ison): Bug fix: Join nicks by space
+    instead of commas.
 
-	* irclib.py (ServerConnection.whowas): Bug fix: Let the max
-	argument default to the empty string.
+    * irclib.py (ServerConnection.whowas): Bug fix: Let the max
+    argument default to the empty string.
 
-	* irclib.py (numeric_events): Added new events: traceservice,
-	tracereconnect, tryagain, invitelist, endofinvitelist, exceptlist,
-	endofexceptlist, unavailresource, nochanmodes, banlistfull,
-	restricted and uniqopprivsneeded.
+    * irclib.py (numeric_events): Added new events: traceservice,
+    tracereconnect, tryagain, invitelist, endofinvitelist, exceptlist,
+    endofexceptlist, unavailresource, nochanmodes, banlistfull,
+    restricted and uniqopprivsneeded.
 
 2002-02-17  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.3.3.
+    * Released version 0.3.3.
 
-	* Makefile, README, .cvsignore: Removed documentation generated by
-	pythondoc.  Use pydoc instead.
+    * Makefile, README, .cvsignore: Removed documentation generated by
+    pythondoc.  Use pydoc instead.
 
-	* servermap: Removed some excess whitespace.
+    * servermap: Removed some excess whitespace.
 
-	* README: Mention http://python-irclib.sourceforge.net.
+    * README: Mention http://python-irclib.sourceforge.net.
 
-	* Makefile (dist): Changed archive name from irclib-* to
-	python-irclib-*.
+    * Makefile (dist): Changed archive name from irclib-* to
+    python-irclib-*.
 
-	Changed license from GPL 2 to LGPL 2.1:
+    Changed license from GPL 2 to LGPL 2.1:
 
-	* COPYING: New license text.
+    * COPYING: New license text.
 
-	* irclib.py, ircbot.py, servermap: New license header.
+    * irclib.py, ircbot.py, servermap: New license header.
 
 2001-10-21  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.3.2.
+    * Released version 0.3.2.
 
-	* irclib.py (_parse_modes): Fixed problem found by Tom Morton: the
-	mode parsing code bailed out if a unary mode character didn't have
-	a corresponding argument.
+    * irclib.py (_parse_modes): Fixed problem found by Tom Morton: the
+    mode parsing code bailed out if a unary mode character didn't have
+    a corresponding argument.
 
-	* irclib.py (_alpha): Fixed bug found by Tom Morton: w was missing
-	in the alphabet used by irc_lower().
+    * irclib.py (_alpha): Fixed bug found by Tom Morton: w was missing
+    in the alphabet used by irc_lower().
 
-	* ircbot.py: Removed redundant import of is_channel.
+    * ircbot.py: Removed redundant import of is_channel.
 
-	* servermap: Clarified copyright and license.
+    * servermap: Clarified copyright and license.
 
-	* irccat: Ditto.
+    * irccat: Ditto.
 
-	* irccat2: Ditto.
+    * irccat2: Ditto.
 
 2000-12-11  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.3.1.
+    * Released version 0.3.1.
 
-	* irclib.py (IRC.process_once): Work-around for platform-dependent
-	select() on Windows systems.
+    * irclib.py (IRC.process_once): Work-around for platform-dependent
+    select() on Windows systems.
 
-	* ircbot.py: Clarification of SingleServerIRCBot doc string.
+    * ircbot.py: Clarification of SingleServerIRCBot doc string.
 
 2000-11-26  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.3.0.
+    * Released version 0.3.0.
 
-	* Makefile (dist): Include ircbot.py again.
+    * Makefile (dist): Include ircbot.py again.
 
-	* README: Updated.
+    * README: Updated.
 
-	* irclib.py (ServerConnection.get_nickname): Renamed from
-	get_nick_name.
-	(ServerConnection._get_socket): Return None if not connected.
+    * irclib.py (ServerConnection.get_nickname): Renamed from
+    get_nick_name.
+    (ServerConnection._get_socket): Return None if not connected.
 
 2000-11-25  Joel Rosdahl  <joel@rosdahl.net>
 
-	* irclib.py (ServerConnection.process_data): all_raw_messages
-	instead of allrawmessages.
-	(IRC._handle_event): Added "all_events" event type.
-	(nm_to_n): Renamed from nick_from_nickmask.
-	(nm_to_uh): Renamed from userhost_from_nickmask.
-	(nm_to_h): Renamed from host_from_nickmask.
-	(nm_to_u): Renamed from user_from_nickmask.
-	(SimpleIRCClient): Created.
+    * irclib.py (ServerConnection.process_data): all_raw_messages
+    instead of allrawmessages.
+    (IRC._handle_event): Added "all_events" event type.
+    (nm_to_n): Renamed from nick_from_nickmask.
+    (nm_to_uh): Renamed from userhost_from_nickmask.
+    (nm_to_h): Renamed from host_from_nickmask.
+    (nm_to_u): Renamed from user_from_nickmask.
+    (SimpleIRCClient): Created.
 
 2000-11-22  Joel Rosdahl  <joel@rosdahl.net>
 
-	* irclib.py (lower_irc_string): Use translation instead.
-	(ServerConnection.process_data): Split non-RFC-compliant lines a
-	bit more intelligently.
-	(ServerConnection.process_data): Removed unnecessary try/except
-	block.
-	(ServerConnection.get_server_name): Return empty server if
-	unknown.
-	(_rfc_1459_command_regexp): Tweaked a bit.
+    * irclib.py (lower_irc_string): Use translation instead.
+    (ServerConnection.process_data): Split non-RFC-compliant lines a
+    bit more intelligently.
+    (ServerConnection.process_data): Removed unnecessary try/except
+    block.
+    (ServerConnection.get_server_name): Return empty server if
+    unknown.
+    (_rfc_1459_command_regexp): Tweaked a bit.
 
-	* ircbot.py: Rewritten.
+    * ircbot.py: Rewritten.
 
 2000-11-21  Joel Rosdahl  <joel@rosdahl.net>
 
-	* irclib.py (IRC.process_forever): Default to processing a bit
-	more often.
+    * irclib.py (IRC.process_forever): Default to processing a bit
+    more often.
 
 2000-10-29  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.2.4.
+    * Released version 0.2.4.
 
-	* Makefile (dist): Include generated documentation in
-	distribution.
+    * Makefile (dist): Include generated documentation in
+    distribution.
 
-	* Makefile (doc): Make documentation.
+    * Makefile (doc): Make documentation.
 
-	* irclib.py: Updated documentation.
+    * irclib.py: Updated documentation.
 
-	* irclib.py (is_channel): Included "!" as channel prefix.
+    * irclib.py (is_channel): Included "!" as channel prefix.
 
 2000-10-02  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.2.3.
+    * Released version 0.2.3.
 
-	* irclib.py (ServerConnection.connect): Make socket.connect() work
-	for Python >= 1.6.
+    * irclib.py (ServerConnection.connect): Make socket.connect() work
+    for Python >= 1.6.
 
 2000-09-26  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.2.2.
+    * Released version 0.2.2.
 
-	* irclib.py (ServerConnection.user): Fixed erroneous format
-	string.
+    * irclib.py (ServerConnection.user): Fixed erroneous format
+    string.
 
 2000-09-24  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.2.1.
+    * Released version 0.2.1.
 
-	* irclib.py (ServerConnection.process_data): Bug fix (didn't keep
-	track of nick name).
-	(IRC.process_once): New method.
-	(ServerConnection.process_data): Bug fix.
-	(IRC.disconnect_all): Created.
-	(IRC.exit): Removed.
-	(ServerConnection.exit): Removed.
-	(ServerConnection.connect): Follow RFC closer.
-	(ServerConnection.user): Follow RFC closer.
+    * irclib.py (ServerConnection.process_data): Bug fix (didn't keep
+    track of nick name).
+    (IRC.process_once): New method.
+    (ServerConnection.process_data): Bug fix.
+    (IRC.disconnect_all): Created.
+    (IRC.exit): Removed.
+    (ServerConnection.exit): Removed.
+    (ServerConnection.connect): Follow RFC closer.
+    (ServerConnection.user): Follow RFC closer.
 
-	* ircbot.py: Removed.
+    * ircbot.py: Removed.
 
-	* irccat (on_disconnect): Just sys.exit(0).
+    * irccat (on_disconnect): Just sys.exit(0).
 
-	* servermap (on_disconnect): Just sys.exit(0).
+    * servermap (on_disconnect): Just sys.exit(0).
 
-	* irclib.py: Various documentation and some clean-ups.
+    * irclib.py: Various documentation and some clean-ups.
 
 1999-08-21  Joel Rosdahl  <joel@rosdahl.net>
 
-	* Released version 0.2.0.
+    * Released version 0.2.0.
 
-	* servermap: Updated to work with irclib 0.2.0.
+    * servermap: Updated to work with irclib 0.2.0.
 
-	* irccat: Updated to work with irclib 0.2.0.
+    * irccat: Updated to work with irclib 0.2.0.
 
-	* ircbot.py: Updated to work with irclib 0.2.0.  The bot now
- 	checks every minute that it is connected.  If it's not, it
- 	reconnects.
+    * ircbot.py: Updated to work with irclib 0.2.0.  The bot now
+    checks every minute that it is connected.  If it's not, it
+    reconnects.
 
-	* irclib.py: Changes in how to create a ServerConnection object.
-  	Made the code for handling disconnection hopefully more robust.
-  	Renamed connect() to sconnect().
+    * irclib.py: Changes in how to create a ServerConnection object.
+    Made the code for handling disconnection hopefully more robust.
+    Renamed connect() to sconnect().
 
 1999-06-19  Joel Rosdahl  <joel@rosdahl.net>
 
-	* irclib.py: Released 0.1.0.
+    * irclib.py: Released 0.1.0.
         self.fn_to_add_timeout = fn_to_add_timeout
         self.connections = []
         self.handlers = {}
-        self.delayed_commands = [] # list of tuples in the format (time, function, arguments)
+        self.delayed_commands = [] # list of DelayedCommands
 
         self.add_global_handler("ping", _ping_ponger, -42)
 
 
         See documentation for IRC.__init__.
         """
-        t = time.time()
         while self.delayed_commands:
-            if t >= self.delayed_commands[0][0]:
-                self.delayed_commands[0][1](*self.delayed_commands[0][2])
-                if len(self.delayed_commands[0]) > 3:
-                    self.execute_delayed(self.delayed_commands[0][3]['tick'],
-                                         self.delayed_commands[0][1],
-                                         self.delayed_commands[0][2],
-                                         self.delayed_commands[0][3])
-                del self.delayed_commands[0]
-            else:
+            command = self.delayed_commands[0]
+            if not command.due():
                 break
+            command.function(*command.arguments)
+            if isinstance(command, PeriodicCommand):
+                self._schedule_command(command.next())
+            del self.delayed_commands[0]
 
     def process_once(self, timeout=0):
         """Process data from connections once.
         Arguments:
 
             event -- Event type (a string).
-
             handler -- Callback function.
 
         Returns 1 on success, otherwise 0.
         Arguments:
 
             at -- Execute at this time (standard \"time_t\" time).
-
             function -- Function to call.
-
             arguments -- Arguments to give the function.
         """
-        self.execute_delayed(at-time.time(), function, arguments)
-    def execute_delayed(self, delay, function, arguments=(), persistant=False):
-        """Execute a function after a specified time.
-        Arguments:
+        command = DelayedCommand.at_time(at, function, arguments)
+        self._schedule_command(command)
 
-            delay -- How many seconds to wait.
+    def execute_delayed(self, delay, function, arguments=()):
+        """
+        Execute a function after a specified time.
 
-            function -- Function to call.
-            arguments -- Arguments to give the function.
+        delay -- How many seconds to wait.
+        function -- Function to call.
+        arguments -- Arguments to give the function.
+        """
+        command = DelayedCommand(delay, function, arguments)
+        self._schedule_command(command)
 
-            persistant -- Do not delete the job, keep processing for ever.
+    def execute_every(self, period, function, arguments=()):
         """
-        if persistant:
-            data = (delay+time.time(), function, arguments, {'tick': delay})
-        else:
-            data = (delay+time.time(), function, arguments)
-        bisect.insort(self.delayed_commands, data)
+        Execute a function every 'period' seconds.
+
+        period -- How often to run (always waits this long for first).
+        function -- Function to call.
+        arguments -- Arguments to give the function.
+        """
+        command = PeriodicCommand(period, function, arguments)
+        self._schedule_command(command)
+
+    def _schedule_command(self, command):
+        bisect.insort(self.delayed_commands, command)
         if self.fn_to_add_timeout:
-            self.fn_to_add_timeout(delay)
+            self.fn_to_add_timeout(command.delay)
+
     def dcc(self, dcctype="chat"):
         """Creates and returns a DCCConnection object.
 
         if self.fn_to_remove_socket:
             self.fn_to_remove_socket(connection._get_socket())
 
+class DelayedCommand(object):
+    """
+    A three-tuple describing a command to be executed after delay seconds.
+    """
+    def __init__(self, delay, function, arguments):
+        self.at = time.time() + delay
+        self.delay = delay
+        self.function = function
+        self.arguments = arguments
+
+    def at_time(cls, at, function, arguments):
+        """
+        Construct a DelayedCommand to come due at `at`.
+        """
+        delay = at - time.time()
+        return cls(delay, function, arguments)
+    at_time = classmethod(at_time)
+
+    def due(self):
+        return time.time() >= self.at
+
+class PeriodicCommand(DelayedCommand):
+    """
+    Like a deferred command, but expect this command to run every delay
+    seconds.
+    """
+    def next(self):
+        return PeriodicCommand(self.at+self.delay, self.function,
+            self.arguments)
+
 _rfc_1459_command_regexp = re.compile("^(:(?P<prefix>[^ ]+) +)?(?P<command>[^ ]+)( *(?P<argument> .+))?")
 
 class Connection: