Merge branch 'helpformatter' into 'dev'

Helpformatter

See merge request Ev-1/shite-music-bot!16
This commit is contained in:
Ev-1 committed 2019-03-03 16:24:18 +00:00
commit 23f0f093aa
20 files changed
+900 -357

No files matched your search

+7 -12
View File
@@ -12,6 +12,8 @@ from cogs.utils.localizer import Localizer
from cogs.utils.localizer import LocalizerWrapper
from cogs.utils.alias import Aliaser
from cogs.utils.context import Context
from cogs.helpformatter import commandhelper
from cogs.utils.paginator import Scroller
with codecs.open("data/config.yaml", 'r', encoding='utf8') as f:
@@ -21,7 +23,8 @@ with codecs.open("data/config.yaml", 'r', encoding='utf8') as f:
initial_extensions = [
'cogs.cogs',
'cogs.settings',
'cogs.misc'
'cogs.misc',
'cogs.helpformatter'
]
@@ -58,15 +61,9 @@ class Bot(commands.Bot):
if not self.debug:
if (isinstance(err, commands.MissingRequiredArgument) or
isinstance(err, commands.BadArgument)):
formatter = ctx.bot.formatter
if ctx.invoked_subcommand is None:
_help = await formatter.format_help_for(ctx, ctx.command)
else:
_help = await formatter.format_help_for(ctx,
ctx.invoked_subcommand)
for message in _help:
await ctx.send(message)
paginator = commandhelper(ctx, ctx.command, ctx.invoker)
scroller = Scroller(ctx, paginator)
await scroller.start_scrolling()
if isinstance(err, commands.CommandInvokeError):
pass
@@ -94,8 +91,6 @@ class Bot(commands.Bot):
# Replace aliases with commands
ctx = self.aliaser.get_command(ctx)
if ctx.command and isinstance(ctx.command, commands.GroupMixin):
ctx = self.aliaser.get_subcommand(ctx, ctx.command, [str(ctx.command)])
# Add the localizer
if ctx.command and ctx.command.cog_name:
+1 -1
View File
@@ -10,7 +10,7 @@ class Cogs(commands.Cog):
self.bot = bot
self.settings = self.bot.settings
@commands.group(name='cogs')
@commands.group(name='cogs', hidden=True)
@checks.is_owner()
async def _cogs(self, ctx):
if ctx.invoked_subcommand is None:
+111
View File
@@ -0,0 +1,111 @@
# NOTICE: Before you copy this example, be sure you understand what all this does. Remember: This is a gist, not a github file meaning
# you can't pip install this, you would need to put this into a new file and add it to your cog list.
import pprint
import discord
import asyncio
from discord.ext import commands
from cogs.utils.paginator import HelpPaginator, Scroller
def get_cmd_dict(ctx, qualified_name):
split = qualified_name.split()
cmd_dict = ctx.bot.aliaser.get_cmd_help(ctx.locale, split[-1], split[:-1])
return cmd_dict
def helper(ctx):
bot = ctx.bot
# Display music commands first
music = bot.get_cog('Music')
paginator = coghelper(ctx, music)
for cog in bot.cogs.copy().values():
if cog.__cog_name__ is 'Music':
continue
cogpaignator = coghelper(ctx, cog)
paginator.append_paginator(cogpaignator)
paginator.add_page_indicator(ctx.localizer, "{pageindicator}", ctx.prefix)
return paginator
def coghelper(ctx, cog, ignore_subcommands=True):
paginator = HelpPaginator(max_size=5000, max_fields=5, color=ctx.me.color, title=cog.__cog_name__)
for cmd in cog.walk_commands():
if ignore_subcommands:
if len(cmd.qualified_name.split()) > 1:
continue
if cmd.hidden:
continue
cmd_dict = get_cmd_dict(ctx, cmd.qualified_name)
paginator.add_command_field(cmd_dict)
paginator.add_page_indicator(ctx.localizer, "{paginator}", ctx.prefix)
return paginator
def commandhelper(ctx, command, invoker, include_subcmd=True):
cmd_dict = get_cmd_dict(ctx, command.qualified_name)
prefix = ctx.prefix
if invoker.split()[:-1]:
prefix += ' '.join(invoker.split()[:-1]) + ' '
aliases = cmd_dict.get('aliases', [])
args = cmd_dict.get('args', '')
description = cmd_dict.get('description', '')
sub_commands = cmd_dict.get('sub_commands', [])
if len(aliases) > 1:
cmd = prefix + '[' + '|'.join([str(a) for a in aliases]) + '] '
else:
cmd = prefix + '|'.join([str(a) for a in aliases]) + ' '
cmd += args
if not sub_commands:
paginator = HelpPaginator(max_size=5000, max_fields=5, color=ctx.me.color, title=cmd, description=description)
paginator.force_close_page()
return paginator
description = f"```{description}```"
paginator = HelpPaginator(max_size=5000, max_fields=5, color=ctx.me.color, title=cmd, description=description)
for sub_command, sub_cmd_dict in sub_commands.items():
paginator.add_command_field(sub_cmd_dict)
paginator.add_page_indicator(ctx.localizer, "{pageindicator}", ctx.prefix)
return paginator
class Help(commands.Cog):
"""Help command"""
def __init__(self, bot):
self.bot = bot
@commands.command(hidden=True)
async def help(self, ctx): # Takes no args because reasons(using the view directly)
ctx.view.skip_ws()
v = ctx.view
invoker = v.buffer[v.index:v.end]
ctx = self.bot.aliaser.get_subcommand(ctx, group=None, parents=[])
command = v.buffer[v.index:v.end]
if not command:
scroller = Scroller(ctx, helper(ctx))
await scroller.start_scrolling()
if command:
thing = ctx.bot.get_cog(command) or ctx.bot.get_command(command)
if not thing:
return await ctx.send(f'Looks like "{command}" is not a command or category.')
if isinstance(thing, commands.Command):
paginator = commandhelper(ctx, thing, invoker)
scroller = Scroller(ctx, paginator)
await scroller.start_scrolling()
else:
scroller = Scroller(ctx, coghelper(ctx, thing))
await scroller.start_scrolling()
def setup(bot):
bot.remove_command("help")
bot.add_cog(Help(bot))
+1
View File
@@ -9,6 +9,7 @@ from discord.ext import commands
from cogs.utils import checks
from lavalink import __version__ as LavalinkVersion
class Misc(commands.Cog):
def __init__(self, bot):
self.bot = bot
+7 -4
View File
@@ -15,7 +15,7 @@ from typing import Optional
from .utils import checks, RoxUtils, timeformatter
from .utils.mixplayer import MixPlayer
from .utils.embedscroller import QueueScroller
from .utils.paginator import QueuePaginator, Scroller
time_rx = re.compile('[0-9]+')
@@ -220,7 +220,8 @@ class Music(commands.Cog):
if user is None:
queue = player.global_queue()
scroller = QueueScroller(ctx, queue, ctx.localizer, lines_per_page=10)
pagified_queue = QueuePaginator(ctx.localizer, queue, color=ctx.me.color)
scroller = Scroller(ctx, pagified_queue)
await scroller.start_scrolling()
else:
@@ -228,7 +229,8 @@ class Music(commands.Cog):
if not user_queue:
return await ctx.send(ctx.localizer.format_str("{queue.empty}", _user=user.name))
scroller = QueueScroller(ctx, user_queue, ctx.localizer, lines_per_page=10, user_name=user.name)
pagified_queue = QueuePaginator(ctx.localizer, user_queue, color=ctx.me.color, user_name=ctx.author.name)
scroller = Scroller(ctx, pagified_queue)
await scroller.start_scrolling()
@commands.command(name='myqueue')
@@ -240,7 +242,8 @@ class Music(commands.Cog):
if not user_queue:
return await ctx.send(ctx.localizer.format_str("{my_queue}"))
scroller = QueueScroller(ctx, user_queue, ctx.localizer, lines_per_page=10, user_name=ctx.author.name)
pagified_queue = QueuePaginator(ctx.localizer, user_queue, color=ctx.me.color, user_name=ctx.author.name)
scroller = Scroller(ctx, pagified_queue)
await scroller.start_scrolling()
@commands.command(name='pause')
+1 -1
View File
@@ -105,7 +105,7 @@ class Settings(commands.Cog):
await ctx.send(embed=embed)
@commands.guild_only()
@_set.command(name='listenchannels')
@_set.command(name='listenchannels', hidden=True)
async def set_listen_voice(self, ctx, *channels: discord.VoiceChannel):
if channels:
channel_ids = [channel.id for channel in channels]
+42 -6
View File
@@ -6,6 +6,12 @@ from os import path
from discord.ext import commands
"""
Not the prettiest this, works by replacing any found aliases in a command string with the actual command names.
Allows per guild aliases of subcommands without doing anything to discord.py itself. Suggestions of better/correct
ways of doing this appreciated.
"""
class Aliaser:
def __init__(self, localization_folder, default_lang):
self.localization_folder = path.realpath(localization_folder)
@@ -39,7 +45,7 @@ class Aliaser:
def load_localizations(self):
for lang in self.localization_table.keys():
with open(path.join(self.localization_folder, lang, "aliases.yaml"), "r", encoding='utf-8') as f:
with open(path.join(self.localization_folder, lang, "commands.yaml"), "r", encoding='utf-8') as f:
data = yaml.load(f)
self.localization_table[lang] = {'aliases': data, 'commands': self._gen_alias_dict(data)}
@@ -66,9 +72,27 @@ class Aliaser:
return command
return default
def get_alias(self, locale, command):
def get_cmd_help(self, locale, command=None, parents=[]):
""" Fetches the command info dictionary """
locale = self.localization_table[locale]
return locale['aliases'].get(command, [])
def traverse(command_tree, parents, command):
# Return the command when no more parents exist
if not parents:
return command_tree.get(command, [])
parent = command_tree.get(parents.pop(0), None)
if not parent:
return []
command_tree = parent.get('sub_commands', [])
if not command_tree:
return None
return traverse(command_tree, parents, command)
command_tree = locale['aliases']
if command:
return traverse(command_tree, parents, command)
return command_tree
def get_command(self, ctx):
""" Get a top level command. """
@@ -76,13 +100,22 @@ class Aliaser:
ctx.command = None
return ctx
ctx.view.undo()
ctx.invoker = invoker = ctx.view.buffer[ctx.view.index:ctx.view.end]
alias = ctx.view.get_word()
command = self.convert_alias(ctx.locale, alias, alias)
ctx.invoked_with = command
ctx.command = ctx.bot.all_commands.get(command)
if ctx.command and isinstance(ctx.command, commands.GroupMixin):
ctx = self.get_subcommand(ctx, ctx.command, [str(ctx.command)])
return ctx
def get_subcommand(self, ctx, group, parents=[]):
def _replace_command(self, view, index, alias, command):
buf = view.buffer
changed = buf[index:]
view.buffer = buf[:index] + changed.replace(alias, command, 1)
return view
def get_subcommand(self, ctx, group=None, parents=[]):
""" Recursicely replaces all subcommand aliases with subcommands."""
view = ctx.view
prev = view.previous
@@ -96,7 +129,7 @@ class Aliaser:
parents.append(subcmd)
# Replace the alias in the command
view.buffer = view.buffer.replace(alias, subcmd)
self._replace_command(view, idx, alias, subcmd)
# Update the view to account for difference in length
strdiff = len(subcmd) - len(alias)
@@ -104,7 +137,10 @@ class Aliaser:
view.index += strdiff
# Get the subcommand
sub = group.all_commands.get(subcmd, None)
if group:
sub = group.all_commands.get(subcmd, None)
else:
sub = ctx.bot.all_commands.get(subcmd, None)
# Translate any subsubcommands
if sub and isinstance(sub, commands.GroupMixin):
-220
View File
@@ -1,220 +0,0 @@
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=localizer.format_str("{queue.pageindicator}",
_current=index//lines_per_page + 1,
_total=pagecount))
pages.append(embed)
page = ''
if page != '':
embed = discord.Embed(color=0xEFD26C,
description=page)
embed.set_footer(text=localizer.format_str("{queue.pageindicator}",
_current=pagecount,
_total=pagecount))
pages.append(embed)
super().__init__(ctx=ctx, pages=pages)
class QueueScroller(EmbedScroller):
""" Fugly, but works for now """
def __init__(self, ctx, queue, localizer, lines_per_page=10, user_name: str=None):
pagecount = math.ceil(len(queue) / lines_per_page)
self.queue = queue
if user_name is None:
title = localizer.format_str("{queue.length}",
_length=len(queue))
else:
title = localizer.format_str("{queue.userqueue}",
_user=user_name,
_length=len(queue))
pages = []
page = ''
for index, temp in enumerate(queue):
if user_name is None:
track = temp
page += localizer.format_str("{queue.globaltrack}",
_index=index+1,
_title=track.title,
_uri=track.uri,
_user_id=track.requester)
else:
track, globpos = temp
page += localizer.format_str("{queue.usertrack}",
_index=index+1,
_globalindex=globpos+1,
_title=track.title,
_uri=track.uri)
if index % lines_per_page == lines_per_page - 1:
embed = discord.Embed(color=0xEFD26C,
title=title,
description=page)
embed.set_footer(text=localizer.format_str("{queue.pageindicator}",
_current=index//lines_per_page + 1,
_total=pagecount))
pages.append(embed)
page = ''
if page != '':
embed = discord.Embed(color=0xEFD26C,
title=title,
description=page)
embed.set_footer(text=localizer.format_str("{queue.pageindicator}",
_current=pagecount,
_total=pagecount))
pages.append(embed)
super().__init__(ctx=ctx, pages=pages)
async def scroll(self, page):
# overwrite to add ability to update queue length/add scrubber.
if page < 0 or page >= len(self.pages):
return
self.current_page = page
await self.message.edit(embed=self.pages[page])
+1 -1
View File
@@ -52,7 +52,7 @@ class Localizer:
self.localization_table[lang] = {}
l_table = self.localization_table[lang]
for file in glob(path.join(self.localization_folder, lang, "*.yaml")):
if 'aliases' in file:
if 'aliases' in file or 'commands' in file:
continue
file_base = path.basename(file).split(".")[0]
with open(file, "r", encoding='utf-8') as f:
+285
View File
@@ -0,0 +1,285 @@
import discord
import asyncio
class CantScroll(Exception):
pass
class BasePaginator:
def __init__(self, max_size=2000, max_units=10):
self._pages = []
self._current_page_size = 0
self._current_units = 0
self._max_size = max_size
self._max_units = max_units
def close_page(self):
pass
def add_page_indicator(self, localizer, localizer_str=None, prefix=None):
self.close_page()
if localizer_str:
for i, page in enumerate(self._pages, start=1):
page.set_footer(text=localizer.format_str(localizer_str,
_current=i,
_total=len(self._pages),
_prefix=prefix))
else:
for i, page in enumerate(self._pages, start=1):
page.set_footer(text=f"{i}/{len(self._pages)}")
def append_paginator(self, paginator):
if not isinstance(paginator, BasePaginator):
raise TypeError('Pageinator needs to be a subclass of BasePaginator.')
self.close_page()
for page in paginator.pages:
self.pages.append(page)
@property
def pages(self):
if self._current_page_size > 0:
self.close_page()
return self._pages
class TextPaginator(BasePaginator):
def __init__(self, max_size=2000, max_lines=10, **embed_base):
super().__init__(max_size=max_size, max_units=max_lines)
self._current_page = []
self.embed_base = embed_base
def close_page(self):
if self._current_page_size > 0:
embed = discord.Embed(**self.embed_base)
embed.description = '\n'.join(self._current_page)
self._pages.append(embed)
self._current_page_size = 0
self._current_units = 0
self._current_page = []
def add_line(self, line='', *, empty=False):
if len(line) > self._max_size:
raise RuntimeError(f'Line exceeds maximum page size {self._max_size}')
if self._current_page_size + len(line) + 1 > self._max_size:
self.close_page()
if self._current_units >= self._max_units:
self.close_page()
self._current_page_size += len(line) + 1
self._current_units += 1
self._current_page.append(line)
if empty:
self._current_page.append('')
self._current_page_size += 1
class FieldPaginator(BasePaginator):
def __init__(self, max_size=5000, max_fields=8, **embed_base):
super().__init__(max_size=max_size, max_units=max_fields)
self._embed_base = embed_base
self._current_page = discord.Embed(**self._embed_base)
def close_page(self):
if self._current_page_size > 0:
self._pages.append(self._current_page)
self._current_page_size = 0
self._current_units = 0
self._current_page = discord.Embed(**self._embed_base)
def add_field(self, name, value, inline=False):
field = {"name": name, "value": value}
fieldsize = sum([len(val) for _, val in field.items()])
if len(name) > 256 or len(value) > 1024:
raise RuntimeError(f'Maximum field size exceeded, max name length: 256. max value length: 1024.')
if self._current_page_size + fieldsize > self._max_size:
self.close_page()
if self._current_units >= self._max_units:
self.close_page()
field["inline"] = inline
self._current_page_size += fieldsize
self._current_units += 1
self._current_page.add_field(**field)
class QueuePaginator(TextPaginator):
def __init__(self, localizer, queue, color, user_name: str=None):
self.localizer = localizer
self.queue = queue
if user_name is None:
title = localizer.format_str("{queue.length}",
_length=len(queue))
else:
title = localizer.format_str("{queue.userqueue}",
_user=user_name,
_length=len(queue))
super().__init__(max_lines=10, **{"color": color, "title": title})
for index, temp in enumerate(queue):
if user_name is None:
track = temp
queued_track = localizer.format_str("{queue.globaltrack}", _index=index+1,
_title=track.title, _uri=track.uri,
_user_id=track.requester)
else:
track, globpos = temp
queued_track = localizer.format_str("{queue.usertrack}", _index=index+1,
_globalindex=globpos+1, _title=track.title,
_uri=track.uri)
self.add_line(queued_track)
self.add_page_indicator(self.localizer, "{queue.pageindicator}")
class HelpPaginator(FieldPaginator):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def force_close_page(self):
self._pages.append(self._current_page)
self._current_page_size = 0
self._current_units = 0
self._current_page = discord.Embed(**self._embed_base)
def add_command_field(self, cmd_dict):
if not isinstance(cmd_dict, dict):
return
aliases = cmd_dict.get('aliases', [])
args = cmd_dict.get('args', '')
description = cmd_dict.get('description', '')
cmd = str(aliases[0])
cmd += ' ' + args
self.add_field(name=cmd, value=description, inline=False)
# Maybe slightly very copied from rdanny
# Thanks danny <3
class Scroller:
def __init__(self, ctx, paginator):
self.bot = ctx.bot
self.pages = paginator.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()
-63
View File
@@ -1,63 +0,0 @@
# Aliases for each of the commands in the the bot(except the forgotten onces.)
# Aliases without subcommands don't need to have "aliases:", specified.
# For commands with subcommands you need to have one subcategory called aliases and one called subcommands.
# Music
play: [p]
now: [np, nowplaying]
queue: [q]
myqueue: [mq]
seek: []
skip: []
skipto: [forceskip]
stop: []
pause: [resume]
shuffle: []
move: [m]
remove: [rem]
DJremove: [djremove]
removeuser: []
search: [s]
disconnect: [dc]
volume: [v, vol]
normalize: [normal]
boost: [bassboost]
history: [h]
scrub: []
# Misc
info: []
musicinfo: []
uptime: []
ping: []
guilds: []
reloadlocale: []
reloadalias: []
# Settings
settings:
aliases: [set]
sub_commands:
current: [show]
serverlocale: [lang]
djroles: []
dynamicmax: []
musicchannels: [vc]
listenchannels: []
textchannels: [tc]
maxduration: []
modrole: []
resetprefix: []
serverprefix: []
threshold: []
# Cogs
cogs:
aliases: []
sub_commands:
load: []
unload: []
reload: []
reloadall: []
shutdown: []
+185
View File
@@ -0,0 +1,185 @@
# Aliases and translated versions of help messages and arguments
# for each of the commands in the the bot(except the forgotten onces.)
# Currently no fallback so everything has to be translated.
# Help
help:
aliases: [help]
args: '<commands>'
description: 'Shows a help message.'
# Music
play:
aliases: [play, p]
args: '<query>' # This is just a cosmetic representation of the arguments.
description: 'Searches and plays a song from a given query.'
now:
aliases: [now, np, nowplaying]
description: 'Show the song currently playing.'
queue:
aliases: [queue, q]
args: '[user]'
description: 'Shows the queue. Shows a user queue if user is specified.'
myqueue:
aliases: [myqueue, mq]
description: 'Shows your queue.'
seek:
aliases: [seek]
args: '<seconds>'
description: 'Seek forward or backwards in the song.'
skip:
aliases: [skip]
description: 'Vote to skip the current song.'
skipto:
aliases: [skipto, forceskip]
args: '<queue position>'
description: 'Skips to the specified position in the queue.'
stop:
aliases: [stop]
description: 'Stops playing and clears the queue.'
pause:
aliases: [pause, resume]
description: 'Pause/resume the current song.'
shuffle:
aliases: [shuffle]
description: 'Shuffles your queue'
move:
aliases: [move, m]
args: '<start_pos> <end_pos>'
description: 'Moves a track in your queue.'
remove:
aliases: [rem]
args: '<pos>'
description: 'Removes a song from your queue.'
DJremove:
aliases: [DJremove, djremove]
args: '<pos>'
description: 'Removes a song from the global queue.'
removeuser:
aliases: [removeuser]
args: '<user>'
description: 'Removes all songs queued by <user>.'
search:
aliases: [search, s]
args: '<query>'
description: 'Returns a list of possible songs.'
disconnect:
aliases: [disconnect, dc]
description: 'Clears the queue, stops playing and leaves the current voice channel.'
volume:
aliases: [volume, v, vol]
args: '<vol>'
description: 'Sets the volume of the music.'
normalize:
aliases: [nomralize, normal]
description: 'Resets the volume and the equalizer.'
boost:
aliases: [boost, bassboost]
args: <True/False>
description: 'Turns on or off bass boost'
history:
aliases: [history, h]
description: 'Shows the last 10 songs played.'
scrub:
aliases: [scrub]
description: 'Shows a temporary controller/scrubber.'
# Misc
info:
aliases: [info]
description: 'Shows info about the bot.'
musicinfo:
aliases: [musicinfo]
description: 'Shows music related info about the bot.'
uptime:
aliases: [uptime]
description: 'Shows how long the bot has been running.'
ping:
aliases: [ping]
description: 'Get the current latency of the bot.'
guilds:
aliases: [guilds]
description: 'Show the guilds the bot is in'
reloadlocale:
aliases: [reloadlocale]
description: 'Reload all response translations'
reloadalias:
aliases: [reloadalias]
description: 'Reload all aliases and help information.'
# Settings
settings:
aliases: [settings, set]
description: 'Manage server settings.'
sub_commands:
current:
aliases: [current, show]
description: 'Show current settings.'
serverlocale:
aliases: [serverlocale, lang]
args: '<locale>'
description: 'Set the server language.'
djroles:
aliases: [djroles]
args: '[roles...]'
description: 'Set the DJ roles for the server.'
dynamicmax:
aliases: [dynamicmax]
args: '<True/false>'
description: 'Choose if the max song duration is dynamic.'
musicchannels:
aliases: [musicchannels, vc]
args: '[voicechannels...]'
description: 'Set the channels where the bot will play music.'
listenchannels:
aliases: [listenchannels]
args: '[voicechannels...]'
description: 'Set the channels where the bot will mute people who join.'
textchannels:
aliases: [textchannels, tc]
args: '[textchannels...]'
description: 'Set the channels where the bot will accept music commands.'
maxduration:
aliases: [maxduration]
args: '<duration>'
description: 'Max song length that can be queued in minutes.'
modrole:
aliases: [modrole]
args: '[roles...]'
description: 'Set the modroles for the server.'
resetprefix:
aliases: [resetprefix]
description: 'reset the prefixes on the server to the bots default.'
serverprefix:
aliases: [serverprefix]
args: '[prefixes...]'
description: 'Set serverprefixes. Not listing any prefixes will show the current ones.'
threshold:
aliases: [threshold]
args: '<threshold>'
description: 'Set the vote threshold required to skip a song.'
# Cogs
cogs:
aliases: [cogs]
description: 'cog management'
sub_commands:
load:
aliases: [load]
args: '<cog>'
description: 'Loads a cog'
unload:
aliases: [unload]
args: '<cog>'
description: 'Unloads a cog'
reload:
aliases: [reload]
args: '<cog>'
description: 'Reloads a cog'
reloadall:
aliases: [reloadall]
description: 'Reload all cogs'
shutdown:
aliases: [shutdown]
description: 'Shuts down the bot'
+1
View File
@@ -0,0 +1 @@
pageindicator: Viewing page {_current}/{_total} | Type "{_prefix}help <command>" for more information
+2 -2
View File
@@ -23,8 +23,8 @@ queue:
user_empty: "{_user}'s queue is empty"
length: "**Queue** `{_length} songs`"
userqueue: "**{_user}\\'s queue** `{_length}`"
globaltrack: "`{_index}.` **[{_title}]({_uri})** _by <@{_user_id}>_\n"
usertrack: "`{_index}({_globalindex}).` **[{_title}]({_uri})**\n"
globaltrack: "`{_index}.` **[{_title}]({_uri})** _by <@{_user_id}>_"
usertrack: "`{_index}({_globalindex}).` **[{_title}]({_uri})**"
pageindicator: Viewing page {_current}/{_total}
my_queue: Your queue is empty
resume:
-43
View File
@@ -1,43 +0,0 @@
# Music aliases
play: [p, spill, s]
now: [np, nå]
queue: [q, kø, k]
myqueue: [mq, minkø, mk]
seek: [spol]
skip: [hopp]
skipto: [forceskip, hopptil, tvinghopp]
stop: [stopp]
pause: [resume, gjenoppta]
shuffle: [stokk]
move: [m, flytt, f]
remove: [rem, fjern]
DJremove: [DJfjern, djfjern]
removeuser: [fjernbruker]
search: [søk, finn]
disconnect: [dc, kf, koblefra]
volume: [vol, volum, lydstyrke, lyd]
normalize: [normal, nl, normaliser]
boost: [bassboost, bassforsterker]
history: [h, hist, historie]
scrub: [kontroller, konsoll]
# Other
info: [informasjon]
musicinfo: [musikkinfo, musikkinformasjon]
settings:
aliases: [innstillinger]
sub_commands:
serverlocale: [språk]
current: [gjeldende]
djroles: [djroller]
dynamicmax: [dynamiskmaks]
listenchannels: []
maxduration: [maksvarighet]
modrole: [modrolle]
musicchannels: [musikkanaler]
resetprefix: []
serverprefix: [serverprefiks]
textchannels: [tekstkanaler]
threshold: [grense]
+185
View File
@@ -0,0 +1,185 @@
# Aliases for each of the commands in the the bot(except the forgotten onces.)
# Aliases without subcommands don't need to have "aliases:", specified.
# For commands with subcommands you need to have one subcategory called aliases and one called subcommands.
# Help
help:
aliases: [hjelp]
args: '<kommandoer>'
description: 'Viser en hjelp-melding.'
# Music
play:
aliases: [spill, s]
args: '<sang>' # This is just a cosmetic representation of the arguments.
description: 'Søker opp og spiller av en sang.'
now:
aliases: [nå, spillernå]
description: 'Viser hvilken sang som spilles.'
queue:
aliases: [kø, k]
args: '[bruker]'
description: 'Viser køen. Viser en brukerkø om bruker er spesifisert.'
myqueue:
aliases: [minkø, mk]
description: 'Viser din personlige kø.'
seek:
aliases: [spol]
args: '<sekunder>'
description: 'Spol frem eller tilbake i sangen.'
skip:
aliases: [hopp]
description: 'Stem for å hoppe over sangen som spilles.'
skipto:
aliases: [hopptil, tvinghopp]
args: '<køposisjon>'
description: 'Hopper over til sangen i den spesifiserte køposisjonen.'
stop:
aliases: [stopp]
description: 'Stopper avspillingen og tømmer køen.'
pause:
aliases: [pause, fortsett]
description: 'Pauser/fortsetter den nåværende sangen.'
shuffle:
aliases: [omstokk, stokkom, bland]
description: 'Stokker om rekkefølgen til den personlige køen din.'
move:
aliases: [flytt, f]
args: '<fra_posisjon> <til_posisjon>'
description: 'Flytter en sang i den personlige køen din.'
remove:
aliases: [fjern]
args: '<posisjon>'
description: 'Fjerner en sang fra personlige køen din.'
DJremove:
aliases: [DJfjern, djfjern]
args: '<posisjon>'
description: 'Fjerner en sang fra køen.'
removeuser:
aliases: [fjernbruker]
args: '<bruker>'
description: 'Fjerner alle sangene i køen som er lagt til av en spesifisert bruker.'
search:
aliases: [søk, finn]
args: '<sang>'
description: 'Søker opp og viser en liste med mulige sanger.'
disconnect:
aliases: [koblefra, kf]
description: 'Tømmer køen, stopper avspillingen og forlater talekanalen.'
volume:
aliases: [volum, v, vol, lydnivå]
args: '<vol>'
description: 'Setter volumet på musikken.'
normalize:
aliases: [normaliser, normal]
description: 'Tilbakestiller volumet og equalizer til standardinnstillinger.'
boost:
aliases: [bassforsterker, forsterkbass]
args: ''
description: 'Skrur av/på bassforsterkeren'
history:
aliases: [historikk, avspillingshistorikk, h]
description: 'Viser en liste over de 10 siste avspilte sangene.'
scrub:
aliases: [kontroller]
description: 'Gir deg en kontroller som du kan styre musikken med.'
# Misc
info:
aliases: [info, botinfo, båttinfo]
description: 'Gir deg informasjon om båtten.'
musicinfo:
aliases: [musikkinfo]
description: 'Gir deg informasjon om musikkspilleren til båtten.'
uptime:
aliases: [oppetid]
description: 'Viser hvor lenge båtten har kjørt.'
ping:
aliases: [ping]
description: 'Sjekker responstiden til båtten.'
guilds:
aliases: [tenarar]
description: 'Sender en liste over tenarane som båtten er medlem av'
reloadlocale:
aliases: [reloadlocale]
description: 'Laser inn alle oversetningsfilene på nytt'
reloadalias:
aliases: [reloadalias]
description: 'Laster inn aliaser og hjelp på nytt.'
# Settings
settings:
aliases: [innstillinger, oppsett]
description: 'Behandle serverinnstillinger.'
sub_commands:
current:
aliases: [vis, gjeldende]
description: 'Viser gjeldende innstillinger.'
serverlocale:
aliases: [språk]
args: '<språk>'
description: 'Endrer serverspråket.'
djroles:
aliases: [djroller, DJroller]
args: '[roller...]'
description: 'Setter DJ-rollene på serveren.'
dynamicmax:
aliases: [dynamiskmaks]
args: '<True/false>'
description: 'Velg om maks sanglengde skal være dynamisk eller ikke.'
musicchannels:
aliases: [musikk-kanal]
args: '[talekanaler...]'
description: 'Setter kanalene som båtten kan spille musikk i.'
listenchannels:
aliases: [lyttekanaler, lk]
args: '[talekanaler...]'
description: 'Setter kanalene hvor båtten vil automatisk dempe alle som kobler seg til den.'
textchannels:
aliases: [tekstkanaler, tk]
args: '[tekstkanaler...]'
description: 'Setter kanalene hvor man kan bruke musikk-kommandoer.'
maxduration:
aliases: [makslengde]
args: '<lengde_i_minutter>'
description: 'Setter makslengden på sanger som kan bli lagt til i køen.'
modrole:
aliases: [modrolle]
args: '[roller...]'
description: 'Setter serverens modrolle.'
resetprefix:
aliases: [resetprefiks]
description: 'Tilbakestiller serverprefiksen til båtten sin standardprefiks.'
serverprefix:
aliases: [serverprefiks]
args: '[prefikser...]'
description: 'Setter serverprefiksen. Om ingen prefiks blir gitt, vil den vise serverens foreløpige satte prefikser.'
threshold:
aliases: [stemmegrense]
args: '<grense>'
description: 'Setter grensen for hvor mange prosent som må stemme for å hoppe over en sang.'
# Cogs
cogs:
aliases: [cogs]
description: 'behandle cogs'
sub_commands:
load:
aliases: [load]
args: '<cog>'
description: 'Laster inn en cog'
unload:
aliases: [unload]
args: '<cog>'
description: 'Unloads a cog'
reload:
aliases: [reload]
args: '<cog>'
description: 'Laster en cog inn på nytt.'
reloadall:
aliases: [reloadall]
description: 'Laser inn alle cogs på nytt.'
shutdown:
aliases: [shutdown]
description: 'Stopper båtten.'
+1
View File
@@ -0,0 +1 @@
pageindicator: Viser side {_current}/{_total} | Skriv "{_prefix}hjelp <kommando>" for mer informasjon
+2 -2
View File
@@ -23,8 +23,8 @@ queue:
user_empty: "{_user} sin kø er tom"
length: "**Kø** `{_length} sanger`"
userqueue: "**{_user} sin kø** `{_length}` sanger"
globaltrack: "`{_index}.` **[{_title}]({_uri})** _av <@{_user_id}>_\n"
usertrack: "`{_index}({_globalindex}).` **[{_title}]({_uri})**\n"
globaltrack: "`{_index}.` **[{_title}]({_uri})** _av <@{_user_id}>_"
usertrack: "`{_index}({_globalindex}).` **[{_title}]({_uri})**"
pageindicator: Viser side {_current}/{_total}
my_queue: Din kø er tom
resume:
+66
View File
@@ -0,0 +1,66 @@
# Aliases for each of the commands in the the bot(except the forgotten onces.)
# Aliases without subcommands don't need to have "aliases:", specified.
# For commands with subcommands you need to have one subcategory called aliases and one called subcommands.
# Music
play:
aliases: [play, p]
args: <query>
description: Searches and plays a song from a given query.
now: [now, np, nowplaying]
queue: [queue, q]
myqueue: [myqueue, mq]
seek: [seek]
skip: [skip]
skipto: [skipto, forceskip]
stop: [stop]
pause: [pause, resume]
shuffle: [shuffle]
move: [move, m]
remove: [rem]
DJremove: [DJremove, djremove]
removeuser: [removeuser]
search: [search, s]
disconnect: [disconnect, dc]
volume: [volume, v, vol]
normalize: [nomralize, normal]
boost: [boost, bassboost]
history: [history, h]
scrub: [scrub]
# Misc
info: [info]
musicinfo: [musicinfo]
uptime: [uptime]
ping: [ping]
guilds: [guilds]
reloadlocale: [reloadlocale]
reloadalias: [reloadalias]
# Settings
settings:
aliases: [settings, set]
sub_commands:
current: [current, show]
serverlocale: [serverlocale, lang]
djroles: [djroles]
dynamicmax: [dynamicmax]
musicchannels: [musicchannels, vc]
listenchannels: [listenchannels]
textchannels: [textchannels, tc]
maxduration: [maxduration]
modrole: [modrole]
resetprefix: [resetprefix]
serverprefix: [serverprefix]
threshold: [threshold]
# Cogs
cogs:
aliases: [cogs]
sub_commands:
load: [load]
unload: [unload]
reload: [reload]
reloadall: [reloadall]
shutdown: [shutdown]
+2 -2
View File
@@ -23,8 +23,8 @@ queue:
user_empty: "{_user} sin kø er tom"
length: "**Kø** `{_length} songar`"
userqueue: Køen til **{_user}** `{_length}` songar
globaltrack: "`{_index}.` **[{_title}]({_uri})** _av <@{_user_id}>_\n"
usertrack: "`{_index}({_globalindex}).` **[{_title}]({_uri})**\n"
globaltrack: "`{_index}.` **[{_title}]({_uri})** _av <@{_user_id}>_"
usertrack: "`{_index}({_globalindex}).` **[{_title}]({_uri})**"
pageindicator: Viser side {_current}/{_total}
my_queue: Din kø er tom
resume: