|
@@ -27,19 +27,19 @@ except ImportError:
|
|
|
|
|
|
class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
def __init__(self, bot = None):
|
|
|
- config = SafeConfigParser({'hostname': ''})
|
|
|
+ self.__config = SafeConfigParser()
|
|
|
|
|
|
- config.read('locationbot.ini')
|
|
|
+ self.__config.read('locationbot.ini')
|
|
|
|
|
|
try:
|
|
|
- nick = config.sections()[0]
|
|
|
+ nick = self.__config.sections()[0]
|
|
|
except IndexError:
|
|
|
sys.exit('No nick configured')
|
|
|
|
|
|
servers = []
|
|
|
|
|
|
try:
|
|
|
- for server in config.get(nick, 'servers').split():
|
|
|
+ for server in self.__config.get(nick, 'servers').split():
|
|
|
server = server.split(':', 2)
|
|
|
|
|
|
if len(server) == 1:
|
|
@@ -54,13 +54,17 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
else:
|
|
|
servers.append((host, port, ssl))
|
|
|
|
|
|
- self.__admins = config.get(nick, 'admins').split()
|
|
|
- self.__channels = set(config.get(nick, 'channels').split())
|
|
|
- self.__dsn = config.get(nick, 'dsn')
|
|
|
- self.__hostname = config.get(nick, 'hostname')
|
|
|
+ self.__admins = self.__config.get(nick, 'admins').split()
|
|
|
+ self.__channels = set(self.__config.get(nick, 'channels').split())
|
|
|
+ self.__dsn = self.__config.get(nick, 'dsn')
|
|
|
except NoOptionError, error:
|
|
|
sys.exit(error)
|
|
|
|
|
|
+ try:
|
|
|
+ self.__hostname = self.__config.get(nick, 'hostname')
|
|
|
+ except NoOptionError:
|
|
|
+ self.__hostname = ''
|
|
|
+
|
|
|
ircbot.SingleServerIRCBot.__init__(self, servers, nick, 'Location Bot')
|
|
|
|
|
|
self.__latitude_timer_lock = threading.Lock()
|
|
@@ -70,6 +74,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
if bot is None:
|
|
|
self.__locations = []
|
|
|
self.__logins = {}
|
|
|
+ self.__nick = None
|
|
|
self.__reloading = False
|
|
|
else:
|
|
|
irclibobj = self.ircobj.connections[0].irclibobj
|
|
@@ -79,8 +84,10 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
self.connection = bot.connection
|
|
|
self.__locations = bot.__locations
|
|
|
self.__logins = bot.__logins
|
|
|
+ self.__nick = bot.__nick
|
|
|
self.__reloading = True
|
|
|
|
|
|
+ self.__quiting = False
|
|
|
self.__variables = frozenset(['nick', 'secret', 'masks', 'channels', 'timezone', 'location', 'latitude'])
|
|
|
self.__lists = self.__variables.intersection(['masks', 'channels'])
|
|
|
self.__unsetable = self.__variables.difference(['nick', 'secret'])
|
|
@@ -123,6 +130,9 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
|
|
|
if admin:
|
|
|
commands.update({
|
|
|
+ 'join': ('channel', 'join a channel'),
|
|
|
+ 'part': ('channel [message]', 'part from a channel'),
|
|
|
+ 'quit': ('[message]', 'quit and do not come back'),
|
|
|
'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'),
|
|
@@ -140,6 +150,18 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
for command, (arguments, description) in sorted(commands.iteritems()):
|
|
|
help(command, arguments, description)
|
|
|
|
|
|
+ def __join(self, connection, nick, arguments):
|
|
|
+ try:
|
|
|
+ channel = arguments.split(None, 1)[0]
|
|
|
+ except IndexError:
|
|
|
+ return self.__help(connection, nick, True, False, 'join')
|
|
|
+
|
|
|
+ connection.join(channel)
|
|
|
+ self.__channels.add(channel)
|
|
|
+ self.__config.set(self._nickname, 'channels', ' '.join(self.__channels))
|
|
|
+ self.__write()
|
|
|
+ connection.privmsg(nick, 'successfully joined channel ("%s")' % channel)
|
|
|
+
|
|
|
def __latitude(self):
|
|
|
now = datetime.utcnow()
|
|
|
|
|
@@ -255,6 +277,33 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
def __logout(self, connection, nick):
|
|
|
connection.privmsg(nick, 'logged out as "%s"' % self.__logins.pop(nick)[0])
|
|
|
|
|
|
+ def __part(self, connection, nick, arguments):
|
|
|
+ arguments = arguments.split(None, 1)
|
|
|
+
|
|
|
+ if len(arguments) == 2:
|
|
|
+ channel, message = arguments
|
|
|
+ message = ':' + message
|
|
|
+ elif len(arguments) == 1:
|
|
|
+ channel = arguments[0]
|
|
|
+ message = ''
|
|
|
+ else:
|
|
|
+ return self.__help(connection, nick, True, False, 'part')
|
|
|
+
|
|
|
+ if channel in self.__channels:
|
|
|
+ connection.part(channel, message)
|
|
|
+ self.__channels.remove(channel)
|
|
|
+ self.__config.set(self._nickname, 'channels', ' '.join(self.__channels))
|
|
|
+ self.__write()
|
|
|
+ connection.privmsg(nick, 'successfully parted channel ("%s")' % channel)
|
|
|
+ else:
|
|
|
+ connection.privmsg(nick, 'not in channel ("%s")' % channel)
|
|
|
+
|
|
|
+ def __quit(self, connection, nick):
|
|
|
+ self.__reloading = True
|
|
|
+ self.__quiting = True
|
|
|
+
|
|
|
+ connection.privmsg(nick, 'quiting')
|
|
|
+
|
|
|
def __register(self, connection, nick, arguments):
|
|
|
arguments = arguments.split(None, 1)
|
|
|
|
|
@@ -277,6 +326,7 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
connection.privmsg(nick, 'nick ("%s") sucessfully registered' % login)
|
|
|
|
|
|
def __reload(self, connection, nick):
|
|
|
+ self.__nick = nick
|
|
|
self.__reloading = True
|
|
|
|
|
|
connection.privmsg(nick, 'reloading')
|
|
@@ -434,6 +484,10 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
else:
|
|
|
connection.privmsg(nick, 'nobody logged in')
|
|
|
|
|
|
+ def __write(self):
|
|
|
+ with open('locationbot.ini', 'w') as config:
|
|
|
+ self.__config.write(config)
|
|
|
+
|
|
|
def _connect(self):
|
|
|
if len(self.server_list[0]) != 2:
|
|
|
ssl = self.server_list[0][2]
|
|
@@ -452,6 +506,14 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
except irclib.ServerConnectionError:
|
|
|
pass
|
|
|
|
|
|
+ def disconnect(self, message = 'oh no!'):
|
|
|
+ ircbot.SingleServerIRCBot.disconnect(self, message)
|
|
|
+
|
|
|
+ def error(self, error):
|
|
|
+ print error
|
|
|
+
|
|
|
+ self.connection.privmsg(self.__nick, 'an error occured')
|
|
|
+
|
|
|
def get_version(self):
|
|
|
return 'locationbot ' + sys.platform
|
|
|
|
|
@@ -511,6 +573,12 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
self.__set(connection, nickmask, nick, login, arguments)
|
|
|
elif login and command == 'unset':
|
|
|
self.__unset(connection, nick, login, arguments)
|
|
|
+ elif admin and command == 'join':
|
|
|
+ self.__join(connection, nick, arguments)
|
|
|
+ elif admin and command == 'part':
|
|
|
+ self.__part(connection, nick, arguments)
|
|
|
+ elif admin and command == 'quit':
|
|
|
+ self.__quit(connection, nick)
|
|
|
elif admin and command == 'reload':
|
|
|
self.__reload(connection, nick)
|
|
|
elif admin and command == 'restart':
|
|
@@ -544,8 +612,11 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
else:
|
|
|
self.__reloading = False
|
|
|
|
|
|
- for channel in self.__channels.difference(self.channels.keys()):
|
|
|
- self.connection.join(channel)
|
|
|
+ for channel in self.__channels.symmetric_difference(self.channels.keys()):
|
|
|
+ if channel in self.__channels:
|
|
|
+ self.connection.join(channel)
|
|
|
+ else:
|
|
|
+ self.connection.part(channel)
|
|
|
|
|
|
while not self.__reloading:
|
|
|
if self.__locations_lock.acquire(False):
|
|
@@ -566,18 +637,41 @@ class LocationBot(ircbot.SingleServerIRCBot):
|
|
|
self.__latitude_timer.cancel()
|
|
|
self.__latitude_timer.join()
|
|
|
|
|
|
+ return not self.__quiting
|
|
|
+
|
|
|
+ def success(self):
|
|
|
+ self.connection.privmsg(self.__nick, 'successfully reloaded')
|
|
|
+
|
|
|
def _or(function, values):
|
|
|
return reduce(lambda a, b: a or b, map(function, values) if values else [False])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
+ pid = os.fork()
|
|
|
+
|
|
|
+ if pid != 0:
|
|
|
+ with open('locationbot.pid', 'w') as _file:
|
|
|
+ _file.write('%u\n' % pid)
|
|
|
+
|
|
|
+ sys.exit(0)
|
|
|
+
|
|
|
+ sys.stdin = open('/dev/null')
|
|
|
+ sys.stdout = open('locationbot.log', 'a', 1)
|
|
|
+ sys.stderr = sys.stdout
|
|
|
+
|
|
|
import locationbot
|
|
|
|
|
|
- bot = None
|
|
|
+ bot = locationbot.LocationBot()
|
|
|
|
|
|
try:
|
|
|
- while True:
|
|
|
- bot = reload(locationbot).LocationBot(bot)
|
|
|
-
|
|
|
- bot.start()
|
|
|
+ while bot.start():
|
|
|
+ try:
|
|
|
+ bot = reload(locationbot).LocationBot(bot)
|
|
|
+ except (ImportError, SyntaxError), error:
|
|
|
+ bot.error(error)
|
|
|
+ else:
|
|
|
+ bot.success()
|
|
|
except KeyboardInterrupt:
|
|
|
- bot.connection.disconnect('oh no!')
|
|
|
+ pass
|
|
|
+
|
|
|
+ bot.disconnect()
|
|
|
+ os.unlink('locationbot.pid')
|