cobalt.py

changeset 12
e843c08ee51e
parent 11
90851b22ab88
child 13
4da122a2f79f
equal deleted inserted replaced
11:90851b22ab88 12:e843c08ee51e
66 plugins=[ImportDoctor (suds_import)]) 66 plugins=[ImportDoctor (suds_import)])
67 suds_active = True 67 suds_active = True
68 except Exception: 68 except Exception:
69 pass 69 pass
70 70
71 btannounce_active = False
72 btannounce_timeout = 0
73
74 def save_config():
75 with open ('cobalt.json', 'w') as fp:
76 json.dump (g_config, fp, sort_keys = True, indent = 4)
77
78 def cfg (key, default):
79 if not hasattr (g_config, key):
80 g_config[key] = default
81 save_config()
82 return default
83 return g_config[key]
84
85 def bt_updatechecktimeout():
86 global btannounce_timeout
87 btannounce_timeout = time.time() + (cfg ('btlatest_checkinterval', 5) * 60)
88
89 if suds_active:
90 try:
91 btannounce_id = suds_client.service.mc_issue_get_biggest_id (g_config['trackeruser'], g_config ['trackerpassword'], 0) - 1
92 btannounce_active = True
93 bt_updatechecktimeout()
94 print "Latest ticket on tracker: %d" % btannounce_id
95 except Exception as e:
96 pass
97
98 def bt_getissue(ticket):
99 global suds_client
100 global g_config
101 return suds_client.service.mc_issue_get (g_config['trackeruser'], g_config['trackerpassword'], ticket)
102
103 def bt_checklatest():
104 global btannounce_timeout
105 global btannounce_id
106
107 if time.time() >= btannounce_timeout:
108 bt_updatechecktimeout()
109 newid = btannounce_id
110 try:
111 newid = suds_client.service.mc_issue_get_biggest_id (g_config['trackeruser'], g_config ['trackerpassword'], 0)
112 except Exception as e:
113 pass
114
115 while newid > btannounce_id:
116 try:
117 btannounce_id += 1
118 data = bt_getissue (btannounce_id)
119
120 for client in g_clients:
121 client.announce_ticket (data)
122 except Exception as e:
123 pass
124
71 # 125 #
72 # irc_client flags 126 # irc_client flags
73 # 127 #
74 CLIF_CONTROL = (1 << 0) 128 CLIF_CONTROL = (1 << 0)
75 CLIF_CONNECTED = (1 << 1) 129 CLIF_CONNECTED = (1 << 1)
143 self.flags = flags 197 self.flags = flags
144 self.send_buffer = list() 198 self.send_buffer = list()
145 self.umode = cfg['umode'] if 'umode' in cfg else '' 199 self.umode = cfg['umode'] if 'umode' in cfg else ''
146 self.cfg = cfg 200 self.cfg = cfg
147 self.mynick = '' 201 self.mynick = ''
148 self.verbose = cfg['verbose'] if 'verbose' in cfg else False 202 self.verbose = g_config['verbose'] if 'verbose' in g_config else False
149 self.commandprefix = g_config['commandprefix'][0] if 'commandprefix' in g_config else '.' 203 self.commandprefix = g_config['commandprefix'][0] if 'commandprefix' in g_config else '.'
150 204
151 if not 'conflictsuffix' in self.cfg: 205 if not 'conflictsuffix' in self.cfg:
152 self.cfg['conflictsuffix'] = '`' 206 self.cfg['conflictsuffix'] = '`'
153 207
226 self.write ("NICK %s" % self.mynick) 280 self.write ("NICK %s" % self.mynick)
227 elif words[1] == "433": 281 elif words[1] == "433":
228 #:irc.localhost 433 * cobalt :Nickname is already in use. 282 #:irc.localhost 433 * cobalt :Nickname is already in use.
229 self.mynick = '%s%s' % (self.mynick, self.cfg['conflictsuffix']) 283 self.mynick = '%s%s' % (self.mynick, self.cfg['conflictsuffix'])
230 self.write ("NICK %s" % self.mynick) 284 self.write ("NICK %s" % self.mynick)
285
286 # Check for new issues on the bugtracker
287 bt_checklatest()
231 288
232 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 289 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
233 # 290 #
234 # Handle a PRIVMSG line from the IRC server 291 # Handle a PRIVMSG line from the IRC server
235 # 292 #
262 else: 319 else:
263 control ("Recieved bad PRIVMSG: %s" % line) 320 control ("Recieved bad PRIVMSG: %s" % line)
264 321
265 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 322 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
266 # 323 #
324 # Get the URL for a specified ticket
325 #
326 def get_ticket_url (self, ticket):
327 return 'https://%s/view.php?id=%s' % (g_config['trackerurl'], ticket)
328
329 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
330 #
267 # Retrieve a ticket from mantisbt 331 # Retrieve a ticket from mantisbt
268 # 332 #
269 def get_ticket_data (self, replyto, ticket, withlink): 333 def get_ticket_data (self, replyto, ticket, withlink):
270 if suds_active == False: 334 if suds_active == False:
271 return 335 return
272 336
273 data = {} 337 data = {}
274 try: 338 try:
275 data = suds_client.service.mc_issue_get (g_config['trackeruser'], g_config ['trackerpassword'], ticket) 339 data = bt_getissue (ticket)
276 except Exception, e: 340 except Exception, e:
277 self.privmsg (replyto, "Failed to get info for issue %s: %s" % (ticket, `e`)) 341 self.privmsg (replyto, "Failed to get info for issue %s: %s" % (ticket, `e`))
278 342
279 if data: 343 if data:
280 self.privmsg (replyto, "Issue %s: %s: Reporter: %s, assigned to: %s, status: %s (%s)" % \ 344 self.privmsg (replyto, "Issue %s: %s: Reporter: %s, assigned to: %s, status: %s (%s)" % \
284 data.handler.name if hasattr (data, 'handler') else "nobody", \ 348 data.handler.name if hasattr (data, 'handler') else "nobody", \
285 data.status.name, \ 349 data.status.name, \
286 data.resolution.name)) 350 data.resolution.name))
287 351
288 if withlink: 352 if withlink:
289 self.privmsg (replyto, "Read all about it here: https://%s/view.php?id=%s" % (g_config['trackerurl'], ticket)) 353 self.privmsg (replyto, "Read all about it here: " + self.get_ticket_url (ticket))
290 354
291 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 355 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
292 # 356 #
293 # Process an IRC command 357 # Process an IRC command
294 # 358 #
303 self.privmsg (args[0], " ".join (args[1:])) 367 self.privmsg (args[0], " ".join (args[1:]))
304 elif command == 'ticket': 368 elif command == 'ticket':
305 if len(args) != 1: 369 if len(args) != 1:
306 raise logical_exception ("usage: .%s <ticket>" % command) 370 raise logical_exception ("usage: .%s <ticket>" % command)
307 self.get_ticket_data (replyto, args[0], True) 371 self.get_ticket_data (replyto, args[0], True)
372 elif command == 'testannounce':
373 check_admin (sender, ident, host, command)
374 if len(args) != 1:
375 raise logical_exception ("usage: .%s <ticket>" % command)
376 self.announce_ticket (bt_getissue (args[0]))
308 elif command == 'idgames': 377 elif command == 'idgames':
309 try: 378 try:
310 if len(args) < 1: 379 if len(args) < 1:
311 raise logical_exception ('usage: .%s <keywords>' % command) 380 raise logical_exception ('usage: .%s <keywords>' % command)
312 381
357 excepterm('') 426 excepterm('')
358 else: 427 else:
359 self.privmsg (replyto, 'Up to date at %s.' % r2) 428 self.privmsg (replyto, 'Up to date at %s.' % r2)
360 except hgapi.HgException as e: 429 except hgapi.HgException as e:
361 raise logical_exception ('Search failed: %s' % `e`) 430 raise logical_exception ('Search failed: %s' % `e`)
431 elif command == 'addchan':
432 check_admin (sender, ident, host, command)
433 if len(args) != 1:
434 raise logical_exception ("usage: .%s <channel>" % command)
435
436 for channel in self.channels:
437 if channel['name'].upper() == args[0].upper():
438 raise logical_exception ('I already know of %s!' % args[0])
439
440 chan = {}
441 chan['name'] = args[0]
442 self.channels.append (chan)
443 self.write ('JOIN ' + chan['name'])
444 save_config()
445 elif command == 'delchan':
446 check_admin (sender, ident, host, command)
447 if len(args) != 1:
448 raise logical_exception ("usage: .%s <channel>" % command)
449
450 for channel in self.channels:
451 if channel['name'].upper() == args[0].upper():
452 break;
453 else:
454 raise logical_exception ('unknown channel ' + args[0])
455
456 self.channels.remove (channel)
457 self.write ('PART ' + args[0])
458 save_config()
459 elif command == 'chanattr':
460 check_admin (sender, ident, host, command)
461
462 if len(args) < 2:
463 raise logical_exception ("usage: .%s <attribute> <value...>" % command)
464
465 for channel in self.channels:
466 if channel['name'] == replyto:
467 break
468 else:
469 raise logical_exception ('I don\'t know of a channel named ' + replyto)
470
471 key = args[0]
472 value = ' '.join (args[1:])
473
474 if key == 'name':
475 self.write ('PART ' + channel['name'])
476 channel['name'] = value
477 self.write ('JOIN ' + channel['name'] + ' ' + (channel['password'] if hasattr (channel, 'password') else ''))
478 elif key == 'password':
479 channel['password'] = value
480 elif key == 'btannounce':
481 if value != 'true' and value != 'false':
482 raise logical_exception ('expected true or false for value')
483 channel['btannounce'] = True if value == 'true' else False
484 else:
485 raise logical_exception ('unknown key ' + key)
486
487 save_config()
362 elif command == 'die': 488 elif command == 'die':
363 check_admin (sender, ident, host, command) 489 check_admin (sender, ident, host, command)
364 quit() 490 quit()
365 # else: 491 # else:
366 # raise logical_exception ("unknown command `.%s`" % command) 492 # raise logical_exception ("unknown command `.%s`" % command)
493
494 #
495 # Print a ticket announce to appropriate channels
496 #
497 def announce_ticket (self, data):
498 idstring = "%d" % data.id
499 while len(idstring) < 7:
500 idstring = "0" + idstring
501
502 reporter = data['reporter']['name'] if hasattr (data['reporter'], 'name') else '<nobody>'
503
504 for channel in self.cfg['channels']:
505 if 'btannounce' in channel and channel['btannounce'] == True:
506 self.write ("PRIVMSG %s :New issue %s, reported by %s: %s: %s" % \
507 (channel['name'], idstring, reporter, data['summary'], self.get_ticket_url (idstring)))
367 508
368 def handle_error(self): 509 def handle_error(self):
369 excepterm (traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) 510 excepterm (traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
370 511
371 def privmsg (self, channel, msg): 512 def privmsg (self, channel, msg):

mercurial