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) |
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)" % \ |
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): |