--- a/cobalt.py Tue Nov 04 20:35:25 2014 +0200 +++ b/cobalt.py Wed Nov 05 00:19:15 2014 +0200 @@ -41,6 +41,9 @@ import suds import math from datetime import datetime +import commandhandler as CommandHandler + +CommandHandler.init_data() try: uid = os.geteuid() @@ -61,7 +64,6 @@ g_admins = g_config['admins'] g_mynick = g_config['nickname'] -g_idgamesSearchURL = 'http://www.doomworld.com/idgames/api/api.php?action=search&query=%s&type=title&sort=date&out=json' g_BotActive = False g_needCommitsTxtRebuild = True @@ -97,11 +99,6 @@ global btannounce_timeout btannounce_timeout = time.time() + (cfg ('btlatest_checkinterval', 5) * 60) -def bool_from_string (value): - if value != 'true' and value != 'false': - raise logical_exception ('expected true or false for value') - return True if value == 'true' else False - if suds_active: try: sys.stdout.write ('Retrieving latest tracker ticket... ') @@ -327,6 +324,8 @@ ' Retrieves and processes commits for zandronum repositories ' ' Ensure both repositories are OK before using this! ' def process_zan_repo_updates (repo_name): + return + global repocheck_timeout global suds_client global g_config @@ -739,7 +738,7 @@ command = stuff[0] args = stuff[1:] try: - self.handle_command (sender, user, host, replyto, command, args) + self.handle_command (sender, user, host, replyto, command, args, message) except logical_exception as e: for line in e.value.split ('\n'): if len(line) > 0: @@ -801,20 +800,36 @@ #fi #enddef + def save_config (self): + save_config() + + def is_admin (self, ident, host): + return ("%s@%s" % (ident, host)) in g_admins + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Process an IRC command # - def handle_command (self, sender, ident, host, replyto, command, args): - if command == "raw": - check_admin (sender, ident, host, command) - self.write (" ".join (args)) - elif command == "msg": - check_admin (sender, ident, host, command) - if len(args) < 2: - raise logical_exception ("usage: .%s <target> <message...>" % command) - self.privmsg (args[0], " ".join (args[1:])) - elif command == 'ticket': + def handle_command (self, sender, ident, host, replyto, command, args, message): + kvargs = {'sender': sender, 'ident': ident, 'host': host, 'replyto': replyto, 'cmdname': command, 'message': message} + + try: + result = CommandHandler.call_command (self, **kvargs) + + if result: + return + else: + print 'CommandHandler.call_command returned false' + except CommandHandler.CommandError as e: + lines = str (e).split ('\n') + self.privmsg (replyto, 'error: %s' % lines[0]) + + for line in lines[1:]: + self.privmsg (replyto, ' ' + line) + return + #tried + + if command == 'ticket': if len(args) != 1: raise logical_exception ("usage: .%s <ticket>" % command) self.get_ticket_data (replyto, args[0], True) @@ -823,196 +838,6 @@ if len(args) != 1: raise logical_exception ("usage: .%s <ticket>" % command) self.announce_ticket (bt_getissue (args[0])) - elif command == 'multierror': - raise logical_exception ('a\nb\nc\n') - elif command == 'idgames': - try: - if len(args) < 1: - raise logical_exception ('usage: .%s <keywords>' % command) - - url = g_idgamesSearchURL % urllib.quote (" ".join (args[0:])) - response = urllib2.urlopen (url).read() - data = json.loads (response) - - if 'content' in data and 'file' in data['content']: - if type (data['content']['file']) is list: - files = data['content']['file'] - else: - files = [data['content']['file']] - - i = 0 - for filedata in files: - if i >= 5: - break - - self.privmsg (replyto, '- %s: \'%s\' by \'%s\', rating: %s: %s' % \ - (filedata['filename'], filedata['title'], filedata['author'], filedata['rating'], filedata['url'])) - - i += 1 - self.privmsg (replyto, "(%d / %d results posted)" % (i, len(files))) - elif 'warning' in data and 'message' in data['warning']: - raise logical_exception (data['warning']['message']) - elif 'error' in data and 'message' in data['error']: - raise logical_exception (data['error']['message']) - else: - raise logical_exception ("Incomplete JSON response from doomworld.com/idgames") - except logical_exception as e: - raise e - except Exception as e: - raise logical_exception ('Search failed: %s' % `e`) - elif command == 'restart': - check_admin (sender, ident, host, command) - excepterm('') - elif command == 'update': - check_admin (sender, ident, host, command) - - try: - repo = hgapi.Repo ('.') - r1 = repo.hg_id() - repo.hg_pull() - repo.hg_update('tip', True) - r2 = repo.hg_id() - if r1 != r2: - self.privmsg (replyto, 'Updated to %s, restarting...' % r2) - excepterm('') - else: - self.privmsg (replyto, 'Up to date at %s.' % r2) - except hgapi.HgException as e: - raise logical_exception ('Update failed: %s' % str (e)) - elif command == 'addchan': - check_admin (sender, ident, host, command) - if len(args) != 1: - raise logical_exception ("usage: .%s <channel>" % command) - - for channel in self.channels: - if channel['name'].upper() == args[0].upper(): - raise logical_exception ('I already know of %s!' % args[0]) - - chan = {} - chan['name'] = args[0] - chan['logchannel'] = False - self.channels.append (chan) - self.write ('JOIN ' + chan['name']) - save_config() - elif command == 'delchan': - check_admin (sender, ident, host, command) - if len(args) != 1: - raise logical_exception ("usage: .%s <channel>" % command) - - for channel in self.channels: - if channel['name'].upper() == args[0].upper(): - break; - else: - raise logical_exception ('unknown channel ' + args[0]) - - self.channels.remove (channel) - self.write ('PART ' + args[0]) - save_config() - elif command == 'chanattr': - check_admin (sender, ident, host, command) - - if len(args) < 1: - raise logical_exception ("usage: .%s <attribute> [value...]" % command) - - for channel in self.channels: - if channel['name'] == replyto: - break - else: - raise logical_exception ('I don\'t know of a channel named ' + replyto) - - key = args[0] - - if len(args) < 2: - try: - self.privmsg (replyto, '%s = %s' % (key, channel[key])) - except KeyError: - self.privmsg (replyto, 'attribute %s is not set' % key) - else: - value = " ".join (args[1:]) - if key == 'name': - if replyto == channel['name']: - replyto = value - - self.write ('PART ' + channel['name']) - channel['name'] = value - self.write ('JOIN ' + channel['name'] + ' ' + (channel['password'] if hasattr (channel, 'password') else '')) - elif key == 'password': - channel['password'] = value - elif key == 'btannounce': - channel['btannounce'] = bool_from_string (value) - elif key == 'btprivate': - channel['btprivate'] = bool_from_string (value) - elif key == 'logchannel': - channel['logchannel'] = bool_from_string (value) - else: - raise logical_exception ('unknown key ' + key) - - self.privmsg (replyto, '%s is now %s' % (key, channel[key])) - - save_config() - elif command == 'devemail': - check_admin (sender, ident, host, command) - - if len(args) < 2: - raise logical_exception ("usage: .%s <user> <email>" % command) - #fi - - if not 'developer_emails' in g_config: - g_config['developer_emails'] = {} - #fi - - user = ' '.join (args[0:-1]) - - if args[0] in g_config['developer_emails']: - g_config['developer_emails'][user].append (args[-1]) - else: - g_config['developer_emails'][user] = [args[-1]] - #fi - - self.privmsg (replyto, 'Developer emails for %s are now %s' % - (user, ', '.join (g_config['developer_emails'][user]))) - save_config() - elif command == 'deldevemail': - check_admin (sender, ident, host, command) - - if len(args) < 2: - raise logical_exception ("usage: .%s <user> <email>" % command) - #fi - - if not 'developer_emails' in g_config: - g_config['developer_emails'] = {} - #fi - - user = ' '.join (args[0:-1]) - - if user in g_config['developer_emails']: - try: - g_config['developer_emails'][user].remove (args[-1]) - except: - pass - #tried - - if len (g_config['developer_emails'][user]) == 0: - g_config['developer_emails'].pop (user) - self.privmsg (replyto, 'No more developer emails for %s' % user) - else: - self.privmsg (replyto, 'Developer emails for %s are now %s' % - (user, ', '.join (g_config['developer_emails'][user]))) - #fi - save_config() - else: - self.privmsg (replyto, 'There is no developer \'%s\'' % user) - #fi - elif command == 'listdevemails': - check_admin (sender, ident, host, command) - - if 'developer_emails' in g_config: - for dev, emails in g_config['developer_emails'].iteritems(): - self.privmsg (replyto, 'Emails for %s: %s' % (dev, ', '.join (emails))) - #done - else: - self.privmsg (replyto, 'No dev emails.') - #fi elif command == 'checkhg': check_admin (sender, ident, host, command) global repocheck_timeout @@ -1213,6 +1038,9 @@ def handle_error(self): excepterm (traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) + def restart(self): + excepterm('') + def privmsg (self, channel, msg): self.write ("PRIVMSG %s :%s" % (channel, msg))