diff --git a/.gitignore b/.gitignore index aea2ca1..0c5b9e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ config.ini config.ini.md -logs/FA_bot.log +log .ropeproject .venv/ .idea/ diff --git a/bot/FAbot.py b/bot/FAbot.py index 88c1367..5e01475 100644 --- a/bot/FAbot.py +++ b/bot/FAbot.py @@ -10,17 +10,7 @@ import json import subprocess from urllib import quote - - -def command(cmd): - """When you write a new command, add this decorator to it, so it gets registered""" - def outerwrap(function): - def innerwrap(*args): - args[0].commands[cmd] = function - function(*args) - return innerwrap - return outerwrap - +import commands class FAbot(object): def __init__(self, configfilename): @@ -31,8 +21,7 @@ def __init__(self, configfilename): self.main_watcher = None self.game_servers = {} self.commandregex = re.compile("(?s)^!(?P\w+)\s*(?P.*)?") - self.commands = {} - self.botMethods = ['start', 'stop', 'server_address'] # Bob: now I hate it even more... + self.commands = commands.commands self.FAMDB_API_key = None self.FAMDB_app_id = None self.TS3_address = None @@ -44,12 +33,6 @@ def __init__(self, configfilename): format="%(asctime)-15s %(message)s") logging.info("FAbot starting up") logging.info("Registering commands: ") - for method in dir(self): - if callable(getattr(self, method)): - if method[:2] != '__' and method not in self.botMethods: - call = getattr(self, method) - call(None, None) - logging.info(method) logging.info("Full command list:") logging.info(self.commands) @@ -126,47 +109,6 @@ def start(self): logging.info("Entering main message event loop") self.discordClient.run() - def stop(self): - self.discordClient.logout() - if self.event_manager.timer is not None: # Todo: move that one to event manager? Maybe not needed. - self.event_manager.timer.cancel() - self.main_watcher.stop() - - @command('help') - def help_cmd(self, message, args): - """!help : display this text""" - # We don't want to spam chat because someone wanted - # to sing The Beatles in Spanish, do we? - if not args: - help_texts = ["Available commands:"] - for item in self.commands.values(): - if item.func_doc: - help_texts.append(item.func_doc) - msg = '\n'.join(help_texts) - return msg - - @command('github') - def github(self, message, args): - """!github : report the URL of the FA_bot github project""" - if message is None: - return None - return "https://github.com/darkChozo/folkbot" - - @command('status') - def status(self, message, args): - """!status : reports the current state of the game on the Arma server""" - if message is None: - return None - gametype, gamestate = self.game_servers['arma'].state() - return gamestate - - @command('nextevent') - def nextevent(self, message, args): - """!nextevent : reports the next scheduled Folk ARPS session""" - if message is None: - return None - return self.event_manager.next_event_message() - def server_address(self, server_name): if server_name in self.game_servers: server = self.game_servers[server_name] @@ -177,232 +119,7 @@ def server_address(self, server_name): steam_url = "{}{}".format(steam_url, server.password) return "{}{}\nOr just use this link:\n<{}>".format(address_msg, password_msg, steam_url) - @command('armaserver') - def armaserver(self, message, args): - """!armaserver : report the hostname and port of the Folk ARPS Arma server""" - if message is None: - return None - return self.server_address("arma") - - @command('testserver') - def testserver(self, message, args): - """!testserver : report the hostname and port of the Folk ARPS mission testing Arma server""" - if message is None: - return None - return self.server_address("arma_test") - - @command('insurgencyserver') - def insurgencyserver(self, message, args): - """!insurgencyserver : report the hostname and port of the Folk ARPS Insurgency (Standalone) server""" - if message is None: - return None - return self.server_address("insurgency") - - @command('tsserver') - def tsserver(self, message, args): - """!tsserver : report the hostname and port of the Folk ARPS teamspeak server""" - if message is None: - return None - if not self.TS3_address or not self.TS3_port: - return "I don't know about any TS3 Server." - - # nickname = "&nickname={}".format(quote(message.author.name)) - nickname = "" - - ts3_link = "ts3server://{}/?port={}{}".format(self.TS3_address, self.TS3_port, nickname) - password_text = "" - if self.TS3_password is not None: - ts3_link = "{}&password={}".format(ts3_link, self.TS3_password) - password_text = " Password: **{}**".format(self.TS3_password) - - msg = "Our Teamspeak server:\nAddress: **{}:{}**{}\nOr you can just click this link:\n<{}>".format( - self.TS3_address, self.TS3_port, password_text, ts3_link) - return msg - - @command('ping') - def ping(self, message, args): - """!ping : report the ping time from FA_bot to the Arma server""" - if message is None: - return None - ping = self.game_servers['arma'].ping() - return "{} milliseconds".format(str(ping)) - - @command('info') - def info(self, message, args): - """!info : report some basic information on the Arma server""" - if message is None: - return None - info = self.game_servers['arma'].info() - msg = "Arma 3 v{version} - {server_name} - {game} - {player_count}/{max_players} humans, {bot_count} AI on {map}" - return msg.format(**info) - - @command('players') - def players(self, message, args): - """!players (insurgency) : show a list of players on the Arma (Insurgency) server""" - if message is None: - return None - if args == "insurgency": - players = self.game_servers['insurgency'].players() - else: - players = self.game_servers['arma'].players() - player_string = "Total players: {player_count}\n".format(**players) - for player in sorted(players["players"], - key=lambda p: p["score"], - reverse=True): - player_string += "{score} {name} (on for {duration} seconds)\n".format(**player) - return player_string - - @command('rules') - def rules(self, message, args): - """!rules : report on the cvars in force on the insurgency server""" - if message is None: - return None - # rules doesn't work for the arma server for some reason - rules = self.game_servers['insurgency'].rules() - msg = rules["rule_count"] + " rules:\n" - msg += "\n".join(rules["rules"]) - return msg - - @command('insurgency') - def insurgency(self, message, args): - """!insurgency : report on the current state of the Folk ARPS Insurgency server""" - if message is None: - return None - msg = "Insurgency v{version} - {server_name} - {game} - {player_count}/{max_players} humans, {bot_count} AI on {map}" - info = self.game_servers['insurgency'].info() - return msg.format(**info) - - @command('f3') - def f3(self, message, args): - """!f3 : report the URL for the latest F3 release""" - if message is None: - return None - return "Latest F3 downloads: http://ferstaberinde.com/f3/en//index.php?title=Downloads" - - @command('biki') - def biki(self, message, args): - """!biki : search the bohemia interactive wiki for """ - if message is None: - return None - if args is not None: - return "https://community.bistudio.com/wiki?search={}&title=Special%3ASearch&go=Go".format("+".join(args.split())) - - @command('f3wiki') - def f3wiki(self, message, args): - """!f3wiki : search the f3 wiki for """ - if message is None: - return None - if args is not None: - return "http://ferstaberinde.com/f3/en//index.php?search={}&title=Special%3ASearch&go=Go".format("+".join(args.split())) - - @command('session') - def session(self, message, args): - """!session : show whether or not a Folk ARPS session is running - !session start : tell the bot a Folk ARPS session is starting - !session stop : tell the bot a Folk ARPS session is ending""" - if message is None: - return None - if args == "start": - self.main_watcher.start() - elif args == "stop": - self.main_watcher.stop() - else: - if self.main_watcher.session.isSet(): - return "Folk ARPS session underway; FA_bot will announce when we're slotting" - else: - return "No Folk ARPS session running at the moment. Check when the next event is on with !nextevent" - - @command('addons') - def addons(self, message, args): - """!addons : display link to FA optional addons""" - return "http://www.folkarps.com/forum/viewtopic.php?f=43&t=1382" - - @command('test') - def test(self, message, args): - # """!test : under development""" - if message is None: - return None - logging.info('test()') - msg = self.game_servers['arma'].raw_info() + '\n\n' + self.game_servers['insurgency'].raw_info() - return msg - - @command('mission') - def mission(self, message, args): - """!mission : describe or the mission currently being played on the server""" - if message is None: - return None - logging.info('mission(%(args)s)' % {'args': args}) - - servermapname = None - - if (args is None) or (not args.strip()): - logging.info('No mission name specified, interrogating arma server') - servermapname = self.game_servers['arma'].info()['game'] - regex = re.compile("fa3_[c|a]\w.[0-9]*_(?P\w+)[_v[0-9]*]?") - logging.info('Server map name: %s' % servermapname) - result = regex.search(servermapname) - if result.groups is None: - logging.info("Didn't recognise the server map name") - return "Need a mission name (didn't recognise the one on the server right now)" - tokenlist = result.group('mapname').split('_') - args = max(tokenlist, key=len) - logging.info('Map name tokens : %s',tokenlist) - logging.info('Selected search token : %s',args) - - header = {'X-Parse-Application-Id' : self.FAMDB_app_id, - 'X-Parse-REST-API-Key' : self.FAMDB_API_key, - 'Content-Type' : 'application/json'} - - query = {'where': json.dumps({'missionName' : { '$regex' : '\Q%s\E' % args, '$options' : 'i'}})} - logging.info('Query: %s' % query) - - response = requests.get('https://api.parse.com/1/classes/Missions', headers=header, params=query) - logging.info('URL: %s' % response.url) - - result = response.json() - bestguess = result['results'][0] - logging.info('Response: %s ' % bestguess) - - data = {'name': bestguess[u'missionName'], - 'type': bestguess[u'missionType'], - 'map':bestguess[u'missionMap'], - 'author':bestguess[u'missionAuthor'], - 'description':bestguess[u'missionDesc']} - - if not servermapname: - msg = "**Mission name: {name}**\n" - else: - msg = "**Mission name: {name}** *({servername})*\n" - data['servername']=servermapname - - msg = ' '.join( ( msg, "**Mission type:** {type}\n" \ - "**Location:** {map}\n" \ - "**Author:** {author}\n" \ - "**Description:** {description}\n" ) ) - - logging.info(msg.format(**data)) - return msg.format(**data) - - @command('update') - def update(self, message, args): - """!update : tell the bot to get its latest release from github and restart. Permission required.""" - if message is None: - return None - - try: - git_result = subprocess.check_output('git pull', shell=True) - logging.info(git_result) - if (git_result == 'Already up-to-date.'): - return git_result - - msg = ' '.join(("**Restarting for update:**\n```", git_result, "```")) - self.discordClient.announce(msg) - open('update','w').close() - self.stop() - - except subprocess.CalledProcessError as err: - logging.info(err) - logging.info(' '.join(('shell: ', err.cmd))) - logging.info(' '.join(('output:', err.output))) - msg = ' '.join(('**Update failed:** ',str(err))) - return msg + def stop(self): + self.discordClient.logout() + self.event_manager.stop() + self.main_watcher.stop() diff --git a/bot/commands/__init__.py b/bot/commands/__init__.py new file mode 100644 index 0000000..9c0e6ed --- /dev/null +++ b/bot/commands/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from .command import commands +import commands_basic +import commands_fa \ No newline at end of file diff --git a/bot/commands/command.py b/bot/commands/command.py new file mode 100644 index 0000000..8332c02 --- /dev/null +++ b/bot/commands/command.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +import re + +commands = {} + + +def command(cmd): + """ + When you write a new command, add this decorator to it, so it's gets registered + """ + + def wrapper(wrapped): + commands[cmd] = wrapped + + return wrapped + + return wrapper \ No newline at end of file diff --git a/bot/commands/commands_basic.py b/bot/commands/commands_basic.py new file mode 100644 index 0000000..5384167 --- /dev/null +++ b/bot/commands/commands_basic.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from .command import command, commands +import logging + +@command('help') +def help_cmd(bot, message, args): + """!help : display this text""" + # We don't want to spam chat because someone wanted + # to sing The Beatles in Spanish, do we? + if not args: + help_texts = ["Available commands:"] + for item in bot.commands.values(): + if item.func_doc: + help_texts.append(item.func_doc) + msg = '\n'.join(help_texts) + return msg + +@command('github') +def github(bot, message, args): + """!github : report the URL of the FA_bot github project""" + if message is None: + return None + return "https://github.com/darkChozo/folkbot" \ No newline at end of file diff --git a/bot/commands/commands_fa.py b/bot/commands/commands_fa.py new file mode 100644 index 0000000..e82c18c --- /dev/null +++ b/bot/commands/commands_fa.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +from .command import command, commands +import logging +import json +import re +import requests + +@command('status') +def status(bot, message, args): + """!status : reports the current state of the game on the Arma server""" + if message is None: + return None + gametype, gamestate = bot.game_servers['arma'].state() + return gamestate + +@command('nextevent') +def nextevent(bot, message, args): + """!nextevent : reports the next scheduled Folk ARPS session""" + if message is None: + return None + return bot.event_manager.next_event_message() + +@command('armaserver') +def armaserver(bot, message, args): + """!armaserver : report the hostname and port of the Folk ARPS Arma server""" + if message is None: + return None + return bot.server_address("arma") + +@command('testserver') +def testserver(bot, message, args): + """!testserver : report the hostname and port of the Folk ARPS mission testing Arma server""" + if message is None: + return None + return bot.server_address("arma_test") + +@command('insurgencyserver') +def insurgencyserver(bot, message, args): + """!insurgencyserver : report the hostname and port of the Folk ARPS Insurgency (Standalone) server""" + if message is None: + return None + return bot.server_address("insurgency") + +@command('tsserver') +def tsserver(bot, message, args): + """!tsserver : report the hostname and port of the Folk ARPS teamspeak server""" + if message is None: + return None + if not bot.TS3_address or not bot.TS3_port: + return "I don't know about any TS3 Server." + + # nickname = "&nickname={}".format(quote(message.author.name)) + nickname = "" + + ts3_link = "ts3server://{}/?port={}{}".format(bot.TS3_address, bot.TS3_port, nickname) + password_text = "" + if bot.TS3_password is not None: + ts3_link = "{}&password={}".format(ts3_link, bot.TS3_password) + password_text = " Password: **{}**".format(bot.TS3_password) + + msg = "Our Teamspeak server:\nAddress: **{}:{}**{}\nOr you can just click this link:\n<{}>".format( + bot.TS3_address, bot.TS3_port, password_text, ts3_link) + return msg + +@command('ping') +def ping(bot, message, args): + """!ping : report the ping time from FA_bot to the Arma server""" + if message is None: + return None + ping = bot.game_servers['arma'].ping() + return "{} milliseconds".format(str(ping)) + +@command('info') +def info(bot, message, args): + """!info : report some basic information on the Arma server""" + if message is None: + return None + info = bot.game_servers['arma'].info() + msg = "Arma 3 v{version} - {server_name} - {game} - {player_count}/{max_players} humans, {bot_count} AI on {map}" + return msg.format(**info) + +@command('players') +def players(bot, message, args): + """!players (insurgency) : show a list of players on the Arma (Insurgency) server""" + if message is None: + return None + if args == "insurgency": + players = bot.game_servers['insurgency'].players() + else: + players = bot.game_servers['arma'].players() + player_string = "Total players: {player_count}\n".format(**players) + for player in sorted(players["players"], + key=lambda p: p["score"], + reverse=True): + player_string += "{score} {name} (on for {duration} seconds)\n".format(**player) + return player_string + +@command('rules') +def rules(bot, message, args): + """!rules : report on the cvars in force on the insurgency server""" + if message is None: + return None + # rules doesn't work for the arma server for some reason + rules = bot.game_servers['insurgency'].rules() + msg = rules["rule_count"] + " rules:\n" + msg += "\n".join(rules["rules"]) + return msg + +@command('insurgency') +def insurgency(bot, message, args): + """!insurgency : report on the current state of the Folk ARPS Insurgency server""" + if message is None: + return None + msg = "Insurgency v{version} - {server_name} - {game} - {player_count}/{max_players} humans, {bot_count} AI on {map}" + info = bot.game_servers['insurgency'].info() + return msg.format(**info) + +@command('f3') +def f3(bot, message, args): + """!f3 : report the URL for the latest F3 release""" + if message is None: + return None + return "Latest F3 downloads: http://ferstaberinde.com/f3/en//index.php?title=Downloads" + +@command('biki') +def biki(bot, message, args): + """!biki : search the bohemia interactive wiki for """ + if message is None: + return None + if args is not None: + return "https://community.bistudio.com/wiki?search={}&title=Special%3ASearch&go=Go".format("+".join(args.split())) + +@command('f3wiki') +def f3wiki(bot, message, args): + """!f3wiki : search the f3 wiki for """ + if message is None: + return None + if args is not None: + return "http://ferstaberinde.com/f3/en//index.php?search={}&title=Special%3ASearch&go=Go".format("+".join(args.split())) + +@command('session') +def session(bot, message, args): + """!session : show whether or not a Folk ARPS session is running + !session start : tell the bot a Folk ARPS session is starting + !session stop : tell the bot a Folk ARPS session is ending""" + if message is None: + return None + if args == "start": + bot.main_watcher.start() + elif args == "stop": + bot.main_watcher.stop() + else: + if bot.main_watcher.session.isSet(): + return "Folk ARPS session underway; FA_bot will announce when we're slotting" + else: + return "No Folk ARPS session running at the moment. Check when the next event is on with !nextevent" + +@command('addons') +def addons(bot, message, args): + """!addons : display link to FA optional addons""" + return "http://www.folkarps.com/forum/viewtopic.php?f=43&t=1382" + +@command('test') +def test(bot, message, args): + # """!test : under development""" + if message is None: + return None + logging.info('test()') + msg = bot.game_servers['arma'].raw_info() + '\n\n' + bot.game_servers['insurgency'].raw_info() + return msg + +@command('mission') +def mission(bot, message, args): + """!mission : describe or the mission currently being played on the server""" + if message is None: + return None + logging.info('mission(%(args)s)' % {'args': args}) + + servermapname = None + + if (args is None) or (not args.strip()): + logging.info('No mission name specified, interrogating arma server') + servermapname = bot.game_servers['arma'].info()['game'] + regex = re.compile("fa3_[c|a]\w.[0-9]*_(?P\w+)[_v[0-9]*]?") + logging.info('Server map name: %s' % servermapname) + result = regex.search(servermapname) + if result.groups is None: + logging.info("Didn't recognise the server map name") + return "Need a mission name (didn't recognise the one on the server right now)" + tokenlist = result.group('mapname').split('_') + args = max(tokenlist, key=len) + logging.info('Map name tokens : %s',tokenlist) + logging.info('Selected search token : %s',args) + + header = {'X-Parse-Application-Id' : bot.FAMDB_app_id, + 'X-Parse-REST-API-Key' : bot.FAMDB_API_key, + 'Content-Type' : 'application/json'} + + query = {'where': json.dumps({'missionName' : { '$regex' : '\Q%s\E' % args, '$options' : 'i'}})} + logging.info('Query: %s' % query) + + response = requests.get('https://api.parse.com/1/classes/Missions', headers=header, params=query) + logging.info('URL: %s' % response.url) + + result = response.json() + bestguess = result['results'][0] + logging.info('Response: %s ' % bestguess) + + data = {'name': bestguess[u'missionName'], + 'type': bestguess[u'missionType'], + 'map':bestguess[u'missionMap'], + 'author':bestguess[u'missionAuthor'], + 'description':bestguess[u'missionDesc']} + + if not servermapname: + msg = "**Mission name: {name}**\n" + else: + msg = "**Mission name: {name}** *({servername})*\n" + data['servername']=servermapname + + msg = ' '.join( ( msg, "**Mission type:** {type}\n" \ + "**Location:** {map}\n" \ + "**Author:** {author}\n" \ + "**Description:** {description}\n" ) ) + + logging.info(msg.format(**data)) + return msg.format(**data) + +@command('update') +def update(bot, message, args): + """!update : tell the bot to get its latest release from github and restart. Permission required.""" + if message is None: + return None + + try: + git_result = subprocess.check_output('git pull', shell=True) + logging.info(git_result) + if (git_result == 'Already up-to-date.'): + return git_result + + msg = ' '.join(("**Restarting for update:**\n```", git_result, "```")) + bot.discordClient.announce(msg) + open('update','w').close() + bot.stop() + + except subprocess.CalledProcessError as err: + logging.info(err) + logging.info(' '.join(('shell: ', err.cmd))) + logging.info(' '.join(('output:', err.output))) + msg = ' '.join(('**Update failed:** ',str(err))) + return msg \ No newline at end of file diff --git a/bot/event_manager.py b/bot/event_manager.py index d298fc8..c9d1990 100644 --- a/bot/event_manager.py +++ b/bot/event_manager.py @@ -2,6 +2,7 @@ import datetime from pytz import utc, timezone import threading +import logging class EventManager(object): @@ -22,6 +23,10 @@ def __init__(self): self.timer = None self.announcement_channels = [] + def stop(self): + if self.timer is not None: + self.timer.cancel(); + def handle_message(self, cli): if self.timer is None: self.find_next_event() @@ -33,11 +38,11 @@ def handle_message(self, cli): self.timer = threading.Timer(seconds, self.handle_timer, args=[cli, "@everyone " + self.nextEvent[0] + warning[0]]) self.timer.start() - print "created " + str(seconds) + "s timer for " + str(self.nextEvent) + logging.info("created " + str(seconds) + "s timer for " + str(self.nextEvent)) break def handle_timer(self, cli, message): - print "timer complete, printing """ + message + '"' + logging.info("timer complete, printing """ + message + '"') self.timer = None for channel in self.announcement_channels: cli.send_message(cli.get_channel(channel), message) diff --git a/test.py b/test.py new file mode 100644 index 0000000..26450a5 --- /dev/null +++ b/test.py @@ -0,0 +1,165 @@ +import unittest +from bot.commands import commands +from bot import event_manager +from bot import game_server + +class FakeClient(object): + def send_message(self,channel,message): + "empty"; + +class FakeBot(object): + def __init__(self, **kwargs): + self.game_servers = {} + self.commands = commands + self.event_manager = kwargs.get("event_manager") + self.main_watcher = kwargs.get("main_watcher") + self.FAMDB_app_id = kwargs.get("FAMDB_app_id") + self.FAMDB_API_key = kwargs.get("FAMDB_API_key") + self.TS3_address = kwargs.get("TS3_address") + self.TS3_port = kwargs.get("TS3_port") + self.TS3_password = kwargs.get("TS3_password") + + def server_address(self, server_name): + return "wow this function sure is fake" + +class FakeMessage(object): + def __init__(self, **kwargs): + self.id = kwargs.get("id") + self.name = kwargs.get("name") + self.server = kwargs.get("server") + +class FakeChannel(object): + def __init__(self, **kwargs): + self.channel = kwargs.get("channel") + +class FakeSession(object): + isSetVar = False; + def start(self) : + self.isSetVar = True + + def stop(self) : + self.isSetVar = False + + def isSet(self) : + return self.isSetVar + +class FakeWatcher(object): + session = FakeSession() + + def start(self): + self.session.start() + + def stop(self): + self.session.stop() + +class TestCommands(unittest.TestCase): + def setUp(self): + self.main_client = FakeClient(); + self.bot = FakeBot( + # this may fail and/or cause weird issues if run when a event starts + event_manager = event_manager.EventManager(), + main_watcher = FakeWatcher(), + FAMDB_app_id = "1IijmSndIGJFPg6cw6xDl5PRe5AiGCHliyPzIgPc", + FAMDB_API_key = "A7n2hKn8S1qiBY3dmSduYl90kskHBi957KXuSqgs", + TS3_address = "server.folkarps.com", + TS3_port = 9988, + TS3_password = "freedom" + ) + self.test_channel = FakeMessage(id = "12345", name = "Test Channel", server = "Test Server") + self.test_message = FakeChannel(channel = self.test_channel) + self.bot.game_servers['arma'] = game_server.ArmaServer( + ip="91.121.223.212", + port=2702, + password="freedom" + ) + self.bot.game_servers['armatest'] = game_server.ArmaServer( + ip="91.121.223.212", + port=2722, + password="freedom" + ) + self.bot.game_servers['insurgency'] = game_server.InsurgencyServer( + ip="91.121.223.212", + port=27014 + ) + + def tearDown(self): + self.bot.event_manager.stop(); + + #update once status works + def test_status(self): + self.assertIsNotNone(commands["status"](self.bot, self.test_message, "")); + + def test_info(self): + self.assertRegexpMatches(commands["info"](self.bot, self.test_message, ""), "Arma 3 v[0-9\.]* - Folk ARPS - .* - [0-9]*/[0-9]* humans, [0-9]* AI on .*") + + def test_github(self): + self.assertEqual(commands["github"](self.bot, self.test_message, ""), "https://github.com/darkChozo/folkbot") + + def test_help(self): + self.assertRegexpMatches(commands["help"](self.bot, self.test_message, ""), "Available commands:\n(!(\w )+: .*)*"); + + def test_tsserver(self): + self.assertEqual(commands["tsserver"](self.bot, self.test_message, ""), "Our Teamspeak server:\nAddress: **server.folkarps.com:9988** Password: **freedom**\nOr you can just click this link:\n"); + + def test_testserver(self): + self.assertEqual(commands["testserver"](self.bot, self.test_message, ""), "wow this function sure is fake"); + + def test_armaserver(self): + self.assertEqual(commands["armaserver"](self.bot, self.test_message, ""), "wow this function sure is fake"); + + def test_insurgency(self): + self.assertRegexpMatches(commands["insurgency"](self.bot, self.test_message, ""), "Insurgency v[0-9\.]* - .* - .* - [0-9]*/[0-9]* humans, [0-9]* AI on .*") + + def test_ping(self): + self.assertRegexpMatches(commands["ping"](self.bot, self.test_message, ""), "[0-9.]* milliseconds") + + def test_nextevent(self): + self.bot.event_manager.handle_message(self.main_client) + self.assertRegexpMatches(commands["nextevent"](self.bot, self.test_message, ""), "Next event is .+ in .+ \([0-9]+:[0-9]+ UTC on .+\)\.") + + def test_players(self): + self.assertRegexpMatches(commands["players"](self.bot, self.test_message, ""), "Total players: [0-9]+(\n[0-9]+ .* \(on for [0-9]+\.[0.9]+ seconds\))*$") + + def test_players_insurgency(self): + self.assertRegexpMatches(commands["players"](self.bot, self.test_message, "insurgency"), "Total players: [0-9]+(\n[0-9]+ .* \(on for [0-9]+\.[0.9]+ seconds\))*$") + + #update once rules works + def test_rules(self): + self.assertIsNotNone(commands["rules"](self.bot, self.test_message, "")); + + def test_insurgency(self): + self.assertRegexpMatches(commands["insurgency"](self.bot, self.test_message, ""), "Insurgency v[0-9\.]* - Folk ARPS - Insurgency - [0-9]*/[0-9]* humans, [0-9]* AI on .*") + + def test_f3(self): + self.assertEqual(commands["f3"](self.bot, self.test_message, ""), "Latest F3 downloads: http://ferstaberinde.com/f3/en//index.php?title=Downloads"); + + def test_biki(self): + self.assertEqual(commands["biki"](self.bot, self.test_message, "search"), "https://community.bistudio.com/wiki?search=search&title=Special%3ASearch&go=Go"); + + def test_f3wiki(self): + self.assertEqual(commands["f3wiki"](self.bot, self.test_message, "search"), "http://ferstaberinde.com/f3/en//index.php?search=search&title=Special%3ASearch&go=Go"); + + def test_session(self): + self.assertIsNone(commands["session"](self.bot, self.test_message, "start")); + self.assertEqual(commands["session"](self.bot, self.test_message, ""), "Folk ARPS session underway; FA_bot will announce when we're slotting"); + self.assertIsNone(commands["session"](self.bot, self.test_message, "stop")); + self.assertEqual(commands["session"](self.bot, self.test_message, ""), "No Folk ARPS session running at the moment. Check when the next event is on with !nextevent"); + + def test_addons(self): + self.assertEqual(commands["addons"](self.bot, self.test_message, ""), "http://www.folkarps.com/forum/viewtopic.php?f=43&t=1382"); + + def test_test(self): + # i dunno + self.assertIsNotNone(commands["test"](self.bot, self.test_message, "")); + + def test_mission_current(self): + self.assertRegexpMatches(commands["mission"](self.bot, self.test_message, ""), "\*\*Mission name: .*\*\* \*.*\*\n\*\*Mission type:\*\* .*\n*\*Location:\*\* .*\n*\*Author:\*\* .*\n*\*Description:\*\* .*"); + + def test_mission_search(self): + self.assertRegexpMatches(commands["mission"](self.bot, self.test_message, "Bees"), "\*\*Mission name: .*\*\*\n \*\*Mission type:\*\* .*\n\*\*Location:\*\* .*\n\*\*Author:\*\* .*\n\*\*Description:\*\* [.\n]*"); + + # this will be an interesting one... + #def test_update(self) + +if __name__ == '__main__': + unittest.main()