Created
April 1, 2017 22:40
-
-
Save Jan200101/0e2a90fc8444a33a5fcd81066c4e4b91 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
import pagify | |
class ReactionGui(): | |
def __init__(self): | |
self.logger = logging.getLogger("red") | |
async def interactive_results(self, ctx, results, single_msg=True,): | |
author = ctx.message.author | |
channel = ctx.message.channel | |
if single_msg: | |
choices = OrderedDict((('◀', 'prev'), | |
('❌', 'close'), | |
('▶', 'next'))) | |
else: | |
choices = OrderedDict((('❌', 'close'), | |
('🔽', 'next'))) | |
nbs = '' | |
discord_fmt = nbs + '```py\n{}\n```' | |
prompt = (" Output too long. Navigate pages with ({})" | |
.format('/'.join(choices.values()))) | |
pages = [p for p in pagify(results, ['\n', ' '], | |
page_length=1500)] | |
# results is not a generator, so no reason to keep this as one | |
pages = [discord_fmt.format(p) + 'pg. {}/{}' | |
.format(c + 1, len(pages)) | |
for c, p in enumerate(pages)] | |
pages[0] += prompt | |
choice = 'next' | |
page_num = 0 | |
dirs = {'next': 1, 'prev': -1} | |
msgs = [] | |
while choice: | |
msg = await self.display_page(pages[page_num], channel, choices, | |
msgs, single_msg) | |
choice = await self.wait_for_interaction(msg, author, choices) | |
if choice == 'close': | |
try: | |
await self.bot.delete_messages(msgs) | |
except: # selfbots | |
for m in msgs: | |
await self.bot.delete_message(m) | |
break | |
if choice in dirs: | |
page_num = (page_num + dirs[choice]) % len(pages) | |
if choice is None: | |
await self.remove_reactions(msgs.pop()) | |
async def display_page(self, page, channel, emojis, msgs, overwrite_prev): | |
if msgs and overwrite_prev: | |
msg = msgs.pop() | |
embed = msg.embeds[0] if len(msg.embeds) else None | |
msg = await self.bot.edit_message(msg, new_content=page, embed=embed) | |
else: | |
send_msg = self.bot.send_message(channel, page) | |
if msgs: | |
# refresh msg | |
prv_msg = await self.bot.get_message(channel, msgs[len(msgs) - 1].id) | |
tasks = (send_msg, self.remove_reactions(prv_msg)) | |
results = await asyncio.gather(*tasks, return_exceptions=True) | |
msg = results[0] | |
else: | |
msg = await send_msg | |
try: | |
async def add_emojis(m, es): | |
try: | |
for e in es: # we want these to be in order | |
await self.bot.add_reaction(m, e) | |
except discord.errors.NotFound: | |
# was deleted before we could react | |
pass | |
# but we don't want to wait | |
self.bot.loop.create_task(add_emojis(msg, emojis)) | |
except: | |
pass | |
msgs.append(msg) | |
return msg | |
async def wait_for_interaction(self, msg, author, choices: OrderedDict, | |
timeout=120, delete_msg=True, | |
match_first_char=True): | |
"""waits for a message or reaction add/remove | |
If the response is a msg, | |
schedules msg deletion it if delete_msg | |
also match 1 character msgs to the choice if match_first_char | |
""" | |
emojis = tuple(choices.keys()) | |
words = tuple(choices.values()) | |
first_letters = {w[0]: w for w in words} | |
def mcheck(msg): | |
lm = msg.content.lower() | |
return (lm in words or | |
(match_first_char and lm in first_letters)) | |
tasks = (self.bot.wait_for_message(author=author, timeout=timeout, | |
channel=msg.channel, check=mcheck), | |
self.bot.wait_for_reaction(user=author, timeout=timeout, | |
message=msg, emoji=emojis), | |
self.wait_for_reaction_remove(user=author, timeout=timeout, | |
message=msg, emoji=emojis)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment