From 67f5d5e8e6323495969d761d8222417ec44dee75 Mon Sep 17 00:00:00 2001 From: CMDR furrycat Date: Wed, 28 Sep 2016 15:59:58 +0100 Subject: [PATCH] Sleep when idle and wake on activity. --- bot.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/bot.py b/bot.py index f144909..05b1c13 100755 --- a/bot.py +++ b/bot.py @@ -13,6 +13,7 @@ import pexpect import random import re import sys +import time from PIL import Image dryrun = os.getenv('DRYRUN') is not None @@ -85,10 +86,52 @@ def wait_for_prompt(p): p.expect('EDI> ') @asyncio.coroutine +def set_avatar(url): + if re.match(r'!https?:', url): + fd = open_url(url) + else: + fd = open(url, 'rb') + if fd is None: + log.debug('Failed to open URL {} for avatar'.format(url)) + return False + try: + yield from client.edit_profile(avatar = fd.read()) + fd.close() + return True + except: + fd.close() + raise + return False + +@asyncio.coroutine +def set_idle(idle): + yield from client.change_status(idle = idle) + +@asyncio.coroutine +def wake_up(force = False): + for server in client.servers: + if force or server.me.status != discord.Status.online: + log.info('Waking up...') + yield from set_avatar('avatar_online.png') + yield from set_idle(False) + awake_since = time.time() + break + +@asyncio.coroutine +def zzz(): + for server in client.servers: + if server.me.status != discord.Status.idle: + log.info('Sleeping...') + yield from set_avatar('avatar_idle.png') + yield from set_idle(True) + break + +@asyncio.coroutine def maybe_say(channel, text, probability = 0.2): if random.random() <= probability: yield from client.send_typing(channel) yield from client.send_message(channel, text) + yield from wake_up() return True else: log.debug("Didn't bother to say {}".format(text)) @@ -103,7 +146,7 @@ def say(channel, text): def say_expect(message, stdout): if stdout: log.debug(stdout) - yield from client.send_message(message.channel, '{}```{}```'.format('{} '.format(message.author.mention) if not message.channel.is_private else '', stdout)) + yield from say(message.channel, '{}```{}```'.format('{} '.format(message.author.mention) if not message.channel.is_private else '', stdout)) else: yield from say(message.channel, 'Sorry!') @@ -353,7 +396,7 @@ def greet(channel, member): if dryrun: log.info('Not sending greeting {}'.format(message)) else: - yield from client.send_message(channel, message) + yield from say(channel, message) @asyncio.coroutine def set_rss_permissions(feed): @@ -362,7 +405,7 @@ def set_rss_permissions(feed): log.warning("Can't get channel {} for feed {}.".format(feed['channel'], feed['url'])) return role = None - for server_role in channel.server.get_member(client.user.id).roles: + for server_role in channel.server.me.roles: if server_role.name == 'Robocat': role = server_role break @@ -420,7 +463,7 @@ def do_rss(feed): log.info('Dryrun: Not posting to {}: {}'.format(channel, formatted)) else: log.info('Posting to {}: {}'.format(channel, formatted)) - message = yield from client.send_message(channel, formatted) + message = yield from say(channel, formatted) digest = hashlib.sha224(message.content.encode('utf-8')).hexdigest() digests.append(digest) log.debug('Posted RSS with digest {}'.format(digest)) @@ -435,6 +478,17 @@ def do_feeds(feeds): yield from do_rss(feed) yield from asyncio.sleep(rsstime) +@asyncio.coroutine +def maybe_sleep(): + while True: + for server in client.servers: + if server.me.status != discord.Status.idle: + now = time.time() + if now - last_spoke >= idletime: + yield from zzz() + break + yield from asyncio.sleep(60) + p = pexpect.spawnu('./edi.py') wait_for_prompt(p) @@ -461,6 +515,9 @@ modules = { } } +idletime = 7200 + +last_spoke = time.time() client = discord.Client() @asyncio.coroutine @@ -505,6 +562,7 @@ def should_greet_member_in(channel, member, role_name = 'Unassigned', minimum = def on_ready(): print('Logged in as {}#{}'.format(client.user.name, client.user.id)) print('Admins are: {}'.format(admins)) + yield from wake_up(True) channels = yield from channels_to_greet() print('Greeting in {}'.format([channel.name for channel in channels])) for channel in channels: @@ -518,7 +576,8 @@ def on_ready(): log.debug('Maybe unassigning {}'.format(member.name)) yield from set_unassigned(member) print('RSS feeds: {}'.format([feed['description'] for feed in feeds if 'description' in feed])) - yield from do_feeds(feeds) + asyncio.async(do_feeds(feeds)) + asyncio.async(maybe_sleep()) @client.event @asyncio.coroutine -- 2.7.4