Ruby-Cogs/shop/inventory.py

97 lines
3.7 KiB
Python

import asyncio
import discord
from redbot.core.utils.chat_formatting import box
from .menu import MenuCheck
class Inventory:
def __init__(self, ctx, data):
self.ctx = ctx
self.data = data
async def display(self):
msg, groups = await self.setup()
try:
return await self.inv_loop(groups, msg)
except asyncio.TimeoutError:
await msg.delete()
await self.ctx.send("Menu timed out.")
raise RuntimeError
except ExitMenu:
await self.ctx.send("Exited inventory.")
raise RuntimeError
async def setup(self, groups=None, page=0, msg=None):
if not groups:
groups = self.splitter()
options = self.update(groups, page)
embed = self.build_embed(options, page, groups)
if msg:
await msg.edit(embed=embed)
else:
msg = await self.ctx.send(embed=embed)
return msg, groups
async def inv_loop(self, groups, msg):
page = 0
maximum = len(groups) - 1
while True:
check = MenuCheck(self.ctx, groups, page, maximum)
choice = await self.ctx.bot.wait_for("message", timeout=35.0, check=check.predicate)
if choice.content.isdigit() and int(choice.content) in range(1, len(groups[page]) + 1):
try:
await choice.delete()
await msg.delete()
except (discord.NotFound, discord.Forbidden):
pass
return groups[page][int(choice.content) - 1][0]
elif choice.content.lower() in (">", "n", "next"):
page += 1
elif choice.content.lower() in ("b", "<", "back"):
page -= 1
elif choice.content.lower() in ("e", "x", "exit"):
try:
await choice.delete()
await msg.delete()
except (discord.NotFound, discord.Forbidden):
pass
raise ExitMenu
elif choice.content.lower() in ("p", "prev"):
continue
else:
msg, _ = await self.setup(groups=groups, page=page, msg=msg)
await msg.edit(embed=msg)
msg, _ = await self.setup(groups=groups, page=page, msg=msg)
def splitter(self):
return [self.data[i : i + 5] if len(self.data) > 5 else self.data for i in range(0, len(self.data), 5)]
def update(self, groups, page=0):
header = f"{'#':<3} {'Items':<29} {'Qty':<7} {'Type':<8}\n{'--':<3} {'-'*29:<29} {'-'*4:<7} {'-'*8:<8}"
fmt = [header]
for idx, x in enumerate(groups[page], 1):
line_one = f"{f'{idx}.': <{3}} {x[0]: <{28}s} {x[1]['Qty']: < {9}}{x[1]['Type']: <{7}s}"
fmt.append(line_one)
fmt.append(f'< {x[1]["Info"][:50]} >' if len(x[1]["Info"]) < 50 else f'< {x[1]["Info"][:47]}... >')
fmt.append("",)
return box("\n".join(fmt), lang="md")
def build_embed(self, options, page, groups):
title = "{}'s Inventory".format(self.ctx.author.name)
footer = "You are viewing page {} of {}.".format(page + 1 if page > 0 else 1, len(groups))
instructions = (
"Type the number for your selection or one of the words below "
"for page navigation if there are multiple pages available.\n"
"Next page: Type n, next, or >\n"
"Previous page: Type b, back, or <\n"
"Exit menu system: Type e, x, or exit"
)
embed = discord.Embed(color=0x5EC6FF)
embed.add_field(name=title, value=options, inline=False)
embed.set_footer(text="\n".join((instructions, footer)))
return embed
class ExitMenu(Exception):
pass