def wait_for_prompt(p):
p.expect('EDI> ')
-@asyncio.coroutine
-def say_expect(message, stdout):
+async def say_expect(message, stdout):
if stdout:
log.debug(stdout)
- result = yield from bot.say(message.channel, '{}```{}```'.format('{} '.format(message.author.mention) if not message.channel.is_private else '', stdout))
+ result = await bot.say(message.channel, '{}```{}```'.format('{} '.format(message.author.mention) if not message.channel.is_private else '', stdout))
else:
- result = yield from bot.say(message.channel, 'Sorry!')
+ result = await bot.say(message.channel, 'Sorry!')
return result
-@asyncio.coroutine
-def not_admin(message):
+async def not_admin(message):
log.warning('Not admin: {} id {}'.format(message.author, message.author.id))
- yield from bot.maybe_say(message.channel, 'hiss!')
+ await bot.maybe_say(message.channel, 'hiss!')
-@asyncio.coroutine
-def show_help(message, *args):
+async def show_help(message, *args):
if len(args):
command = args[0]
else:
params = modules['edi']
fn = params['fn']
args = params['args']
- yield from fn(message, 'help', 'help {}'.format(command), *args)
+ await fn(message, 'help', 'help {}'.format(command), *args)
return
else:
- result = yield from plugins.handle_help(message, *args)
+ result = await plugins.handle_help(message, *args)
if result:
return
lines = ['*shrugs*']
- yield from bot.say_many(message.channel, lines)
+ await bot.say_many(message.channel, lines)
-@asyncio.coroutine
-def do_commands(message, command, raw, non_admin):
+async def do_commands(message, command, raw, non_admin):
if not non_admin:
if not bot.is_admin(message.author, message.server):
- yield from not_admin(message)
+ await not_admin(message)
return
log.debug('Command: {}'.format(raw))
url = message.attachments[0]['url']
if url is None:
log.debug('No URL for avatar')
- yield from cat.zzz(message.channel)
+ await cat.zzz(message.channel)
return
- result = yield from set_avatar(url)
+ result = await set_avatar(url)
if not result:
- yield from cat.yelp(message.channel)
+ await cat.yelp(message.channel)
return
elif command == 'delete':
# delete
if message.channel.is_private:
- yield from cat.hiss(message.channel, wake = False)
+ await cat.hiss(message.channel, wake = False)
return
args = {}
if m is not None:
if m.group(1) != 'all':
limit = int(m.group(1))
- yield from client.purge_from(message.channel, *args, limit = limit)
+ await client.purge_from(message.channel, *args, limit = limit)
return
elif command == 'help':
m = re.match(r'\bhelp\s+(.+)', raw, re.IGNORECASE)
if m is not None:
args = shlex.split(m.group(1))
- yield from show_help(message, *args)
+ await show_help(message, *args)
else:
- yield from show_help(message)
+ await show_help(message)
elif command == 'idle':
# idle
m = re.match(r'\bidle\s+(\d+)\b', raw, re.IGNORECASE)
if m is None:
- yield from bot.say(message.channel, 'Sorry!')
+ await bot.say(message.channel, 'Sorry!')
return
idletime.value = int(m.group(1))
elif command == 'time':
# time
- yield from bot.say(message.channel, bot.iso8601(int(time.time())))
- yield from bot.maybe_play_sound(bot.voice_channel_for_user(message.author), 'purr.wav', join = False)
+ await bot.say(message.channel, bot.iso8601(int(time.time())), embed = embed)
+ await bot.maybe_play_sound(bot.voice_channel_for_user(message.author), 'purr.wav', join = False)
return
elif command == 'url':
# Invite URL.
- yield from bot.say(message.channel, "<{}>".format(discord.utils.oauth_url(client.user.id)))
+ await bot.say(message.channel, "<{}>".format(discord.utils.oauth_url(client.user.id)))
return
- yield from bot.maybe_say(message.channel, 'purr', wake = False)
- yield from bot.maybe_play_sound(bot.voice_channel_for_user(message.author), 'purr.wav', join = False)
+ await bot.maybe_say(message.channel, 'purr', wake = False)
+ await bot.maybe_play_sound(bot.voice_channel_for_user(message.author), 'purr.wav', join = False)
-@asyncio.coroutine
-def do_edi(message, command, raw, p):
+async def do_edi(message, command, raw, p):
if command == 'close_to' and not '-m' in raw:
raw = 'close_to'
if command == 'distance':
raw = raw.replace(',', '')
log.info(raw)
- yield from client.send_typing(message.channel)
+ await client.send_typing(message.channel)
p.sendline(raw)
wait_for_prompt(p)
- yield from say_expect(message, p.before)
+ await say_expect(message, p.before)
-@asyncio.coroutine
-def do_fork(message, command, raw):
- yield from client.send_typing(message.channel)
+async def do_fork(message, command, raw):
+ await client.send_typing(message.channel)
if re.search(r'[^A-Za-z0-9-_."\'\s]', raw):
- yield from cat.hiss(message.channel)
+ await cat.hiss(message.channel)
return
p = pexpect.spawnu('./{}'.format(raw))
p.expect(pexpect.EOF)
- yield from say_expect(message, p.before)
+ await say_expect(message, p.before)
-@asyncio.coroutine
-def maybe_sleep():
+async def maybe_sleep():
while True:
if bot.status() != discord.Status.idle:
now = time.time()
if now - bot.get('last_spoke') >= idletime.value:
- yield from bot.zzz()
- yield from asyncio.sleep(60)
+ await bot.zzz()
+ await asyncio.sleep(60)
p = pexpect.spawnu('./edi.py')
wait_for_prompt(p)
plugins.get_plugin('admin').db = db
plugins.get_plugin('admin').plugins = plugins
-@asyncio.coroutine
-def builtin_commands(message, command, raw):
+async def builtin_commands(message, command, raw):
if command == 'plugins':
args = shlex.split(raw)
if len(args) > 1:
lines.append('{}: {}'.format(name, description))
else:
lines.append(name)
- yield from bot.say_many(message.channel, lines)
+ await bot.say_many(message.channel, lines)
else:
- yield from cat.shrug(message.channel)
+ await cat.shrug(message.channel)
return True
return False
-@asyncio.coroutine
-def process_module(message, command, raw):
+async def process_module(message, command, raw):
for module, params in modules.items():
if command in params['commands']:
log.info('Recognised command "{}" from {} in "{}" module'.format(command, message.author.name, module))
fn = params['fn']
args = params['args']
- yield from fn(message, command, raw, *args)
+ await fn(message, command, raw, *args)
return
log.debug('Unrecognised command from {}!'.format(message.author.name))
if bot.status() == discord.Status.idle:
- yield from cat.maybe_zzz(message.channel)
+ await cat.maybe_zzz(message.channel)
else:
- yield from cat.maybe_meow(message.channel)
+ await cat.maybe_meow(message.channel)
return True
@client.event
-@asyncio.coroutine
-def on_ready():
+async def on_ready():
state = db.get_state(client)
if state is not None:
if state['idle']:
log.info('Restoring idle status.')
- yield from bot.set_idle(True)
+ await bot.set_idle(True)
if state['avatar'] != db.IDLE_AVATAR:
log.info('Restoring idle avatar.')
- yield from set_avatar(db.IDLE_AVATAR)
+ await set_avatar(db.IDLE_AVATAR)
elif state['avatar'] != db.ONLINE_AVATAR:
log.info('Restoring online avatar.')
- yield from set_avatar(db.ONLINE_AVATAR)
+ await set_avatar(db.ONLINE_AVATAR)
if state['last_spoke']:
bot.set('last_spoke', state['last_spoke'])
log.info('Logged in as {}#{}'.format(client.user.name, client.user.id))
return True
@client.event
-@asyncio.coroutine
-def on_message(message):
+async def on_message(message):
if message.author.id == client.user.id:
return
log.debug('Got message from {}: {}'.format(message.author, message.content))
if m is None:
return
command = m.group(1)
- result = yield from builtin_commands(message, command, raw)
+ result = await builtin_commands(message, command, raw)
if not result:
- result = yield from plugins.handle_command(message, command, raw)
+ result = await plugins.handle_command(message, command, raw)
if not result:
- yield from process_module(message, command, raw)
+ await process_module(message, command, raw)
@client.event
-@asyncio.coroutine
-def on_member_join(member):
- yield from plugins.on_member_join(member)
+async def on_member_join(member):
+ await plugins.on_member_join(member)
@client.event
-@asyncio.coroutine
-def on_member_update(before, after):
- yield from plugins.on_member_update(before, after)
+async def on_member_update(before, after):
+ await plugins.on_member_update(before, after)
client.run(token)
return server.me.status
return None
-@asyncio.coroutine
-def set_avatar(url):
+async def set_avatar(url):
if re.match(r'^https?:', url):
fd = open_url(url)
else:
log.debug('Failed to open URL {} for avatar'.format(url))
return False
try:
- yield from client.edit_profile(avatar = fd.read())
+ await client.edit_profile(avatar = fd.read())
fd.close()
return True
except:
log.exception("set_avatar")
return False
-@asyncio.coroutine
-def set_idle(idle):
- yield from client.change_presence(status = discord.Status.idle if idle else discord.Status.online)
+async def set_idle(idle):
+ await client.change_presence(status = discord.Status.idle if idle else discord.Status.online)
for voice in list(client.voice_clients):
- yield from voice.disconnect()
+ await voice.disconnect()
-@asyncio.coroutine
-def wake_up(force = False):
+async def wake_up(force = False):
set('last_spoke', time.time())
if force or status() != discord.Status.online:
log.info('Waking up...')
- yield from set_avatar(db.ONLINE_AVATAR)
- yield from set_idle(False)
+ await set_avatar(db.ONLINE_AVATAR)
+ await set_idle(False)
db.set_state(client, avatar = db.ONLINE_AVATAR, idle = False, last_spoke = get('last_spoke'))
-@asyncio.coroutine
-def zzz():
+async def zzz():
# state = db.get_state(client)
# if state is None:
# change = status() != discord.Status.idle
# if change:
if status() != discord.Status.idle:
log.info('Sleeping...')
- yield from set_avatar(db.IDLE_AVATAR)
- yield from set_idle(True)
+ await set_avatar(db.IDLE_AVATAR)
+ await set_idle(True)
db.set_state(client, avatar = db.IDLE_AVATAR, idle = True)
def parse_attachment(attachment, filename = None):
return parsed
-@asyncio.coroutine
-def maybe_say(channel, text, *, attachment = None, embed = None, probability = 0.2, wake = True):
+async def maybe_say(channel, text, *, attachment = None, embed = None, probability = 0.2, wake = True):
if random.random() <= probability:
- yield from client.send_typing(channel)
+ await client.send_typing(channel)
message = None
if attachment is not None:
parsed = parse_attachment(attachment)
if parsed is not None:
- message = yield from client.send_file(channel, parsed['fd'], filename = parsed['filename'], content = text)
+ message = await client.send_file(channel, parsed['fd'], filename = parsed['filename'], content = text)
parsed['fd'].close()
else:
log.warning("Missing or invalid attachment!")
if message is None:
- message = yield from client.send_message(channel, text, embed = embed)
+ message = await client.send_message(channel, text, embed = embed)
if wake:
- yield from wake_up()
+ await wake_up()
return message
else:
log.debug("Didn't bother to say {}".format(text))
return None
-@asyncio.coroutine
-def say(channel, text, *, attachment = None, embed = None, wake = None):
+async def say(channel, text, *, attachment = None, embed = None, wake = None):
args = { 'probability': 1.0 }
if attachment is not None:
args['attachment'] = attachment
args['embed'] = embed
if wake is not None:
args['wake'] = wake
- message = yield from maybe_say(channel, text, **args)
+ message = await maybe_say(channel, text, **args)
return message
-@asyncio.coroutine
-def say_many(channel, lines, *, attachment = None, embed = None, maxlen = 2000):
+async def say_many(channel, lines, *, attachment = None, embed = None, maxlen = 2000):
while len(lines):
message_len = 0
n = 0
# We can't print too big a message.
subset = lines[:n]
message = '\n'.join(subset)
- result = yield from say(channel, message, attachment = attachment, embed = embed)
+ result = await say(channel, message, attachment = attachment, embed = embed)
if not result:
break
lines = lines[len(subset):]
if voice_channel.server in client.servers:
return voice_channel
-@asyncio.coroutine
-def maybe_play_sound(channel, filename, *, probability = 0.05, join = True):
+async def maybe_play_sound(channel, filename, *, probability = 0.05, join = True):
if not channel or not filename:
if join:
log.warning('Missing channel and/or filename for play_sound()')
return False
while get('playing'):
- yield from asyncio.sleep(1)
+ await asyncio.sleep(1)
set('playing', True)
voice = client.voice_client_in(channel.server)
return False
log.debug('Moving to voice channel {}'.format(channel))
if voice is not None:
- yield from client.move_to(channel)
+ await client.move_to(channel)
else:
- yield from client.join_voice_channel(channel)
+ await client.join_voice_channel(channel)
voice = client.voice_client_in(channel.server)
if voice.channel != channel:
log.error("Can't move to voice channel {}".format(channel))
player = voice.create_ffmpeg_player(filename)
player.start()
while not player.is_done():
- yield from asyncio.sleep(1)
+ await asyncio.sleep(1)
set('playing', False)
log.info('Finished playing {} in channel {}'.format(filename, channel))
except:
set('playing', False)
return False
-@asyncio.coroutine
-def play_sound(channel, filename, *, join = True):
- result = yield from maybe_play_sound(channel, filename, probability = 1.0, join = join)
+async def play_sound(channel, filename, *, join = True):
+ result = await maybe_play_sound(channel, filename, probability = 1.0, join = join)
return result
def lower_role_than(member, *, strict = False):
overwrite.update(**args)
return overwrite
-@asyncio.coroutine
-def overwrite_permissions(channel, whom, overwrite, *, strict = True):
+async def overwrite_permissions(channel, whom, overwrite, *, strict = True):
permissions = channel.overwrites_for(whom)
if equal_permissions(permissions.pair(), overwrite.pair(), strict = strict):
log.debug('Permissions for {} in {} are already correct.'.format(whom.name, channel.name))
return
log.info('Setting permissions for {} in {} to {}'.format(whom.name, channel.name, permissions.__dict__))
- yield from client.edit_channel_permissions(channel, whom, overwrite)
+ await client.edit_channel_permissions(channel, whom, overwrite)
-@asyncio.coroutine
-def set_role(member, role, minimum = 1):
+async def set_role(member, role, minimum = 1):
if role is None:
log.warning("Can't find {} role to assign to {}".format(role_name, member.name))
return
return
log.info('Adding {} role to {}'.format(role.name, member.name))
try:
- yield from client.add_roles(member, role)
+ await client.add_roles(member, role)
except discord.errors.Forbidden:
log.warning('Forbidden to add {} role to {}'.format(role.name, member.name))
def digest(text):
return hashlib.sha224(text.encode('utf-8')).hexdigest()
-@asyncio.coroutine
-def say_exception(destination, exception):
- result = yield from say_many(destination, ['```py', str(exception), '```'])
+async def say_exception(destination, exception):
+ result = await say_many(destination, ['```py', str(exception), '```'])
return result
import asyncio
import bot
-@asyncio.coroutine
-def maybe_meow(destination, voice = None, **args):
+async def maybe_meow(destination, voice = None, **args):
result = False
if destination is not None:
- result = yield from bot.maybe_say(destination, 'meow!', **args)
+ result = await bot.maybe_say(destination, 'meow!', **args)
if result and voice is not None:
- yield from bot.play_sound(voice, 'meow.wav', **args)
+ await bot.play_sound(voice, 'meow.wav', **args)
-@asyncio.coroutine
-def meow(destination, voice = None, **extra):
+async def meow(destination, voice = None, **extra):
args = {}
args.update(**extra)
args['probability'] = 1.0
- yield from maybe_meow(destination, voice, **args)
+ await maybe_meow(destination, voice, **args)
-@asyncio.coroutine
-def purr(destination, voice = None, **args):
+async def purr(destination, voice = None, **args):
result = False
if destination is not None:
- result = yield from bot.say(destination, 'purr')
+ result = await bot.say(destination, 'purr')
if result and voice is not None:
- yield from bot.play_sound(voice, 'purr.wav', **args)
+ await bot.play_sound(voice, 'purr.wav', **args)
-@asyncio.coroutine
-def hiss(destination, **args):
- yield from bot.say(destination, 'hiss!', **args)
+async def hiss(destination, **args):
+ await bot.say(destination, 'hiss!', **args)
-@asyncio.coroutine
-def yelp(destination, **args):
- yield from bot.say(destination, 'yelp!', **args)
+async def yelp(destination, **args):
+ await bot.say(destination, 'yelp!', **args)
-@asyncio.coroutine
-def shrug(destination, **args):
- yield from bot.say(destination, '*shrugs*', **args)
+async def shrug(destination, **args):
+ await bot.say(destination, '*shrugs*', **args)
-@asyncio.coroutine
-def maybe_zzz(destination, **args):
- yield from bot.maybe_say(destination, 'zzz', **args)
+async def maybe_zzz(destination, **args):
+ await bot.maybe_say(destination, 'zzz', **args)
-@asyncio.coroutine
-def zzz(destination, **extra):
+async def zzz(destination, **extra):
args = {}
args.update(**extra)
args['probability'] = 1.0
args['wake'] = False
- yield from maybe_zzz(destination, **args)
+ await maybe_zzz(destination, **args)