mirror of
https://github.com/UiO-Gaming/ShiteMusicBot.git
synced 2026-11-06 14:24:30 +01:00
192 lines
6.2 KiB
Python
192 lines
6.2 KiB
Python
import asyncio
|
|
import discord
|
|
import math
|
|
import lavalink
|
|
|
|
class CantScroll(Exception):
|
|
pass
|
|
|
|
# Maybe slightly very copied from rdanny
|
|
# Thanks danny <3
|
|
|
|
class EmbedScroller:
|
|
def __init__(self, ctx, pages):
|
|
|
|
self.bot = ctx.bot
|
|
self.pages = pages
|
|
self.cmdmsg = ctx.message
|
|
self.message = ctx.message
|
|
self.channel = ctx.channel
|
|
self.author = ctx.author
|
|
|
|
if len(self.pages) > 1:
|
|
self.scrolling = True
|
|
else:
|
|
self.scrolling = False
|
|
self.reaction_emojis = [
|
|
('\N{BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', self.first_page),
|
|
('\N{BLACK LEFT-POINTING TRIANGLE}', self.previous_page),
|
|
('\N{BLACK RIGHT-POINTING TRIANGLE}', self.next_page),
|
|
('\N{BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', self.last_page),
|
|
('❌', self.stop_scrolling),
|
|
]
|
|
|
|
if ctx.guild is not None:
|
|
self.permissions = self.channel.permissions_for(ctx.guild.me)
|
|
else:
|
|
self.permissions = self.channel.permissions_for(ctx.bot.user)
|
|
|
|
if not self.permissions.embed_links:
|
|
raise CantScroll('Bot does not have embed links permission.')
|
|
|
|
if not self.permissions.send_messages:
|
|
raise CantScroll('Bot cannot send messages.')
|
|
|
|
if self.scrolling:
|
|
# verify we can actually use the pagination session
|
|
if not self.permissions.add_reactions:
|
|
raise CantScroll('Bot does not have add reactions permission.')
|
|
|
|
if not self.permissions.read_message_history:
|
|
raise CantScroll('Bot does not have Read Message History permission.')
|
|
|
|
async def send(self):
|
|
self.current_page = 0
|
|
# No embeds to scroll through
|
|
if not self.pages:
|
|
return
|
|
|
|
if not self.scrolling:
|
|
return await self.channel.send(embed=self.pages[0])
|
|
|
|
self.message = await self.channel.send(embed=self.pages[0])
|
|
for (reaction, _) in self.reaction_emojis:
|
|
if len(self.pages) == 2 and reaction in ('\u23ed', '\u23ee'):
|
|
continue
|
|
|
|
await self.message.add_reaction(reaction)
|
|
|
|
async def scroll(self, page):
|
|
if page < 0 or page >= len(self.pages):
|
|
return
|
|
self.current_page = page
|
|
await self.message.edit(embed=self.pages[page])
|
|
|
|
async def first_page(self):
|
|
await self.scroll(0)
|
|
|
|
async def last_page(self):
|
|
await self.scroll(len(self.pages) - 1)
|
|
|
|
async def next_page(self):
|
|
await self.scroll(self.current_page + 1)
|
|
|
|
async def previous_page(self):
|
|
await self.scroll(self.current_page - 1)
|
|
|
|
async def stop_scrolling(self):
|
|
self.scrolling = False
|
|
await self.message.delete()
|
|
await self.cmdmsg.delete()
|
|
|
|
def react_check(self, reaction, user):
|
|
if user is None or user.id != self.author.id:
|
|
return False
|
|
|
|
if reaction.message.id != self.message.id:
|
|
return False
|
|
|
|
for (emoji, func) in self.reaction_emojis:
|
|
if reaction.emoji == emoji:
|
|
self.match = func
|
|
return True
|
|
return False
|
|
|
|
async def start_scrolling(self):
|
|
if not self.scrolling:
|
|
await self.send()
|
|
else:
|
|
self.bot.loop.create_task(self.send())
|
|
|
|
while self.scrolling:
|
|
try:
|
|
reaction, user = await self.bot.wait_for('reaction_add', check=self.react_check, timeout=120.0)
|
|
except asyncio.TimeoutError:
|
|
self.scrolling = False
|
|
try:
|
|
await self.message.clear_reactions()
|
|
except:
|
|
pass
|
|
finally:
|
|
break
|
|
|
|
try:
|
|
await self.message.remove_reaction(reaction, user)
|
|
except:
|
|
pass
|
|
|
|
await self.match()
|
|
|
|
|
|
class ScrollerFromLines(EmbedScroller):
|
|
def __init__(self, ctx, description, lines, lines_per_page=10):
|
|
pagecount = math.ceil(len(lines) / lines_per_page)
|
|
pages = []
|
|
page = ''
|
|
for index, line in enumerate(lines):
|
|
page += line + '\n'
|
|
if index%lines_per_page == lines_per_page - 1:
|
|
embed = discord.Embed(color=0xEFD26C,
|
|
title=description,
|
|
description=page)
|
|
embed.set_footer(text=f'Viewing page {index//lines_per_page}/{pagecount}')
|
|
pages.append(embed)
|
|
page = ''
|
|
|
|
if page != '':
|
|
embed = discord.Embed(color=0xEFD26C,
|
|
description=page)
|
|
|
|
embed.set_footer(text=f'Viewing page {pagecount}/{pagecount}')
|
|
pages.append(embed)
|
|
|
|
super().__init__(ctx=ctx, pages=pages)
|
|
|
|
|
|
class QueueScroller(EmbedScroller):
|
|
""" Fugly, but works for now """
|
|
def __init__(self, ctx, queue, lines_per_page=10, user_name: str=None):
|
|
|
|
pagecount = math.ceil(len(queue) / lines_per_page)
|
|
|
|
if user_name is None:
|
|
title = f'**Queue** `{len(queue)} songs`'
|
|
else:
|
|
title = f'**{user_name}\'s queue** `{len(queue)} songs`'
|
|
pages = []
|
|
page = ''
|
|
for index, temp in enumerate(queue):
|
|
if user_name is None:
|
|
track = temp
|
|
page += f'`{index + 1}.` **[{track.title}]({track.uri})** _by <@{track.requester}>_\n'
|
|
else:
|
|
track, globpos = temp
|
|
page += f'`{index + 1}({globpos + 1}).` **[{track.title}]({track.uri})**\n'
|
|
|
|
if index%lines_per_page == lines_per_page - 1:
|
|
embed = discord.Embed(color=0xEFD26C,
|
|
title=title,
|
|
description=page)
|
|
embed.set_footer(text=f'Viewing page {index//lines_per_page + 1}/{pagecount}')
|
|
pages.append(embed)
|
|
page = ''
|
|
|
|
if page != '':
|
|
embed = discord.Embed(color=0xEFD26C,
|
|
title=title,
|
|
description=page)
|
|
embed.set_footer(text=f'Viewing page {pagecount}/{pagecount}')
|
|
pages.append(embed)
|
|
|
|
super().__init__(ctx=ctx, pages=pages)
|