cobalt.py

changeset 65
20bd76353eb5
parent 63
a1a864c25e42
child 66
74d8ca04ff01
equal deleted inserted replaced
64:384167adad2b 65:20bd76353eb5
31 import socket 31 import socket
32 import time 32 import time
33 import sys 33 import sys
34 import traceback 34 import traceback
35 import re 35 import re
36 import json
37 import urllib 36 import urllib
38 import urllib2 37 import urllib2
39 import hgapi 38 import hgapi
40 import os 39 import os
41 import suds 40 import suds
42 import math 41 import math
42 import json
43 from datetime import datetime 43 from datetime import datetime
44 import commandhandler as CommandHandler 44 import modulecore as ModuleCore
45 45 import configfile
46 CommandHandler.init_data() 46 from configfile import Config
47
48 ModuleCore.init_data()
47 49
48 try: 50 try:
49 uid = os.geteuid() 51 uid = os.geteuid()
50 except: 52 except:
51 uid = -1 53 uid = -1
52 54
53 if uid == 0 and raw_input ('Do you seriously want to run cobalt as root? [y/N] ') != 'y': 55 if uid == 0 and raw_input ('Do you seriously want to run cobalt as root? [y/N] ') != 'y':
54 quit() 56 quit()
55 57
56 print 'Loading configuration...' 58 configfile.init()
57 try: 59 g_admins = Config.get_value ('admins', default=[])
58 with open ('cobalt.json', 'r') as fp: 60 g_mynick = Config.get_value ('nickname', default='cobalt')
59 g_config = json.loads (fp.read())
60 except IOError as e:
61 print 'couldn\'t open cobalt.json: %s' % e
62 quit()
63
64 g_admins = g_config['admins']
65 g_mynick = g_config['nickname']
66
67 g_BotActive = False 61 g_BotActive = False
68 g_needCommitsTxtRebuild = True 62 g_needCommitsTxtRebuild = True
69 63
70 # 64 #
71 # SOAP stuff 65 # SOAP stuff
82 pass 76 pass
83 77
84 btannounce_active = False 78 btannounce_active = False
85 btannounce_timeout = 0 79 btannounce_timeout = 0
86 80
87 def save_config():
88 with open ('cobalt.json', 'w') as fp:
89 json.dump (g_config, fp, sort_keys = True, indent = 4)
90
91 def cfg (key, default):
92 if not hasattr (g_config, key):
93 g_config[key] = default
94 save_config()
95 return default
96 return g_config[key]
97
98 def bt_updatechecktimeout(): 81 def bt_updatechecktimeout():
99 global btannounce_timeout 82 global btannounce_timeout
100 btannounce_timeout = time.time() + (cfg ('btlatest_checkinterval', 5) * 60) 83 btannounce_timeout = time.time() + (Config.get_node ('bt').get_value ('checkinterval', default=5) * 60)
84
85 def bt_credentials():
86 bt = Config.get_node ('bt')
87 user = bt.get_value ('username', '')
88 password = bt.get_value ('password', '')
89 return [user, password]
101 90
102 if suds_active: 91 if suds_active:
103 try: 92 sys.stdout.write ('Retrieving latest tracker ticket... ')
104 sys.stdout.write ('Retrieving latest tracker ticket... ') 93 user, password = bt_credentials()
105 btannounce_id = suds_client.service.mc_issue_get_biggest_id (g_config['trackeruser'], g_config['trackerpassword'], 0) 94 btannounce_id = suds_client.service.mc_issue_get_biggest_id (user, password, 0)
106 btannounce_active = True 95 btannounce_active = True
107 bt_updatechecktimeout() 96 bt_updatechecktimeout()
108 print btannounce_id 97 print btannounce_id
109 except Exception as e:
110 pass
111 98
112 def bt_getissue(ticket): 99 def bt_getissue(ticket):
113 global suds_client 100 global suds_client
114 global g_config 101 user, password = bt_credentials()
115 return suds_client.service.mc_issue_get (g_config['trackeruser'], g_config['trackerpassword'], ticket) 102 return suds_client.service.mc_issue_get (user, password, ticket)
116 103
117 def bt_checklatest(): 104 def bt_checklatest():
118 global btannounce_timeout 105 global btannounce_timeout
119 global btannounce_id 106 global btannounce_id
120 107
121 if time.time() >= btannounce_timeout: 108 if time.time() >= btannounce_timeout:
122 bt_updatechecktimeout() 109 bt_updatechecktimeout()
123 newid = btannounce_id 110 newid = btannounce_id
124 try: 111 try:
125 newid = suds_client.service.mc_issue_get_biggest_id (g_config['trackeruser'], g_config['trackerpassword'], 0) 112 user, password = bt_credentials()
113 newid = suds_client.service.mc_issue_get_biggest_id (user, password, 0)
126 except Exception as e: 114 except Exception as e:
127 pass 115 pass
128 116
129 while newid > btannounce_id: 117 while newid > btannounce_id:
130 try: 118 try:
160 for client in g_clients: 148 for client in g_clients:
161 if not client.flags & CLIF_CONNECTED: 149 if not client.flags & CLIF_CONNECTED:
162 continue 150 continue
163 151
164 for channel in client.channels: 152 for channel in client.channels:
165 if channel['logchannel']: 153 if channel.get_value ('logchannel', default=False):
166 client.write ("PRIVMSG %s :%s" % (channel['name'], line)) 154 client.write ("PRIVMSG %s :%s" % (channel['name'], line))
167 155
168 # 156 #
169 # Exception handling 157 # Exception handling
170 # 158 #
273 check_repo_exists ('zandronum-stable', 'Torr_Samaho') 261 check_repo_exists ('zandronum-stable', 'Torr_Samaho')
274 check_repo_exists ('zandronum-sandbox', 'crimsondusk') 262 check_repo_exists ('zandronum-sandbox', 'crimsondusk')
275 check_repo_exists ('zandronum-sandbox-stable', 'crimsondusk') 263 check_repo_exists ('zandronum-sandbox-stable', 'crimsondusk')
276 check_repo_exists ('zandronum-everything', '') 264 check_repo_exists ('zandronum-everything', '')
277 265
278 repocheck_timeout = {'zandronum':(time.time()) + 15, 'zandronum-stable':(time.time() + 15), 'zandronum-sandbox':(time.time()) + 15, 'zandronum-sandbox-stable':(time.time()) + 15} 266 repocheck_timeout = {(time.time()) + 15}
279 267
280 def get_commit_data (zanrepo, rev, template): 268 def get_commit_data (zanrepo, rev, template):
281 return zanrepo.hg_command ('log', '-l', '1', '-r', rev, '--template', template) 269 return zanrepo.hg_command ('log', '-l', '1', '-r', rev, '--template', template)
282 #enddef 270 #enddef
283 271
316 304
317 return result 305 return result
318 #enddef 306 #enddef
319 307
320 def find_developer_by_email (commit_email): 308 def find_developer_by_email (commit_email):
321 for developer, emails in g_config['developer_emails'].iteritems(): 309 for developer, emails in Config.get_value ('developer_emails', default={}).iteritems():
322 for email in emails: 310 for email in emails:
323 if commit_email == email: 311 if commit_email == email:
324 return developer 312 return developer
325 #fi 313 #fi
326 #done 314 #done
332 ' Retrieves and processes commits for zandronum repositories ' 320 ' Retrieves and processes commits for zandronum repositories '
333 ' Ensure both repositories are OK before using this! ' 321 ' Ensure both repositories are OK before using this! '
334 def process_zan_repo_updates (repo_name): 322 def process_zan_repo_updates (repo_name):
335 global repocheck_timeout 323 global repocheck_timeout
336 global suds_client 324 global suds_client
337 global g_config
338 global g_clients 325 global g_clients
326
327 hgns = Config.get_node ('hg')
328
329 if not hgns.get_value ('track', default=True):
330 return
339 331
340 usestable = repo_name == 'zandronum-stable' 332 usestable = repo_name == 'zandronum-stable'
341 usesandbox = repo_name == 'zandronum-sandbox' or repo_name == 'zandronum-sandbox-stable' 333 usesandbox = repo_name == 'zandronum-sandbox' or repo_name == 'zandronum-sandbox-stable'
342 repo_owner = 'Torr_Samaho' if not usesandbox else 'crimsondusk' 334 repo_owner = 'Torr_Samaho' if not usesandbox else 'crimsondusk'
343 repo_url = 'https://bitbucket.org/%s/%s' % (repo_owner, repo_name) 335 repo_url = 'https://bitbucket.org/%s/%s' % (repo_owner, repo_name)
344 num_commits = 0 336 num_commits = 0
345 337 btuser, btpassword = bt_credentials()
346 if time.time() < repocheck_timeout[repo_name]: 338
339 if time.time() < repocheck_timeout:
347 return 340 return
348 341
349 repocheck_timeout[repo_name] = time.time() + (cfg ('hg_checkinterval', 15) * 60) 342 repocheck_timeout = time.time() + hgns.get_value ('checkinterval', default=15) * 60
350 zanrepo = hgapi.Repo (repo_name) 343 zanrepo = hgapi.Repo (repo_name)
351 commit_data = [] 344 commit_data = []
352 delimeter = '@@@@@@@@@@' 345 delimeter = '@@@@@@@@@@'
353 346
354 try: 347 try:
482 commit_author = moredata[0] 475 commit_author = moredata[0]
483 commit_date = moredata[1] 476 commit_date = moredata[1]
484 commit_email = "" 477 commit_email = ""
485 478
486 try: 479 try:
487 ticket_data = suds_client.service.mc_issue_get (g_config['trackeruser'], 480 ticket_data = suds_client.service.mc_issue_get (btuser, btpassword, ticket_id)
488 g_config['trackerpassword'], ticket_id)
489 except Exception as e: 481 except Exception as e:
490 chanlog ('error while processing %s: %s' % (commit_node, `e`)) 482 chanlog ('error while processing %s: %s' % (commit_node, `e`))
491 continue 483 continue
492 #tried 484 #tried
493 485
550 need_update = True 542 need_update = True
551 #fi 543 #fi
552 544
553 # Announce on IRC 545 # Announce on IRC
554 for irc_client in g_clients: 546 for irc_client in g_clients:
555 for channel in irc_client.cfg['channels']: 547 for channel in irc_client.channels:
556 if 'btannounce' in channel and channel['btannounce'] == True: 548 if channel.get_value ('btannounce', default=True):
557 irc_client.privmsg (channel['name'], 549 irc_client.privmsg (channel.get_value ('name'),
558 "%s: commit %s fixes issue %d: %s" 550 "%s: commit %s fixes issue %d: %s"
559 % (repo_name, commit_node, ticket_id, commit_message)) 551 % (repo_name, commit_node, ticket_id, commit_message))
560 irc_client.privmsg (channel['name'], 552 irc_client.privmsg (channel.get_value ('name'),
561 "Read all about it here: " + irc_client.get_ticket_url (ticket_id)) 553 "Read all about it here: " + irc_client.get_ticket_url (ticket_id))
562 #fi 554 #fi
563 #done 555 #done
564 #done 556 #done
565 557
566 if need_update: 558 if need_update:
567 # We need to remove the note data, otherwise the ticket notes 559 # We need to remove the note data, otherwise the ticket notes
568 # will get unnecessary updates. WTF, MantisBT? 560 # will get unnecessary updates. WTF, MantisBT?
569 ticket_data.notes = [] 561 ticket_data.notes = []
570 suds_client.service.mc_issue_update (g_config['trackeruser'], g_config['trackerpassword'], ticket_id, ticket_data) 562 suds_client.service.mc_issue_update (btuser, btpassword, ticket_id, ticket_data)
571 #fi 563 #fi
572 564
573 suds_client.service.mc_issue_note_add (g_config['trackeruser'], g_config['trackerpassword'], ticket_id, { 'text': message }) 565 suds_client.service.mc_issue_note_add (btuser, btpassword, ticket_id, { 'text': message })
574 num_commits += 1 566 num_commits += 1
575 except Exception as e: 567 except Exception as e:
576 chanlog ('Error while processing %s: %s' % (commit_node, `e`)) 568 chanlog ('Error while processing %s: %s' % (commit_node, `e`))
577 continue 569 continue
578 #tried 570 #tried
587 # 579 #
588 # Main IRC client class 580 # Main IRC client class
589 # 581 #
590 class irc_client (asyncore.dispatcher): 582 class irc_client (asyncore.dispatcher):
591 def __init__ (self, cfg, flags): 583 def __init__ (self, cfg, flags):
592 self.name = cfg['name'] 584 self.name = cfg.get_value ('name')
593 self.host = cfg['address'] 585 self.host = cfg.get_value ('address')
594 self.port = cfg['port'] 586 self.port = cfg.get_value ('port', default=6667)
595 self.password = cfg['password'] if 'password' in cfg else '' 587 self.password = cfg.get_value ('password', default='')
596 self.channels = cfg['channels'] 588 self.channels = cfg.get_nodelist ('channels')
597 self.flags = flags 589 self.flags = flags
598 self.send_buffer = list() 590 self.send_buffer = []
599 self.umode = cfg['umode'] if 'umode' in cfg else '' 591 self.umode = cfg.get_value ('umode', default='')
600 self.cfg = cfg 592 self.cfg = cfg
601 self.mynick = '' 593 self.desired_name = Config.get_value ('nickname', default='cobalt')
602 self.verbose = g_config['verbose'] if 'verbose' in g_config else False 594 self.mynick = self.desired_name
603 self.commandprefix = g_config['commandprefix'][0] if 'commandprefix' in g_config else '.' 595 self.verbose = Config.get_value ('verbose', default=False)
604 596 self.commandprefix = Config.get_value ('commandprefix', default='.')
605 for channel in self.channels: 597
606 if not 'logchannel' in channel:
607 channel['logchannel'] = False
608 channel['namesdone'] = True
609 #channel['haslinkbot'] = False
610
611 if not 'conflictsuffix' in self.cfg:
612 self.cfg['conflictsuffix'] = '`'
613
614 self.desired_name = self.cfg['nickname'] if 'nickname' in self.cfg else g_config['nickname']
615 g_clients.append (self) 598 g_clients.append (self)
616 asyncore.dispatcher.__init__ (self) 599 asyncore.dispatcher.__init__ (self)
617 self.create_socket (socket.AF_INET, socket.SOCK_STREAM) 600 self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
618 self.connect ((self.host, self.port)) 601 self.connect ((self.host, self.port))
619 602
620 def register_to_irc (self): 603 def register_to_irc (self):
621 ident = self.cfg['ident'] if 'ident' in self.cfg else g_config['ident'] 604 ident = Config.get_value ('ident', default='cobalt')
622 gecos = self.cfg['gecos'] if 'gecos' in self.cfg else g_config['gecos'] 605 gecos = Config.get_value ('gecos', default='cobalt')
623 if 'password' in self.cfg: 606 self.write ("PASS %s" % self.password)
624 self.write ("PASS %s" % self.cfg['password'])
625 self.write ("USER %s * * :%s" % (ident, gecos)) 607 self.write ("USER %s * * :%s" % (ident, gecos))
626 self.write ("NICK %s" % self.mynick) 608 self.write ("NICK %s" % self.mynick)
627 609
628 def handle_connect (self): 610 def handle_connect (self):
629 self.mynick = self.desired_name
630 print "Connected to [%s] %s:%d" % (self.name, self.host, self.port) 611 print "Connected to [%s] %s:%d" % (self.name, self.host, self.port)
631 self.register_to_irc() 612 self.register_to_irc()
632 613
633 def write (self, utfdata): 614 def write (self, utfdata):
634 try: 615 try:
673 words = line.split(" ") 654 words = line.split(" ")
674 if len(words) >= 2: 655 if len(words) >= 2:
675 if words[1] == "001": 656 if words[1] == "001":
676 self.flags |= CLIF_CONNECTED 657 self.flags |= CLIF_CONNECTED
677 658
678 for channel in self.cfg['channels']: 659 for channel in self.channels:
679 self.write ("JOIN %s %s" % (channel['name'], channel['password'] if 'password' in channel else '')) 660 self.write ("JOIN %s %s" % (channel.get_value ('name'), channel.get_value ('password', default='')))
680 661
681 if 'umode' in self.cfg: 662 umode = self.cfg.get_value ('umode', '')
682 self.write ('MODE %s %s' % (self.mynick, self.cfg['umode'])) 663
664 if umode != '':
665 self.write ('MODE %s %s' % (self.mynick, self.cfg.get_value ('umode', '')))
683 elif words[1] == "PRIVMSG": 666 elif words[1] == "PRIVMSG":
684 self.handle_privmsg (line) 667 self.handle_privmsg (line)
685 elif words[1] == 'JOIN':
686 rex = re.compile (r'^:([^!]+)!([^@]+)@([^ ]+) JOIN :#(.+)')
687 match = rex.match (line)
688
689 #if match and match.group(1).toLower() == 'linkbot':
690 #channel_by_name (match.group(4))['haslinkbot'] = True
691 elif words[1] == 'QUIT': 668 elif words[1] == 'QUIT':
692 rex = re.compile (r'^:([^!]+)!([^@]+)@([^ ]+) QUIT') 669 rex = re.compile (r'^:([^!]+)!([^@]+)@([^ ]+) QUIT')
693 match = rex.match (line) 670 match = rex.match (line)
694 671
695 # Try reclaim our nickname if possible 672 # Try reclaim our nickname if possible
696 if match and match.group(1) == self.desired_name: 673 if match and match.group(1) == self.desired_name:
697 self.mynick = self.desired_name 674 self.mynick = self.desired_name
698 self.write ("NICK %s" % self.mynick) 675 self.write ("NICK %s" % self.mynick)
699
700 #if match and match.group(1).toLower() == 'linkbot':
701 #for channel in self.channels:
702 #channels['haslinkbot'] = False
703 elif words[1] == "433": 676 elif words[1] == "433":
704 #:irc.localhost 433 * cobalt :Nickname is already in use. 677 #:irc.localhost 433 * cobalt :Nickname is already in use.
705 self.mynick = '%s%s' % (self.mynick, self.cfg['conflictsuffix']) 678 self.mynick += self.cfg.get_value ('conflictsuffix', default='`')
706 self.write ("NICK %s" % self.mynick) 679 self.write ("NICK " + self.mynick)
707 680
708 # Check for new issues on the bugtracker 681 # Check for new issues on the bugtracker
709 bt_checklatest() 682 bt_checklatest()
710 683
711 # Check for new commits in the repositories 684 # Check for new commits in the repositories
712 for n in ['zandronum-stable', 'zandronum', 'zandronum-sandbox', 'zandronum-sandbox-stable']: 685 for n in ['zandronum-stable', 'zandronum', 'zandronum-sandbox', 'zandronum-sandbox-stable']:
713 process_zan_repo_updates (n) 686 process_zan_repo_updates (n)
714 687
715 def channel_by_name (self, name): 688 def channel_by_name (self, name):
716 for channel in self.channels: 689 for channel in self.channels:
717 if channel['name'].upper() == args[0].upper(): 690 if channel.get_value ('name').upper() == args[0].upper():
718 return channel 691 return channel
719 else: 692 else:
720 raise logical_exception ('unknown channel ' + args[0]) 693 raise logical_exception ('unknown channel ' + args[0])
721 694
722 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 695 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
733 channel = match.group (4) 706 channel = match.group (4)
734 message = match.group (5) 707 message = match.group (5)
735 replyto = channel if channel != g_mynick else sender 708 replyto = channel if channel != g_mynick else sender
736 709
737 # Check for tracker url in the message 710 # Check for tracker url in the message
738 http_regex = re.compile (r'.*http(s?)://%s/view\.php\?id=([0-9]+).*' % g_config['trackerurl']) 711 url = Config.get_node ('bt').get_value ('url')
712 http_regex = re.compile (r'.*http(s?)://%s/view\.php\?id=([0-9]+).*' % url)
739 http_match = http_regex.match (line) 713 http_match = http_regex.match (line)
740 714
741 # Check for command. 715 # Check for command.
742 if len(message) >= 2 and message[0] == self.commandprefix and message[1] != self.commandprefix: 716 if len(message) >= 2 and message[0] == self.commandprefix and message[1] != self.commandprefix:
743 stuff = message[1:].split(' ') 717 stuff = message[1:].split(' ')
757 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 731 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
758 # 732 #
759 # Get the URL for a specified ticket 733 # Get the URL for a specified ticket
760 # 734 #
761 def get_ticket_url (self, ticket): 735 def get_ticket_url (self, ticket):
762 return 'https://%s/view.php?id=%s' % (g_config['trackerurl'], ticket) 736 url = Config.get_node ('bt').get_value ('url')
737 return 'https://%s/view.php?id=%s' % (url, ticket)
763 738
764 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 739 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
765 # 740 #
766 # Retrieve a ticket from mantisbt 741 # Retrieve a ticket from mantisbt
767 # 742 #
778 if data: 753 if data:
779 if data['view_state']['name'] == 'private': 754 if data['view_state']['name'] == 'private':
780 allowprivate = False 755 allowprivate = False
781 756
782 for channel in self.channels: 757 for channel in self.channels:
783 if channel['name'] == replyto and 'btprivate' in channel and channel['btprivate'] == True: 758 if channel.get_value ('name') == replyto and channel.get_value ('btprivate', False):
784 allowprivate = True 759 allowprivate = True
785 break 760 break
786 #fi 761 #fi
787 #done 762 #done
788 763
804 self.privmsg (replyto, "Read all about it here: " + self.get_ticket_url (ticket)) 779 self.privmsg (replyto, "Read all about it here: " + self.get_ticket_url (ticket))
805 #fi 780 #fi
806 #fi 781 #fi
807 #enddef 782 #enddef
808 783
809 def save_config (self):
810 save_config()
811
812 def is_admin (self, ident, host): 784 def is_admin (self, ident, host):
813 return ("%s@%s" % (ident, host)) in g_admins 785 return ("%s@%s" % (ident, host)) in g_admins
814 786
815 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 787 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
816 # 788 #
818 # 790 #
819 def handle_command (self, sender, ident, host, replyto, command, args, message): 791 def handle_command (self, sender, ident, host, replyto, command, args, message):
820 kvargs = {'sender': sender, 'ident': ident, 'host': host, 'replyto': replyto, 'cmdname': command, 'message': message} 792 kvargs = {'sender': sender, 'ident': ident, 'host': host, 'replyto': replyto, 'cmdname': command, 'message': message}
821 793
822 try: 794 try:
823 result = CommandHandler.call_command (self, **kvargs) 795 result = ModuleCore.call_command (self, **kvargs)
824 796
825 if result: 797 if result:
826 return 798 return
827 else: 799 except ModuleCore.CommandError as e:
828 print 'CommandHandler.call_command returned false'
829 except CommandHandler.CommandError as e:
830 lines = str (e).split ('\n') 800 lines = str (e).split ('\n')
831 self.privmsg (replyto, 'error: %s' % lines[0]) 801 self.privmsg (replyto, 'error: %s' % lines[0])
832 802
833 for line in lines[1:]: 803 for line in lines[1:]:
834 self.privmsg (replyto, ' ' + line) 804 self.privmsg (replyto, ' ' + line)
1028 idstring = "0" + idstring 998 idstring = "0" + idstring
1029 999
1030 isprivate = data['view_state']['name'] == 'private' 1000 isprivate = data['view_state']['name'] == 'private'
1031 reporter = data['reporter']['name'] if hasattr (data['reporter'], 'name') else '<nobody>' 1001 reporter = data['reporter']['name'] if hasattr (data['reporter'], 'name') else '<nobody>'
1032 1002
1033 for channel in self.cfg['channels']: 1003 for channel in self.channels:
1034 if 'btannounce' in channel and channel['btannounce'] == True: 1004 if channel.get_value ('btannounce', False):
1035 if not isprivate or ('btprivate' in channel and channel['btprivate'] == True): 1005 if not isprivate or (channel.get_value ('btprivate', False)):
1036 self.write ("PRIVMSG %s :[%s] New issue %s, reported by %s: %s: %s" % \ 1006 self.write ("PRIVMSG %s :[%s] New issue %s, reported by %s: %s: %s" % \
1037 (channel['name'], data['project']['name'], idstring, reporter, 1007 (channel['name'], data['project']['name'], idstring, reporter,
1038 data['summary'], self.get_ticket_url (idstring))) 1008 data['summary'], self.get_ticket_url (idstring)))
1039 #fi 1009 #fi
1040 #fi 1010 #fi
1066 1036
1067 # 1037 #
1068 # Main procedure: 1038 # Main procedure:
1069 # 1039 #
1070 try: 1040 try:
1071 for aconn in g_config['autoconnect']: 1041 autoconnects = Config.get_value ('autoconnect', [])
1072 for conndata in g_config['connections']: 1042
1073 if conndata['name'] == aconn: 1043 if len (autoconnects) == 0:
1044 print "Nowhere to connect."
1045 quit()
1046
1047 for aconn in autoconnects:
1048 for conndata in Config.get_nodelist ('connections'):
1049 if conndata.get_value ('name') == aconn:
1074 irc_client (conndata, 0) 1050 irc_client (conndata, 0)
1075 break 1051 break
1076 else: 1052 else:
1077 raise logical_exception ("unknown autoconnect entry %s" % (aconn)) 1053 raise ValueError ("unknown autoconnect entry %s" % (aconn))
1078 1054
1079 g_BotActive = True 1055 g_BotActive = True
1080 asyncore.loop() 1056 asyncore.loop()
1081 except KeyboardInterrupt: 1057 except KeyboardInterrupt:
1082 for client in g_clients: 1058 for client in g_clients:
1083 client.keyboardinterrupt() 1059 client.keyboardinterrupt()

mercurial