mod_util.py

Sat, 11 Apr 2015 21:02:54 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 11 Apr 2015 21:02:54 +0300
changeset 122
f899af683bbe
parent 121
ac07779f788d
child 123
aeb0d0788869
permissions
-rw-r--r--

- fixed a derp in commitsdb

import math
import urllib2
import json
import subprocess
import re
from modulecore import command_error
import modulecore as ModuleCore
import utility

ModuleData = {
	'commands':
	[
		{
			'name': 'convert',
			'description': 'Performs numeric conversion',
			'args': '<value> as <valuetype>',
			'level': 'normal',
		},
		
		{
			'name': 'ud',
			'description': 'Looks up a term in urban dictionary',
			'args': '<term...>',
			'level': 'normal',
		},

		{
			'name': 'commands',
			'description': 'Lists commands available to the calling user',
			'args': None,
			'level': 'normal',
		},

		{
			'name': 'help',
			'description': 'Prints help about a given command',
			'args': '<command>',
			'level': 'normal',
		},

		{
			'name': 'calc',
			'description': 'Calculates a mathematical expression using apcalc',
			'args': '<expression...>',
			'level': 'normal',
		},

		{
			'name': 'more',
			'description': 'Prints subsequent command result pages',
			'args': None,
			'level': 'normal',
		},

		{
			'name': 'yes',
			'description': 'Confirms the previous command',
			'args': None,
			'level': 'normal',
		},

		{
			'name': 'no',
			'description': 'Unconfirms the previous command',
			'args': None,
			'level': 'normal',
		},

		{
			'name': 'bitly',
			'description': 'Shortens a link using bit.ly',
			'args': '<link>',
			'level': 'normal'
		},
	]
}

def cmd_convert (bot, args, reply, **rest):
	try:
		value = float (args['value'])
	except Exception as e:
		command_error (str (e))

	valuetype = args['valuetype']
	
	if valuetype in ['radians', 'degrees']:
		if valuetype == 'radians':
			radvalue = value
			degvalue = (value * 180.) / math.pi
		else:
			radvalue = (value * math.pi) / 180.
			degvalue = value
		
		reply ('%s radians, %s degrees (%s)' % (radvalue, degvalue, degvalue % 360.))
		return
	
	if valuetype in ['celsius', 'fahrenheit']:
		if valuetype == 'celsius':
			celvalue = value
			fahrvalue = value * 1.8 + 32
		else:
			celvalue = (value - 32) / 1.8
			fahrvalue = value
		
		reply ('%s degrees celsius, %s degrees fahrenheit' % (celvalue, fahrvalue))
		return
	
	command_error ('unknown valuetype %s, expected one of: degrees, radians (angle conversion), ' +
		'celsius, fahrenheit (temperature conversion)' % valuetype)

def cmd_ud (bot, args, reply, **rest):
	try:
		url = 'http://api.urbandictionary.com/v0/define?term=%s' % (args['term'].replace (' ', '%20'))
		response = urllib2.urlopen (url).read()
		data = json.loads (response)
		
		if not 'list' in data \
		or len(data['list']) == 0 \
		or not 'word' in data['list'][0] \
		or not 'definition' in data['list'][0]:
			command_error ("couldn't find a definition of \002%s\002" % args['term'])
		
		word = data['list'][0]['word']
		definition = data['list'][0]['definition'].replace ('\r', ' ').replace ('\n', ' ').replace ('  ', ' ')
		up = data['list'][0]['thumbs_up']
		down = data['list'][0]['thumbs_down']
		reply ("\002%s\002: %s\0033 %d\003 up,\0035 %d\003 down" % (word, definition, up, down))
	except Exception as e:
		command_error ('Urban dictionary lookup failed: %s' % e)

def cmd_commands (bot, reply, ident, host, **rest):
	commandlist = ModuleCore.get_available_commands (ident, host)
	partitioned=[]

	while len (commandlist) > 0:
		partitioned.append (commandlist[0:15])
		commandlist = commandlist[15:]

	for part in partitioned:
		reply ('\002Available commands\002: %s' % (", ".join (part)))

def cmd_help (bot, reply, ident, host, args, **rest):
	cmd = ModuleCore.get_command_by_name (args['command'])

	if not cmd:
		command_error ('unknown command \'%s\'' % args['command'])

	if not ModuleCore.is_available (cmd, ident, host):
		command_error ('you may not use %s' % cmd['name'])

	reply ('%s %s: %s' % (cmd['name'], cmd['args'], cmd['description']))

def mathsubstitute (expr, token, value):
	rex = re.compile (r'^(.*)\b' + token + r'\b(.*)$')
	match = rex.match (expr)

	while match:
		expr = match.group(1) + str (value) + match.group(2)
		match = rex.match (expr)

	return expr

def cmd_calc (bot, reply, args, **rest):
	expr = args['expression']

	try:
		# Substitute some mathematical constants
		expr = mathsubstitute (expr, 'pi' , 3.14159265358979323846264338327950288419716939937510)
		expr = mathsubstitute (expr, 'e'  , 2.71828182845904523536028747135266249775724709369995)
		expr = mathsubstitute (expr, 'phi', 1.6180339887498948482) # golden ratio

		result = subprocess.check_output (['calc', '--', expr], stderr=subprocess.STDOUT) \
			.replace ('\t', '') \
			.replace ('\n', '')

		errmatch = re.compile (r'^.*\bError\b.*$').match (result)

		if errmatch:
			command_error ('math error')
			return

		reply ('Result: %s' % result)
	except subprocess.CalledProcessError as e:
		command_error (e.output.split('\n')[0])
	except OSError as e:
		command_error ('failed to execute calc: ' + e.strerror)

def cmd_more (commandObject, **rest):
	ModuleCore.print_responses (commandObject)

def cmd_yes (**k):
	ModuleCore.confirm (k, True)

def cmd_no (**k):
	ModuleCore.confirm (k, False)

def cmd_bitly (reply, args, **k):
	reply ('Result: %s' % utility.shorten_link (args['link']))

mercurial