Implement !convert command

master
Nikola Forró 6 years ago
parent 44784b149d
commit f52142fb06

@ -65,6 +65,8 @@ class DiscordClient(discord.Client):
(re.compile(r'^!cheese\s+(?P<q>")?(?P<query>.+)(?(q)")$'), self._do_cheese),
(re.compile(r'^!roll(\s+(?P<q>")?(?P<formula>.+)(?(q)"))?$'), self._do_roll),
(re.compile(r'^!nextstream$'), self._do_nextstream),
(re.compile(r'^!conv(ert)?\s+(?P<q1>")?(?P<expression>.+?)(?(q1)")'
r'(\s+(?P<q2>")?(?P<unit>[^\s]+)(?(q2)"))?$'), self._do_convert),
]
super(DiscordClient, self).__init__()
@ -287,3 +289,12 @@ class DiscordClient(discord.Client):
embed.add_field(name=format_delta(time - datetime.datetime.utcnow()),
value=time.strftime('%Y-%m-%d %I:%M %p GMT'), inline=False)
await message.channel.send(embed=embed)
async def _do_convert(self, server, user, message, expression, unit, **kwargs):
try:
result = self.commands.convert(expression, unit)
except CommandError as e:
await message.channel.send('Sorry {0}, {1}'.format(message.author.mention, e))
else:
embed = discord.Embed(description='**{0}**'.format(result), color=0x39ad0f)
await message.channel.send(embed=embed)

@ -105,6 +105,8 @@ class TwitchClient(irc.bot.SingleServerIRCBot):
(re.compile(r'^!(find)?clip\s+(?P<q>")?(?P<filter>.+)(?(q)")$'), self._do_clip),
(re.compile(r'^!roll(\s+(?P<q>")?(?P<formula>.+)(?(q)"))?$'), self._do_roll),
(re.compile(r'^!giveaway$'), self._do_giveaway),
(re.compile(r'^!conv(ert)?\s+(?P<q1>")?(?P<expression>.+?)(?(q1)")'
r'(\s+(?P<q2>")?(?P<unit>[^\s]+)(?(q2)"))?$'), self._do_convert),
(re.compile(r'^!command\s+set\s+(?P<q1>")?(?P<cmd>.+?)(?(q1)")\s+'
r'(?P<q2>")?(?P<resp>.+)(?(q2)")$'), self._do_command_set),
(re.compile(r'^!command\s+unset\s+(?P<q>")?(?P<cmd>.+)(?(q)")$'), self._do_command_unset),
@ -342,6 +344,14 @@ class TwitchClient(irc.bot.SingleServerIRCBot):
if self.giveaway['command']:
send_response('Type {0} to join!'.format(self.giveaway['command']))
def _do_convert(self, tags, send_response, expression, unit, **kwargs):
try:
result = self.commands.convert(expression, unit)
except CommandError as e:
send_response('Sorry @{0}, {1}'.format(tags['display-name'], e))
else:
send_response(result)
def _do_command_set(self, tags, send_response, cmd, resp, **kwargs):
if not self._is_mod(tags):
send_response('Sorry @{0}, you are not allowed to do this'.format(tags['display-name']))

@ -4,9 +4,10 @@ import unicodedata
import dateutil.parser
import requests
from services.youtube import Youtube, YoutubeError
from services.cheesecom import CheeseCom, CheeseComError
from services.converter import Converter, ConverterError
from services.roll20 import Roll20, Roll20Error
from services.youtube import Youtube, YoutubeError
INSTAGRAM_BASE_URL = 'https://www.instagram.com'
@ -210,6 +211,13 @@ class Commands(object):
self.last_roll_formula = formula
return result
def convert(self, expression, unit=None):
c = Converter()
try:
return c.convert(expression, unit)
except ConverterError as e:
raise CommandError(str(e))
def _get_instagram_media(self, params):
api_url = self.config['Instagram'].get('api_url')
r = requests.get('{0}/media'.format(api_url), params=params)

@ -3,6 +3,7 @@ fuzzywuzzy[speedup]
google-api-python-client
irc
parsy
pint
pyquery
python-dateutil
python-twitter

@ -0,0 +1,65 @@
import pint
class ConverterError(Exception):
pass
class Converter(object):
def __init__(self):
self.ureg = pint.UnitRegistry(autoconvert_offset_to_baseunit=True)
self.ureg.define('degreeC = kelvin; offset: 273.15 = °C = C')
self.ureg.define('degreeF = 5 / 9 * kelvin; offset: 255.372222 = °F = F')
self.default_units = {
self.ureg.degC: self.ureg.degreeF,
self.ureg.degreeC: self.ureg.degreeF,
self.ureg.degF: self.ureg.degreeC,
self.ureg.degreeF: self.ureg.degreeC,
self.ureg.kilometer: self.ureg.mile,
self.ureg.meter: self.ureg.foot,
self.ureg.centimeter: self.ureg.inch,
self.ureg.millimeter: self.ureg.inch,
self.ureg.mile: self.ureg.kilometer,
self.ureg.foot: self.ureg.meter,
self.ureg.inch: self.ureg.millimeter,
self.ureg.kilogram: self.ureg.pound,
self.ureg.pound: self.ureg.kilogram,
self.ureg.ounce: self.ureg.kilogram,
self.ureg.liter: self.ureg.gallon,
self.ureg.milliliter: self.ureg.floz,
self.ureg.gallon: self.ureg.liter,
self.ureg.floz: self.ureg.milliliter,
}
def convert(self, expression, unit=None):
try:
q = self.ureg.parse_expression(expression)
except pint.errors.UndefinedUnitError:
raise ConverterError('unknown units')
try:
q.units
except AttributeError:
if unit is not None:
q = self.ureg.parse_expression(expression + unit)
unit = None
else:
raise ConverterError('unknown units')
try:
q.units
except AttributeError:
raise ConverterError('unknown units')
if unit is not None:
try:
u = self.ureg.parse_units(unit)
except pint.errors.UndefinedUnitError:
raise ConverterError('unknown units')
else:
try:
u = self.default_units[q.units]
except KeyError:
raise ConverterError('no target units specified')
try:
result = q.to(u)
except pint.errors.DimensionalityError:
raise ConverterError('invalid conversion')
return '{:0.5g~P}'.format(result)
Loading…
Cancel
Save