bt.py

Sat, 08 Aug 2015 14:17:06 +0300

author
Teemu Piippo <tsapii@utu.fi>
date
Sat, 08 Aug 2015 14:17:06 +0300
changeset 148
7e225c2659b8
parent 146
c17b82b1f573
child 152
1b734faab67a
permissions
-rw-r--r--

Added .py

'''
	Copyright 2014-2015 Teemu Piippo
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions
	are met:

	1. Redistributions of source code must retain the above copyright
	   notice, this list of conditions and the following disclaimer.
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	3. The name of the author may not be used to endorse or promote products
	   derived from this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''

import suds
import sys
import time
import re
import irc as Irc
from configfile import Config

suds_active = False
btannounce_active = False
btannounce_timeout = 0

def is_active():
	return suds_active

def get_ticket_data (bot, replyto, ticket, withlink):
	if suds_active == False:
		return

	data = {}
	try:
		data = get_issue (ticket)
	except Exception as e:
		bot.privmsg (replyto, "Failed to get info for issue %s: %s" % (ticket, e))

	if data:
		if data['view_state']['name'] == 'private':
			allowprivate = False

			for channel in bot.channels:
				if channel.get_value ('name') == replyto and channel.get_value ('btprivate', False):
					allowprivate = True
					break

			if not allowprivate:
				bot.privmsg (replyto, 'Error: ticket %s is private' % ticket)
				return

		bot.privmsg (replyto, "Issue %s: %s: Reporter: %s, assigned to: %s, status: %s (%s)" % \
			(ticket, \
			data.summary, \
			data.reporter.name if hasattr (data.reporter, 'name') else "<unknown>", \
			data.handler.name if hasattr (data, 'handler') else "nobody", \
			data.status.name, \
			data.resolution.name))

		if withlink:
			bot.privmsg (replyto, "Read all about it here: " + get_ticket_url (ticket))

def process_message (bot, line, replyto):
	# Check for tracker url in the message
	url = Config.get_node ('bt').get_value ('url')
	http_regex = re.compile (r'.*http(s?)://%s/view\.php\?id=([0-9]+).*' % url)
	http_match = http_regex.match (line)

	if http_match:
		get_ticket_data (bot, replyto, http_match.group (2), False)

def init():
	global suds_active
	global suds_client
	global btannounce_id
	
	try:
		print ('Initializing MantisBT connection...')
		suds_import = suds.xsd.doctor.Import ('http://schemas.xmlsoap.org/soap/encoding/', 'http://schemas.xmlsoap.org/soap/encoding/')
		suds_client = suds.client.Client ('https://zandronum.com/tracker/api/soap/mantisconnect.php?wsdl', plugins=[suds.xsd.doctor.ImportDoctor (suds_import)])
		suds_active = True
	except Exception as e:
		print ('Failed to establish MantisBT connection: %s' % e)

	if suds_active:
		sys.stdout.write ('Retrieving latest tracker ticket... ')
		user, password = credentials()
		btannounce_id = suds_client.service.mc_issue_get_biggest_id (user, password, 0)
		btannounce_active = True
		update_checktimeout()
		print (btannounce_id)

def update_checktimeout():
	global btannounce_timeout
	btannounce_timeout = time.time() + (Config.get_node ('bt').get_value ('checkinterval', default=5) * 60)

def credentials():
	bt = Config.get_node ('bt')
	user = bt.get_value ('username', '')
	password = bt.get_value ('password', '')
	return [user, password]

def get_issue (ticket):
	global suds_client
	user, password = credentials()
	print ("Retrieving issue data for %s..." % ticket)
	result = suds_client.service.mc_issue_get (user, password, ticket)
	return result

def poll():
	global btannounce_timeout
	global btannounce_id

	if not suds_active:
		return

	if time.time() >= btannounce_timeout:
		update_checktimeout()
		newid = btannounce_id
		try:
			user, password = credentials()
			newid = suds_client.service.mc_issue_get_biggest_id (user, password, 0)
		except Exception as e:
			Irc.broadcast ("Error while polling: %s" % e)
			pass

		while newid > btannounce_id:
			try:
				btannounce_id += 1
				data = get_issue (btannounce_id)
				
				for client in Irc.all_clients:
					announce_new_issue (client, data)
			except Exception as e:
				pass

def get_ticket_url (ticket):
	url = Config.get_node ('bt').get_value ('url')
	return 'https://%s/view.php?id=%s' % (url, ticket)

#
# Print a ticket announce to appropriate channels
#
def announce_new_issue (bot, data):
	idstring = "%d" % data.id
	while len(idstring) < 7:
		idstring = "0" + idstring

	isprivate = data['view_state']['name'] == 'private'
	reporter = data['reporter']['name'] if hasattr (data['reporter'], 'name') else '<nobody>'

	for channel in bot.channels:
		if channel.get_value ('btannounce', False):
			if not isprivate or (channel.get_value ('btprivate', False)):
				bot.write ("PRIVMSG %s :[%s] New issue %s, reported by %s: %s: %s" % \
					(channel.get_value ('name'),
					data['project']['name'],
					idstring,
					reporter,
					data['summary'],
					get_ticket_url (idstring)))

def update_issue (ticket_id, ticket_data):
	btuser, btpassword = credentials()
	suds_client.service.mc_issue_update (btuser, btpassword, ticket_id, ticket_data)

def post_note (ticket_id, message):
	btuser, btpassword = credentials()
	suds_client.service.mc_issue_note_add (btuser, btpassword, ticket_id, { 'text': message })

def custom_query (func, args):
	btuser, btpassword = credentials()
	args = [x.replace ('$user', btuser).replace ('$password', btpassword) for x in args]
	return getattr (suds_client.service, func)(*args)

mercurial