|
@@ -21,7 +21,7 @@ import urllib, urllib2
|
|
|
import warnings
|
|
|
|
|
|
class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
- def __init__(self):
|
|
|
+ def __init__(self, bot = None):
|
|
|
config = SafeConfigParser({'hostname': ''})
|
|
|
|
|
|
config.read('locationbot.ini')
|
|
@@ -56,11 +56,24 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
except NoOptionError, error:
|
|
|
sys.exit(error)
|
|
|
|
|
|
+ ircbot.SingleServerIRCBot.__init__(self, servers, nick, 'Location Bot')
|
|
|
+
|
|
|
+ self.__latitude_timer_lock = threading.Lock()
|
|
|
+ self.__latitude_timer = None
|
|
|
self.__locations_lock = threading.Lock()
|
|
|
- self.__locations = []
|
|
|
- self.__logins = {}
|
|
|
|
|
|
- ircbot.SingleServerIRCBot.__init__(self, servers, nick, 'Location Bot')
|
|
|
+ if bot is None:
|
|
|
+ self.__locations = []
|
|
|
+ self.__logins = {}
|
|
|
+ self.__reloading = False
|
|
|
+ else:
|
|
|
+ irclibobj = self.ircobj.connections[0].irclibobj
|
|
|
+ self.ircobj.connections[0] = bot.ircobj.connections[0]
|
|
|
+ self.ircobj.connections[0].irclibobj = irclibobj
|
|
|
+ self.channels = bot.channels
|
|
|
+ self.__locations = bot.__locations
|
|
|
+ self.__logins = bot.__logins
|
|
|
+ self.__reloading = True
|
|
|
|
|
|
def __admin(self, nickmask):
|
|
|
return _or(lambda admin: irclib.mask_matches(nickmask, admin), self.__admins)
|
|
@@ -74,7 +87,43 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
|
|
|
return _or(lambda channel: channel.has_user(nick), channels)
|
|
|
|
|
|
- def __do_latitude(self):
|
|
|
+ def __help(self, connection, nick, admin, login, arguments):
|
|
|
+ command = arguments.split(None, 1)[0].lstrip('!') if arguments else None
|
|
|
+ commands = {
|
|
|
+ 'help': ('[command]', 'show this help message'),
|
|
|
+ 'login': ('[nick] [secret]', 'log in as nick with secret or using masks'),
|
|
|
+ 'register': ('[nick] secret', 'register as nick with secret'),
|
|
|
+ 'status': ('[nick]', 'show where everybody or a nick is'),
|
|
|
+ }
|
|
|
+
|
|
|
+ if login:
|
|
|
+ commands.update({
|
|
|
+ 'latitude': ('[id]', 'shortcut for !set latitude [id]'),
|
|
|
+ 'logout': ('', 'log out as nick'),
|
|
|
+ 'set': ('[key [value]]', 'display or set variables'),
|
|
|
+ 'unset': ('key', 'unset a variable'),
|
|
|
+ })
|
|
|
+
|
|
|
+ if admin:
|
|
|
+ commands.update({
|
|
|
+ 'reload': ('', 'reload with more up to date code'),
|
|
|
+ 'restart': ('', 'quit and join running more up to date code'),
|
|
|
+ 'say': ('nick|channel message', 'say message to nick or channel'),
|
|
|
+ 'who': ('', 'show who is logged in'),
|
|
|
+ })
|
|
|
+
|
|
|
+ connection.privmsg(nick, 'Command Arguments Description')
|
|
|
+
|
|
|
+ def help(command, arguments, description):
|
|
|
+ connection.privmsg(nick, '!%-10s %-23s %s' % (command, arguments, description))
|
|
|
+
|
|
|
+ if command in commands:
|
|
|
+ help(command, *commands[command])
|
|
|
+ else:
|
|
|
+ for command, (arguments, description) in sorted(commands.iteritems()):
|
|
|
+ help(command, arguments, description)
|
|
|
+
|
|
|
+ def __latitude(self):
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
try:
|
|
@@ -125,44 +174,10 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
for channel in frozenset(channels).intersection(self.__channels):
|
|
|
self.__locations.append((nick, channel, locations[latitude]))
|
|
|
|
|
|
- self.__latitude = threading.Timer((self.__latitude_next - datetime.utcnow()).seconds, self.__do_latitude)
|
|
|
-
|
|
|
- self.__latitude.start()
|
|
|
-
|
|
|
- def __help(self, connection, nick, admin, login, arguments):
|
|
|
- command = arguments.split(None, 1)[0].lstrip('!') if arguments else None
|
|
|
- commands = {
|
|
|
- 'help': ('[command]', 'show this help message'),
|
|
|
- 'login': ('[nick] [secret]', 'log in as nick with secret or using masks'),
|
|
|
- 'register': ('[nick] secret', 'register as nick with secret'),
|
|
|
- 'status': ('[nick]', 'show where everybody or a nick is'),
|
|
|
- }
|
|
|
-
|
|
|
- if login:
|
|
|
- commands.update({
|
|
|
- 'latitude': ('[id]', 'shortcut for !set latitude [id]'),
|
|
|
- 'logout': ('', 'log out as nick'),
|
|
|
- 'set': ('[key [value]]', 'display or set variables'),
|
|
|
- 'unset': ('key', 'unset a variable'),
|
|
|
- })
|
|
|
-
|
|
|
- if admin:
|
|
|
- commands.update({
|
|
|
- 'restart': ('', 'quit and join running more up to date code'),
|
|
|
- 'say': ('nick|channel message', 'say message to nick or channel'),
|
|
|
- 'who': ('', 'show who is logged in'),
|
|
|
- })
|
|
|
+ with self.__latitude_timer_lock:
|
|
|
+ self.__latitude_timer = threading.Timer((self.__latitude_next - datetime.utcnow()).seconds, self.__latitude)
|
|
|
|
|
|
- connection.privmsg(nick, 'Command Arguments Description')
|
|
|
-
|
|
|
- def help(command, arguments, description):
|
|
|
- connection.privmsg(nick, '!%-10s %-22s %s' % (command, arguments, description))
|
|
|
-
|
|
|
- if command in commands:
|
|
|
- help(command, *commands[command])
|
|
|
- else:
|
|
|
- for command, (arguments, description) in sorted(commands.iteritems()):
|
|
|
- help(command, arguments, description)
|
|
|
+ self.__latitude_timer.start()
|
|
|
|
|
|
def __login(self, connection, nickmask, nick, arguments = ''):
|
|
|
login = nick
|
|
@@ -217,6 +232,11 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
def __logout(self, connection, nick):
|
|
|
connection.privmsg(nick, 'logged out as "%s"' % self.__logins.pop(nick)[0])
|
|
|
|
|
|
+ def __reload(self, connection, nick):
|
|
|
+ self.__reloading = True
|
|
|
+
|
|
|
+ connection.privmsg(nick, 'reloading')
|
|
|
+
|
|
|
def __restart(self, connection):
|
|
|
connection.disconnect('Restarting')
|
|
|
os.execvp(sys.argv[0], sys.argv)
|
|
@@ -225,7 +245,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
try:
|
|
|
nick_channel, message = arguments.split(None, 1)
|
|
|
except ValueError:
|
|
|
- self.__help(connection, nick, True, False, 'say')
|
|
|
+ return self.__help(connection, nick, True, False, 'say')
|
|
|
|
|
|
if irclib.is_channel(nick_channel):
|
|
|
if nick_channel not in self.channels:
|
|
@@ -313,6 +333,8 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
self.__login(connection, nickmask, nick, arguments)
|
|
|
elif login and command == 'logout':
|
|
|
self.__logout(connection, nick)
|
|
|
+ elif admin and command == 'reload':
|
|
|
+ self.__reload(connection, nick)
|
|
|
elif admin and command == 'restart':
|
|
|
self.__restart(connection)
|
|
|
elif admin and command == 'say':
|
|
@@ -332,15 +354,17 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
connection.join(channel)
|
|
|
|
|
|
def start(self):
|
|
|
- self.__latitude = threading.Thread(None, self.__do_latitude)
|
|
|
- self.__latitude.daemon = True
|
|
|
+ self.__latitude_thread = threading.Thread(None, self.__latitude)
|
|
|
+ self.__latitude_thread.daemon = True
|
|
|
|
|
|
- self.__latitude.start()
|
|
|
- self._connect()
|
|
|
+ self.__latitude_thread.start()
|
|
|
|
|
|
- while True:
|
|
|
- self.ircobj.process_once(0.2)
|
|
|
+ if not self.__reloading:
|
|
|
+ self._connect()
|
|
|
+ else:
|
|
|
+ self.__reloading = False
|
|
|
|
|
|
+ while not self.__reloading:
|
|
|
if self.__locations_lock.acquire(False):
|
|
|
if self.__locations and sorted(self.__channels) == sorted(self.channels.keys()):
|
|
|
for nick, channel, location in self.__locations:
|
|
@@ -350,13 +374,27 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
|
|
|
self.__locations_lock.release()
|
|
|
|
|
|
+ self.ircobj.process_once(0.2)
|
|
|
+
|
|
|
+ self.__latitude_thread.join()
|
|
|
+
|
|
|
+ with self.__latitude_timer_lock:
|
|
|
+ if self.__latitude_timer is not None:
|
|
|
+ self.__latitude_timer.cancel()
|
|
|
+ self.__latitude_timer.join()
|
|
|
+
|
|
|
def _or(function, values):
|
|
|
return reduce(lambda a, b: a or b, map(function, values) if values else [False])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
- locationbot = LocationBot()
|
|
|
+ import locationbot
|
|
|
+
|
|
|
+ bot = None
|
|
|
|
|
|
try:
|
|
|
- locationbot.start()
|
|
|
+ while True:
|
|
|
+ bot = reload(locationbot).LocationBot(bot)
|
|
|
+
|
|
|
+ bot.start()
|
|
|
except KeyboardInterrupt:
|
|
|
- locationbot.connection.disconnect('Oh no!')
|
|
|
+ bot.connection.disconnect('Oh no!')
|