Add !roll to Twitch

master
Nikola Forró 6 years ago
parent a7fb13e477
commit 2081b334a8

@ -103,6 +103,7 @@ class TwitchClient(irc.bot.SingleServerIRCBot):
(re.compile(r'^!(bella(gram|pics)|insta(gram|bella))$'), self._do_bellagram),
(re.compile(r'^!yt\s+(?P<q>")?(?P<query>.+)(?(q)")$'), self._do_yt),
(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'^!command\s+set\s+(?P<q1>")?(?P<cmd>.+?)(?(q1)")\s+'
r'(?P<q2>")?(?P<resp>.+)(?(q2)")$'), self._do_command_set),
@ -318,6 +319,14 @@ class TwitchClient(irc.bot.SingleServerIRCBot):
else:
send_response('{0}: {1}'.format(result['title'], result['url']))
def _do_roll(self, tags, send_response, formula, **kwargs):
try:
result = self.commands.roll(formula, True)
except CommandError as e:
send_response('Sorry @{0}, {1}'.format(tags['display-name'], e))
else:
send_response(result)
def _do_giveaway(self, tags, send_response, **kwargs):
if not self.giveaway or not self.giveaway['active']:
send_response('There is currently no giveaway in progress')

@ -192,11 +192,11 @@ class Commands(object):
else:
return event
def roll(self, formula):
def roll(self, formula, plaintext=False):
if not formula:
formula = self.last_roll_formula
try:
result = Roll20.execute(formula)
result = Roll20.execute(formula, plaintext)
except Roll20Error:
raise CommandError('failed to interpret or execute the formula')
else:

@ -17,8 +17,9 @@ def num(x):
class Group(object):
def __init__(self, items):
def __init__(self, items, plaintext=False):
self.items = items
self.plaintext = plaintext
self.keep = None
self.drop = None
self.succ = None
@ -34,7 +35,9 @@ class Group(object):
result = []
for i, x in enumerate(self.items):
if i in kept:
if len(self.items) > 1 and self.succ:
if self.plaintext:
result.append(str(x))
elif len(self.items) > 1 and self.succ:
if self.succ(calculated[i]):
result.append('__{0}__'.format(x))
elif self.fail and self.fail(calculated[i]):
@ -43,9 +46,12 @@ class Group(object):
result.append(str(x))
else:
result.append(str(x))
else:
elif not self.plaintext:
result.append('~~*{0}*~~'.format(x))
return '**{{** {0} **}}**'.format(' + '.join(result))
if self.plaintext:
return '{{ {0} }}'.format(' + '.join(result))
else:
return '**{{** {0} **}}**'.format(' + '.join(result))
def _subrolls(self, tree):
def traverse(node, subrolls):
@ -206,8 +212,9 @@ class Operation2(object):
class Roll(object):
def __init__(self, result):
def __init__(self, result, plaintext=False):
self.result = result
self.plaintext = plaintext
self.label = None
self.keep = None
self.drop = None
@ -224,7 +231,9 @@ class Roll(object):
result = []
for i, x in enumerate(self.result):
if i in kept:
if self.succ:
if self.plaintext:
result.append(str(x))
elif self.succ:
if self.succ(x):
result.append('__{0}__'.format(x))
elif self.fail and self.fail(x):
@ -233,9 +242,12 @@ class Roll(object):
result.append(str(x))
else:
result.append(str(x))
else:
elif not self.plaintext:
result.append('~~*{0}*~~'.format(x))
return '**(** {0} **)**'.format(' + '.join(result))
if self.plaintext:
return '( {0} )'.format(' + '.join(result))
else:
return '**(** {0} **)**'.format(' + '.join(result))
def kept(self, ignore_group=False):
if not ignore_group and self.group_kept is not None:
@ -284,7 +296,7 @@ class Parser(object):
return expression.parse(formula)
@classmethod
def parse(cls, tokens):
def parse(cls, tokens, plaintext=False):
@parsy.generate
def group_failures():
result = yield group_successes
@ -329,7 +341,7 @@ class Parser(object):
yield parsy.match_item('{')
#result = yield group_simple
result = yield function | expression_additive
result = Group([result])
result = Group([result], plaintext)
while True:
end = yield parsy.match_item('}') | parsy.success('')
if end:
@ -474,7 +486,7 @@ class Parser(object):
else:
for modify in m:
result, dice = modify(result, dice)
return Roll(result)
return Roll(result, plaintext)
@parsy.generate
def sort():
@ -667,14 +679,17 @@ class Roll20Error(Exception):
class Roll20(object):
@classmethod
def execute(cls, formula):
def execute(cls, formula, plaintext=False):
try:
tokens = Parser.tokenize(formula)
result = Parser.parse(tokens)
result = Parser.parse(tokens, plaintext)
try:
calculated = result.calc()
except AttributeError:
calculated = num(result)
return '{0} = __**{1}**__'.format(str(result), calculated)
if plaintext:
return '{0} = {1}'.format(str(result), calculated)
else:
return '{0} = __**{1}**__'.format(str(result), calculated)
except (parsy.ParseError, TypeError, RuntimeError) as e:
raise Roll20Error(str(e))

Loading…
Cancel
Save