mod_hgpoll.py

Sat, 29 Nov 2014 16:53:32 +0200

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 29 Nov 2014 16:53:32 +0200
changeset 100
2a56ccf67782
parent 87
9e757b602586
child 110
b2770c43b752
permissions
-rw-r--r--

- be more liberal on posting commit messages to IRC
- don't log REST connections to log channel anymore

from hgapi import hgapi, Repo
from datetime import datetime
import hgpoll as HgPoll
import re
import bt as Bt
from configfile import Config

ModuleData = {
	'commands':
	[
		{
			'name': 'checkhg',
			'description': 'Polls the zandronum repositories for updates',
			'args': None,
			'level': 'admin',
		},
		{
			'name': 'cset',
			'description': 'Yields changeset information (use a hash or date as key)',
			'args': '<key>',
			'level': 'normal',
		},
		{
			'name': 'hg',
			'description': 'Executes a hg command',
			'args': '<repo> <command...>',
			'level': 'admin',
		},
		{
			'name': 'resolves',
			'description': 'Manually cause a ticket to be resolved by a changeset',
			'args': '<ticket> <changeset>',
			'level': 'admin',
		},
	]
}

def plural (a):
	return '' if a == 1 else 's'

def cmd_checkhg (bot, **rest):
	HgPoll.force_poll()

def cmd_cset (bot, args, replyto, **rest):
	repo = Repo ('zandronum-everything')
	data = ""
	node = args['key']

	# Possibly we're passed a date version instead. Try find the node for this.
	try:
		datetime.strptime (args['key'], '%y%m%d-%H%M')
		HgPoll.make_commits_txt()
		commits_txt = open ('commits.txt', 'r')
		
		for line in commits_txt:
			data = line.replace ('\n', '').split (' ')
			if data[1] == args['key']:
				node = data[0]
				break
		else:
			bot.privmsg (replyto, 'couldn\'t find changset for date %s' % args['key'])
			return
	except ValueError:
		pass
	
	# The sandboxes contain all revisions in zandronum and zandronum-stable.
	# Thus we only need to try find the revision in the sandbox repos.
	try:
		data = repo.hg_command ("log", "-r", node, "--template",
			"{node|short}@@@@@@@{desc}@@@@@@@{author}@@@@@@@{diffstat}@@@@@@@{date|hgdate}")
	except hgapi.HgException:
		bot.privmsg (replyto, 'couldn\'t find changeset %s' % (node))
		return
	
	try:
		data = data.split ('@@@@@@@')
		node = data[0]
		message = data[1]
		author = data[2]
		diffstat = data[3]
		date = datetime.utcfromtimestamp (int (data[4].split (' ')[0]))
		delta = datetime.utcnow() - date
		datestring = ''
		
		# Find out the Zandronum version of this changeset
		repo.hg_command ('revert', '-r', node, 'src/version.h')
		zanversion = '<unknown zandronum version>'
		
		with open ('zandronum-everything/src/version.h') as version_file:
			regexps = [ \
				re.compile (r'#define\s+GAMEVER_STRING\s+"([^"]+)"'), \
				re.compile (r'#define\s+DOTVERSIONSTR_NOREV\s+"([^"]+)"'), \
				re.compile (r'#define\s+DOTVERSIONSTR\s+"([^"]+)"')]
			
			for line in version_file:
				for rex in regexps:
					match = rex.match (line)
					if match != None:
						zanversion = match.group (1)
						break
				
				if match != None:
					break
			
		
		repo.hg_command ('revert', '--all')
		
		# Remove the email address from the author if possible
		match = re.compile (r'^(.+) <([^>]+)>$.*').match (author)
		if match:
			author = match.group (1)
			email = match.group (2)
		
		username = Config.find_developer_by_email (email)
		
		if username != '':
			author = username
		
		if delta.days < 4:
			if delta.days == 0:
				if delta.seconds < 60:
					datestring = 'just now'
				elif delta.seconds < 3600:
					minutes = delta.seconds / 60
					datestring = '%d minute%s ago' % (minutes, plural (minutes))
				else:
					hours = delta.seconds / 3600
					datestring = '%d hour%s ago' % (hours, plural (hours))
			else:
				datestring = '%d day%s ago' % (delta.days, plural (delta.days))
		else:
			datestring = 'on %s' % (str (date))
		
		bot.privmsg (replyto, 'changeset %s (%s %s): committed by %s %s (%s)' % \
			(node, zanversion, date.strftime ('%y%m%d-%H%M'), author, datestring, diffstat))
		
		for line in message.split ('\n'):
			bot.privmsg (replyto, '    ' + line)
	except hgapi.HgException as e:
		result = HgPoll.decipher_hgapi_error (e)
		
		if result[0]:
			bot.privmsg (replyto, 'error: %s' % result[1])
		else:
			bot.privmsg (replyto, 'error: %s' % `e`)

def cmd_hg (bot, args, **rest):
	try:
		repo = hgapi.Repo (args['repo'])
		result = repo.hg_command (*args['command'])
		self.privmsg (replyto, result)
	except hgapi.hgapi.HgException as e:
		result = HgPoll.decipher_hgapi_error (e)
		
		if result[0]:
			self.privmsg (replyto, 'error: %s' % result[1])
		else:
			self.privmsg (replyto, 'error: %s' % `e`)

def cmd_resolves (bot, args, replyto, **rest):
	try:
		HgPoll.announce_ticket_resolved (args['ticket'], args['changeset'])
	except Exception as e:
		bot.privmsg (replyto, 'Error: %s' % e)

mercurial