Merge PEP8 and jenkins changes into DEV (#18)

Merge PEP8 and jenkins changes into DEV
This commit is contained in:
Roxedus authored and GitHub committed 2019-07-20 20:22:43 +02:00
commit 2bae6bd5b4
24 files changed
+245 -229

No files matched your search

-12
View File
@@ -1,12 +0,0 @@
pipeline:
build:
image: plugins/docker
repo: rnorge/music
secrets: [ docker_username, docker_password ]
tags:
- latest
- ${DRONE_TAG}
when:
event:
- tag
-16
View File
@@ -1,16 +0,0 @@
build:
image: docker:stable
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
before_script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
stage: build
script:
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
only:
- master
+1 -1
View File
@@ -11,6 +11,6 @@ RUN \
WORKDIR /app
CMD ln -sf /app/data /config && /app/localization /config && python3 /app/bot.py
CMD cp -u /app/data/config.yaml.example /config/config.yaml.example && python3 /app/bot.py --data-directory /config
VOLUME /config
Vendored
+57
View File
@@ -0,0 +1,57 @@
pipeline {
agent none
environment {
GIT_REPO = 'Ev-1/ShiteMusicBot'
DOCKER_REPO = 'rnorge/music'
TAG=""
FLAKE_FILES = "bot.py cogs/*.py cogs/utils/*.py"
}
stages {
stage('Flake8') {
agent { label 'amd64'}
steps {
sh """
python3.7 -m venv venv && venv/bin/pip install flake8 && venv/bin/python -m flake8 --max-line-length 120 ${FLAKE_FILES}
rm -rf venv/
"""
script {
TAG = sh(returnStdout: true, script: 'grep -i bot_version cogs/utils/bot_version.py | cut -d" " -f3 | tr -d \\"').trim()
SBranch = sh(returnStdout: true, script: 'echo ${GIT_BRANCH} | sed "s#/#_#"').trim()
}
}
}
stage('Docker Builds') {
parallel {
stage('branch') {
agent { label 'amd64'}
when {
not {
changeRequest()
}
}
steps {
script {
if (BRANCH_NAME == 'master') {
def image = docker.build("${DOCKER_REPO}:${TAG}-amd64")
image.push()
}
def image = docker.build("${DOCKER_REPO}:${SBranch}-amd64")
image.push()
}
}
}
stage('pr') {
agent { label 'amd64'}
when {
changeRequest()
}
steps {
script {
def image = docker.build("${DOCKER_REPO}:PR_$GIT_BRANCH-amd64")
}
}
}
}
}
}
}
+38 -27
View File
@@ -1,13 +1,13 @@
import discord
import codecs
import time
import sys
import os
import traceback
import yaml
import aiohttp
from discord.ext import commands
from discord.ext.commands.view import StringView
from argparse import ArgumentParser, RawTextHelpFormatter
from cogs.utils.settingsmanager import Settings
from cogs.utils.localizer import Localizer
from cogs.utils.localizer import LocalizerWrapper
@@ -17,11 +17,6 @@ from cogs.utils.logger import BotLogger
from cogs.helpformatter import commandhelper
from cogs.utils.paginator import Scroller
with codecs.open("data/config.yaml", 'r', encoding='utf8') as f:
conf = yaml.load(f, Loader=yaml.SafeLoader)
initial_extensions = [
'cogs.cogs',
'cogs.settings',
@@ -29,7 +24,6 @@ initial_extensions = [
'cogs.helpformatter'
]
on_ready_extensions = [
'cogs.music',
'cogs.musicevents'
@@ -45,11 +39,11 @@ def _get_prefix(bot, message):
class Bot(commands.Bot):
def __init__(self, debug: bool=False):
def __init__(self, datadir, debug: bool = False):
super().__init__(command_prefix=_get_prefix,
description=conf["bot"]["description"])
self.settings = Settings(**conf['default server settings'])
self.settings = Settings(datadir, **conf['default server settings'])
self.APIkeys = conf.get('APIkeys', {})
self.localizer = Localizer(conf.get('locale path', "./localization"), conf.get('locale', 'en_en'))
@@ -57,6 +51,7 @@ class Bot(commands.Bot):
self.session = aiohttp.ClientSession(loop=self.loop)
self.datadir = datadir
self.debug = debug
self.main_logger = logger
self.logger = self.main_logger.bot_logger.getChild("Bot")
@@ -77,27 +72,23 @@ class Bot(commands.Bot):
await scroller.start_scrolling()
if isinstance(err, commands.CommandInvokeError):
self.logger.debug("Error running command: %s\n Traceback: %s"
% (ctx.command, err))
self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err))
pass
elif isinstance(err, commands.NoPrivateMessage):
self.logger.debug("Error running command: %s\n Traceback: %s"
% (ctx.command, err))
self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err))
await ctx.send('That command is not available in DMs')
elif isinstance(err, commands.CommandOnCooldown):
await ctx.send(f"{ctx.message.author.mention} Command is on cooldown. "
f"Try again in `{err.retry_after:.1f}` seconds.")
elif isinstance(err, RuntimeError):
self.logger.debug("Error running command: %s\n Traceback: %s"
% (ctx.command, err))
self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err))
pass
elif isinstance(err, commands.CheckFailure):
self.logger.debug("Error running command: %s\n Traceback: %s"
% (ctx.command, err))
self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err))
pass
elif isinstance(err, commands.CommandNotFound):
@@ -134,7 +125,7 @@ class Bot(commands.Bot):
try:
self.logger.debug("Loading extension %s" % extension)
self.load_extension(extension)
except Exception as e:
except Exception:
self.logger.exception("Loading of extension %s failed" % extension)
print(f'\nLogged in as: {self.user.name}' +
@@ -155,14 +146,34 @@ class Bot(commands.Bot):
print(e)
def run_bot(debug: bool=False):
bot = Bot(debug=debug)
def run_bot(datadir, debug: bool = False):
bot = Bot(datadir, debug=debug)
bot.run()
if __name__ == '__main__':
state = False
if 'debug' in sys.argv:
state = True
logger = BotLogger(state, conf.get('log_path', './data/logs'))
run_bot(debug=state)
parser = ArgumentParser(prog='Shite Music Bot',
description='Discord music bot utilizing discord.py, lavalink and lavalink.py',
formatter_class=RawTextHelpFormatter)
parser.add_argument("-D", "--debug", action='store_true', help='Sets debug to true')
parser.add_argument("-d", "--data-directory", help='Define an alternate data directory location')
args = parser.parse_args()
if args.debug or os.environ.get('debug'):
is_debug = True
else:
is_debug = False
if args.data_folder:
datadir = str(args.data_folder)
else:
datadir = "data"
print(f"Data folder: {datadir}")
with codecs.open(f"{datadir}/config.yaml", 'r', encoding='utf8') as f:
conf = yaml.load(f, Loader=yaml.SafeLoader)
logger = BotLogger(is_debug, conf.get('log_path', f'{datadir}/logs'))
run_bot(debug=is_debug, datadir=datadir)
+4 -6
View File
@@ -1,10 +1,8 @@
import discord
import os
import codecs
import traceback
from discord.ext import commands
from cogs.utils import checks
class Cogs(commands.Cog):
def __init__(self, bot):
self.bot = bot
@@ -34,7 +32,7 @@ class Cogs(commands.Cog):
try:
self.bot.unload_extension(f'cogs.{module}')
await ctx.send(f'{module} unloaded')
except Exception as e:
except Exception:
await ctx.send(f'```py\n{traceback.format_exc()}\n```')
@_cogs.command(name='reload')
@@ -45,7 +43,7 @@ class Cogs(commands.Cog):
self.bot.unload_extension(f'cogs.{module}')
self.bot.load_extension(f'cogs.{module}')
await ctx.send(f'{module} reloaded')
except Exception as e:
except Exception:
await ctx.send(f'```py\n{traceback.format_exc()}\n```')
@_cogs.command(name='reloadall')
@@ -59,7 +57,7 @@ class Cogs(commands.Cog):
self.bot.unload_extension(f'{extension}')
self.bot.load_extension(f'{extension}')
await ctx.send('Extensions reloaded')
except Exception as e:
except Exception:
await ctx.send(f'```py\n{traceback.format_exc()}\n```')
@_cogs.command(name='shutdown')
+6 -6
View File
@@ -1,6 +1,4 @@
import discord
from discord.ext import commands
import asyncio
import re
from cogs.utils.paginator import HelpPaginator, Scroller
@@ -18,10 +16,11 @@ def get_cmd_dict(ctx, qualified_name):
cmd_dict = ctx.bot.aliaser.get_cmd_help("en_en", split[-1], split[:-1])
try:
cmd_dict["aliases"] = [split[-1]]
except:
except KeyError:
cmd_dict = None
return cmd_dict
async def helper(ctx):
bot = ctx.bot
# Display music commands first
@@ -29,7 +28,7 @@ async def helper(ctx):
paginator = await coghelper(ctx, music)
for cog in bot.cogs.copy().values():
if cog.__cog_name__ is 'Music':
if cog.__cog_name__ == 'Music':
continue
cogpaignator = await coghelper(ctx, cog)
paginator.append_paginator(cogpaignator)
@@ -48,7 +47,7 @@ async def coghelper(ctx, cog, ignore_subcommands=True):
continue
try:
can_run = await cmd.can_run(ctx)
except CommandError:
except commands.CommandError: # Was 'CommandError' guessed it was supposed to be what it is now
can_run = False
if not can_run:
continue
@@ -107,13 +106,14 @@ def prefix_cleaner(ctx):
ctx.prefix = pref
return ctx
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)
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]
+16 -25
View File
@@ -1,12 +1,9 @@
import discord
import os
import asyncio
import time
import random
import platform
from discord.ext import commands
from cogs.utils import checks
from cogs.utils import checks, bot_version
from lavalink import __version__ as LavalinkVersion
@@ -16,13 +13,13 @@ class Misc(commands.Cog):
@commands.command(name='ping', hidden=True)
async def _ping(self, ctx):
start = time.perf_counter()
message = await ctx.send('Ping...')
end = time.perf_counter()
duration = int((end - start) * 1000)
edit = f'Pong!\nPing: {duration}ms' \
+ f' | websocket: {int(self.bot.latency * 1000)}ms'
await message.edit(content=edit)
start = time.perf_counter()
message = await ctx.send('Ping...')
end = time.perf_counter()
duration = int((end - start) * 1000)
edit = f'Pong!\nPing: {duration}ms' \
+ f' | websocket: {int(self.bot.latency * 1000)}ms'
await message.edit(content=edit)
@commands.command(name='uptime', hidden=True)
async def _uptime(self, ctx):
@@ -57,7 +54,6 @@ class Misc(commands.Cog):
embed.add_field(name='{music.listeners}', value=f'{listeners}')
embed = ctx.localizer.format_embed(embed)
await ctx.send(embed=embed)
@commands.command(name="reloadlocale")
@checks.is_owner()
@@ -92,19 +88,18 @@ class Misc(commands.Cog):
days, remainder = divmod(diff, 24 * 60 * 60)
hours, remainder = divmod(remainder, 60 * 60)
minutes, seconds = divmod(remainder, 60)
avatar = self.bot.user.avatar_url_as(format=None,
static_format='png',
size=1024)
avatar = self.bot.user.avatar_url_as(format=None, static_format='png', size=1024)
uptimetext = f'{days}d {hours}t {minutes}m {seconds}s'
embed = discord.Embed(color=ctx.me.color)
embed.set_author(name=self.bot.user.name, icon_url=avatar)
embed.set_thumbnail(url=avatar)
embed.set_image(url='https://cdn.discordapp.com/attachments/298524946454282250/368118192251469835/vintage1turntable.png')
embed.set_image(url='https://cdn.discordapp.com/attachments/298524946454282250/'
'368118192251469835/vintage1turntable.png')
embed.add_field(name="{bot.what}",
value='{bot.infotext}', inline=False)
embed.set_footer(icon_url="https://cdn.discordapp.com/icons/532176350019321917/92f43a1f67308a99a30c169db4b671dd.png?size=64",
text="{bot.footer_text}")
embed.set_footer(icon_url="https://cdn.discordapp.com/icons/532176350019321917/"
"92f43a1f67308a99a30c169db4b671dd.png?size=64", text="{bot.footer_text}")
embed.add_field(name="{bot.how}",
value='{bot.spectext}')
embed.add_field(name="{bot.how_many}",
@@ -112,13 +107,9 @@ class Misc(commands.Cog):
embed.add_field(name="{bot.how_long}",
value=uptimetext)
embed = ctx.localizer.format_embed(embed,
_python_v=platform.python_version(),
_discord_v=discord.__version__,
_lavalink_v=LavalinkVersion,
_guilds=guilds,
_members=members
)
embed = ctx.localizer.format_embed(embed, _python_v=platform.python_version(), _discord_v=discord.__version__,
_lavalink_v=LavalinkVersion, _guilds=guilds, _members=members,
_bot_v=bot_version.bot_version)
await ctx.send(embed=embed)
+39 -41
View File
@@ -4,7 +4,6 @@ Music commands
import math
import re
import asyncio
import time
import yaml
import codecs
@@ -33,7 +32,7 @@ class Music(commands.Cog):
if not hasattr(bot, 'lavalink'): # This ensures the client isn't overwritten during cog reloads.
bot.lavalink = lavalink.Client(bot.user.id, player=MixPlayer)
with codecs.open("data/config.yaml", 'r', encoding='utf8') as f:
with codecs.open(f"{self.bot.datadir}/config.yaml", 'r', encoding='utf8') as f:
conf = yaml.load(f, Loader=yaml.SafeLoader)
bot.lavalink.add_node(**conf['lavalink nodes']['main'])
@@ -106,7 +105,7 @@ class Music(commands.Cog):
async def _seek(self, ctx, *, time: str):
""" Seeks to a given position in a track. """
player = self.bot.lavalink.players.get(ctx.guild.id)
if not player.is_playing:
return await ctx.send(ctx.localizer.format_str("{not_playing}"))
@@ -150,7 +149,7 @@ class Music(commands.Cog):
@commands.command(name='skipto')
@checks.DJ_or(alone=True)
async def _skip_to(self, ctx, pos: int=1):
async def _skip_to(self, ctx, pos: int = 1):
""" Plays the queue from a specific point. Disregards tracks before the pos. """
player = self.bot.lavalink.players.get(ctx.guild.id)
@@ -212,7 +211,7 @@ class Music(commands.Cog):
await ctx.send(embed=embed)
@commands.command(name='queue')
async def _queue(self, ctx, user: discord.Member=None):
async def _queue(self, ctx, user: discord.Member = None):
""" Shows the player's queue. """
player = self.bot.lavalink.players.get(ctx.guild.id)
@@ -220,7 +219,7 @@ class Music(commands.Cog):
embed = discord.Embed(description='{queue.empty}', color=ctx.me.color)
embed = ctx.localizer.format_embed(embed)
return await ctx.send(embed=embed)
if user is None:
queue = player.global_queue()
pagified_queue = QueuePaginator(ctx.localizer, queue, color=ctx.me.color)
@@ -228,7 +227,7 @@ class Music(commands.Cog):
else:
user_queue = player.user_queue(user.id, dual=True)
if not user_queue:
return await ctx.send(ctx.localizer.format_str("{queue.empty}", _user=user.name))
return await ctx.send(ctx.localizer.format_str("{queue.empty}", _user=user.name))
pagified_queue = QueuePaginator(ctx.localizer, user_queue, color=ctx.me.color, user_name=user.name)
scroller = Scroller(ctx, pagified_queue)
@@ -285,13 +284,13 @@ class Music(commands.Cog):
if not user_queue:
return await ctx.send(ctx.localizer.format_str("{my_queue}"))
if not all(x in range(1,len(user_queue) + 1) for x in [from_pos, to_pos]):
if not all(x in range(1, len(user_queue) + 1) for x in [from_pos, to_pos]):
return await ctx.send(ctx.localizer.format_str("{out_of_range}", _len=len(user_queue)))
moved = player.move_user_track(ctx.author.id, from_pos - 1, to_pos - 1)
if moved is None:
return await ctx.send(ctx.localizer.format_str("{move.not_in_queue}"))
msg = ctx.localizer.format_str("{move.moved_to}", _title=moved.title, _from=from_pos, _to=to_pos)
await ctx.send(msg)
@@ -316,7 +315,7 @@ class Music(commands.Cog):
@commands.command(name="DJremove")
@checks.DJ_or()
async def _djremove(self, ctx, pos: int, user: discord.Member=None):
async def _djremove(self, ctx, pos: int, user: discord.Member = None):
""" Remove a song from either the global queue or a users queue"""
player = self.bot.lavalink.players.get(ctx.guild.id)
@@ -436,13 +435,11 @@ class Music(commands.Cog):
await result_msg.edit(embed=embed)
try:
reaction, user = await self.bot.wait_for('reaction_add',
timeout=15.0,
check=check)
reaction, user = await self.bot.wait_for('reaction_add', timeout=15.0, check=check)
except asyncio.TimeoutError:
await result_msg.clear_reactions()
embed.title = ''
embed.description='{time_expired}'
embed.description = '{time_expired}'
embed = ctx.localizer.format_embed(embed)
await result_msg.edit(embed=embed)
await asyncio.sleep(5)
@@ -488,7 +485,7 @@ class Music(commands.Cog):
return await ctx.send(f'🔈 | {player.volume}%')
is_dj = checks.is_DJ(ctx)
is_admin = getattr(ctx.author.guild_permissions, 'administrator', None) == True
is_admin = getattr(ctx.author.guild_permissions, 'administrator', None) is True
if int(player.current.requester) == ctx.author.id and not is_dj and not is_admin:
if not 50 <= volume <= 125:
return await ctx.send(ctx.localizer.format_str("{volume.out_of_range}"))
@@ -516,7 +513,7 @@ class Music(commands.Cog):
@commands.command(name='boost')
@checks.DJ_or(alone=True)
async def _boost(self, ctx, boost: bool=None):
async def _boost(self, ctx, boost: bool = None):
""" Set the equalizer to bass boost the music """
player = self.bot.lavalink.players.get(ctx.guild.id)
@@ -529,7 +526,7 @@ class Music(commands.Cog):
embed.description = '{boost.on}'
else:
embed.description = '{boost.off}'
embed = ctx.localizer.format_embed(embed)
await ctx.send(embed=embed)
@@ -543,15 +540,16 @@ class Music(commands.Cog):
embed = ctx.localizer.format_embed(embed)
return await ctx.send(embed=embed)
track = history[0]
description = ctx.localizer.format_str("{history.current}", _title=track.title, _uri=track.uri,_id=track.requester) + '\n\n'
description = ctx.localizer.format_str("{history.current}", _title=track.title, _uri=track.uri,
_id=track.requester) + '\n\n'
description += ctx.localizer.format_str("{history.previous}", _len=len(history)-1) + '\n'
thumb_url = await RoxUtils.ThumbNailer.identify(self,
track.identifier,
track.uri)
thumb_url = await RoxUtils.ThumbNailer.identify(self, track.identifier, track.uri)
for index, track in enumerate(history[1:], start=1):
description += ctx.localizer.format_str("{history.track}",_index=-index, _title=track.title, _uri=track.uri, _id=track.requester) + '\n'
description += ctx.localizer.format_str("{history.track}", _index=-index, _title=track.title,
_uri=track.uri, _id=track.requester) + '\n'
embed = discord.Embed(title=ctx.localizer.format_str('{history.title}'), color=ctx.me.color, description=description)
embed = discord.Embed(title=ctx.localizer.format_str('{history.title}'), color=ctx.me.color,
description=description)
if thumb_url:
embed.set_thumbnail(url=thumb_url)
@@ -575,7 +573,7 @@ class Music(commands.Cog):
if not query and player.is_playing:
query = player.current.title
query = re.sub('[-()_\[\]]', '', query)
query = re.sub(r'[-()_\[\]]', '', query)
filtered_words = [word for word in query.split() if word.lower() not in excluded_words]
query = ' '.join(filtered_words)
@@ -593,7 +591,7 @@ class Music(commands.Cog):
result = await get_site_content(url)
response = json.loads(result)
song_id = response['response']['hits'][0]['result']['id']
except:
except Exception:
embed = discord.Embed(description=':x:', color=0xFF0000)
return await status_msg.edit(embed=embed)
@@ -620,8 +618,7 @@ class Music(commands.Cog):
await ctx.send(embed=page)
else:
paginator.add_page_indicator(ctx.localizer)
scroller = Scroller(ctx, paginator)
await scroller.start_scrolling()
await Scroller(ctx, paginator).start_scrolling()
@commands.command(name='scrub')
@checks.DJ_or(alone=True)
@@ -677,22 +674,22 @@ class Music(commands.Cog):
scrubbing = True
while scrubbing:
try:
reaction, user = await self.bot.wait_for('reaction_add',
timeout=15.0,
check=check)
reaction, user = await self.bot.wait_for('reaction_add', timeout=15.0, check=check)
except asyncio.TimeoutError:
scrolling = False
# PEP8EDIT scrolling = False
try:
await msg.delete()
await ctx.message.delete()
except:
except discord.Forbidden:
pass
except discord.HTTPException:
pass
finally:
break
try:
await msg.remove_reaction(reaction, user)
except:
except discord.Forbidden:
pass
if selection is not None:
if not isinstance(arg, bool):
@@ -704,8 +701,11 @@ class Music(commands.Cog):
player = self.bot.lavalink.players.create(ctx.guild.id, endpoint=ctx.guild.region.value)
# Create returns a player if one exists, otherwise creates.
should_connect = ctx.command.callback.__name__ in ('_play', '_find', '_search') # Add commands that require joining voice to work.
without_connect = ctx.command.callback.__name__ in ('_queue', '_history', '_now', '_lyrics') # Add commands that don't require the you being in voice.
# Add commands that require joining voice to work.
should_connect = ctx.command.callback.__name__ in ('_play', '_find', '_search')
# Add commands that don't require the you being in voice.
without_connect = ctx.command.callback.__name__ in ('_queue', '_history', '_now', '_lyrics')
if without_connect:
return
@@ -750,8 +750,8 @@ class Music(commands.Cog):
maxlength = self.max_track_length(ctx.guild, player)
if maxlength and track['info']['length'] > maxlength:
embed.description = ctx.localizer.format_str("{enqueue.toolong}",
_length=timeformatter.format(track['info']['length']),
_max=timeformatter.format(maxlength))
_length=timeformatter.format(track['info']['length']),
_max=timeformatter.format(maxlength))
return
track, pos_global, pos_local = player.add(requester=ctx.author.id, track=track)
@@ -769,9 +769,7 @@ class Music(commands.Cog):
embed.add_field(name="{enqueue.playing_in}", value=f"`{until_play} ({{enqueue.estimated}})`", inline=True)
embed.title = '{enqueue.enqueued}'
thumb_url = await RoxUtils.ThumbNailer.identify(self,
track.identifier,
track.uri)
thumb_url = await RoxUtils.ThumbNailer.identify(self, track.identifier, track.uri)
if thumb_url:
embed.set_thumbnail(url=thumb_url)
@@ -784,7 +782,7 @@ class Music(commands.Cog):
maxlength = self.bot.settings.get(guild, 'duration.max', None)
if maxlength is None:
return None
if len(player.listeners): # Avoid division by 0.
if len(player.listeners): # Avoid division by 0.
listeners = len(player.listeners)
else:
listeners = 1
+10 -12
View File
@@ -2,15 +2,13 @@
A cog to separate events from regular music commands
"""
import asyncio
import codecs
import yaml
import discord
import lavalink
from discord.ext import commands
import time
from .utils.mixplayer import MixPlayer
from lavalink.events import *
import lavalink.events
class MusicEvents(commands.Cog):
@@ -20,7 +18,7 @@ class MusicEvents(commands.Cog):
if not hasattr(bot, 'lavalink'): # This ensures the client isn't overwritten during cog reloads.
bot.lavalink = lavalink.Client(bot.user.id, player=MixPlayer)
with codecs.open("data/config.yaml", 'r', encoding='utf8') as f:
with codecs.open(f"{self.bot.datadir}/config.yaml", 'r', encoding='utf8') as f:
conf = yaml.load(f, Loader=yaml.SafeLoader)
bot.lavalink.add_node(**conf['lavalink nodes']['main'])
@@ -32,20 +30,20 @@ class MusicEvents(commands.Cog):
self.bot.lavalink._event_hooks.clear()
async def track_hook(self, event):
if isinstance(event, TrackEndEvent):
if isinstance(event, lavalink.events.TrackEndEvent):
pass # Send track ended message to channel.
if isinstance(event, TrackStartEvent):
if isinstance(event, lavalink.events.TrackStartEvent):
pass
if isinstance(event, QueueEndEvent):
if isinstance(event, lavalink.events.QueueEndEvent):
channel = self.bot.get_channel(event.player.fetch('channel'))
await self.check_leave_voice(channel.guild)
if isinstance(event, PlayerUpdateEvent):
if isinstance(event, lavalink.events.PlayerUpdateEvent):
pass
if isinstance(event, NodeDisconnectedEvent):
if isinstance(event, lavalink.events.NodeDisconnectedEvent):
pass
if isinstance(event, NodeConnectedEvent):
if isinstance(event, lavalink.events.NodeConnectedEvent):
pass
if isinstance(event, NodeChangedEvent):
if isinstance(event, lavalink.events.NodeChangedEvent):
pass
async def connect_to(self, guild_id: int, channel_id: str):
+4 -5
View File
@@ -1,10 +1,9 @@
import discord
import os
import codecs
from discord.ext import commands
from cogs.utils import checks
class Settings(commands.Cog):
def __init__(self, bot):
self.bot = bot
@@ -54,7 +53,7 @@ class Settings(commands.Cog):
@commands.guild_only()
@_set.command(name='threshold')
async def set_vote_threshold(self, ctx, threshold: int=50):
async def set_vote_threshold(self, ctx, threshold: int = 50):
if not 0 <= threshold <= 100:
return await ctx.send('Must be between 0 and 100')
@@ -148,7 +147,7 @@ class Settings(commands.Cog):
@commands.guild_only()
@_set.command(name='maxduration')
async def set_max_track_duration(self, ctx, duration: int=None):
async def set_max_track_duration(self, ctx, duration: int = None):
self.bot.settings.set(ctx.guild, 'duration.max', duration)
duration = self.bot.settings.get(ctx.guild, 'duration.max')
@@ -163,7 +162,7 @@ class Settings(commands.Cog):
@commands.guild_only()
@_set.command(name='dynamicmax')
async def set_track_duration_type(self, ctx, dynamic: bool=False):
async def set_track_duration_type(self, ctx, dynamic: bool = False):
self.bot.settings.set(ctx.guild, 'duration.is_dynamic', dynamic)
is_dynamic = self.bot.settings.get(ctx.guild, 'duration.is_dynamic')
+4 -5
View File
@@ -1,5 +1,4 @@
import aiohttp
import asyncio
from bs4 import BeautifulSoup as bs4
session = aiohttp.ClientSession()
@@ -8,10 +7,10 @@ session = aiohttp.ClientSession()
class ThumbNailer(object):
async def get_img(self, url):
async with session.get(url, timeout=30) as response:
assert response.status == 200
html = await response.read()
return await ThumbNailer.__parse_result(html)
async with session.get(url, timeout=30) as response:
assert response.status == 200
html = await response.read()
return await ThumbNailer.__parse_result(html)
async def __parse_result(html):
try:
+5 -5
View File
@@ -1,4 +1,3 @@
import discord
import yaml
from glob import glob
@@ -12,6 +11,7 @@ Allows per guild aliases of subcommands without doing anything to discord.py its
ways of doing this appreciated.
"""
class Aliaser:
def __init__(self, localization_folder, default_lang):
self.localization_folder = path.realpath(localization_folder)
@@ -100,7 +100,7 @@ class Aliaser:
ctx.command = None
return ctx
ctx.view.undo()
ctx.invoker = invoker = ctx.view.buffer[ctx.view.index:ctx.view.end]
ctx.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
@@ -142,11 +142,11 @@ class Aliaser:
else:
sub = ctx.bot.all_commands.get(subcmd, None)
# Translate any subsubcommands
# Translate any subsubcommands
if sub and isinstance(sub, commands.GroupMixin):
self.get_subcommand(ctx, sub, parents)
# Reset the view indexes
# Reset the view indexes
view.index = idx
view.previous = prev
return ctx
return ctx
+1
View File
@@ -0,0 +1 @@
bot_version = "0.1.2"
+4 -3
View File
@@ -37,8 +37,9 @@ def is_even():
def is_owner():
def predicate(ctx):
is_owner = (ctx.message.author.id == 120970603556503552 or
ctx.message.author.id == 142212883512557569 or ctx.message.author.id == 212635519706726410 or
ctx.message.author.id == 170506717140877312)
ctx.message.author.id == 142212883512557569 or
ctx.message.author.id == 212635519706726410 or
ctx.message.author.id == 170506717140877312)
return is_owner
return commands.check(predicate)
@@ -72,7 +73,7 @@ def is_DJ(ctx):
return any([has_role_id(ctx, role_id) for role_id in dj_role_ids])
def DJ_or(alone: bool=False, current: bool=False):
def DJ_or(alone: bool = False, current: bool = False):
async def predicate(ctx):
try:
player = ctx.bot.lavalink.players.get(ctx.guild.id)
+2 -1
View File
@@ -1,9 +1,10 @@
from discord.ext import commands
class Context(commands.Context):
def __init__(self, **kwargs):
super().__init__(**kwargs)
if self.message.guild:
self.locale = self.bot.settings.get(self.message.guild, 'locale', 'default_locale')
else:
self.locale = self.bot.settings.default_locale
self.locale = self.bot.settings.default_locale
+1
View File
@@ -1,5 +1,6 @@
import collections
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
+17 -17
View File
@@ -16,6 +16,7 @@ Localizer for bot
kmatch = re.compile('({(?!_)([^{}]+)})')
class Localizer:
def __init__(self, localization_folder, default_lang):
self.localization_folder = path.realpath(localization_folder)
@@ -31,7 +32,6 @@ class Localizer:
for folder in glob(path.join(self.localization_folder, "*/")):
folder_base = path.basename(path.dirname(folder))
self.localization_table[folder_base] = False
# loads all localizations
def load_localizations(self):
@@ -41,7 +41,8 @@ class Localizer:
self.all_localizations = flatten(self.localization_table)
for lang, d in self.localization_table.items():
self.localization_table[lang] = Localizer._parse_localization_dictionary(self.localization_table[lang], self.all_localizations)
self.localization_table[lang] = Localizer._parse_localization_dictionary(self.localization_table[lang],
self.all_localizations)
# internal function for loading a localization
def _load_localization(self, lang):
@@ -57,7 +58,7 @@ class Localizer:
file_base = path.basename(file).split(".")[0]
with open(file, "r", encoding='utf-8') as f:
data = yaml.load(f, Loader=yaml.SafeLoader)
l_table[file_base] = data
for file in glob(path.join(self.localization_folder, lang, "*.txt")):
@@ -66,14 +67,13 @@ class Localizer:
content = f.read()
l_table[file_base] = content
l_table = flatten(l_table)
# parsing a few times to resolve all values
for i in range(0, 5):
l_table = Localizer._parse_localization_dictionary(l_table, l_table)
self.localization_table[lang] = Localizer._parse_localization_dictionary(l_table, l_table)
# parses and interpolates translation dictionary
@staticmethod
def _parse_localization_dictionary(d, lookup, prefix=None):
@@ -89,7 +89,7 @@ class Localizer:
def _replace_keys(value, prefix=None):
for outer, inner in kmatch.findall(value):
nstr = inner
if prefix is not None:
if prefix is not None:
nstr = f'{prefix}.{inner}'
nstr = f'{{{nstr}}}'
nstr = nstr.replace(".", "/")
@@ -101,11 +101,11 @@ class Localizer:
d = SafeDict(d)
value = Localizer._replace_keys(value, prefix)
return value.format_map(d)
# returns true if localization is currently loaded
def isLoaded(self, lang):
return self.localization_table.get(lang, False)
def getAvaliableLocalizations(self):
return self.localization_table.keys()
@@ -114,25 +114,25 @@ class Localizer:
lang = lang or self.default_lang
if not self.isLoaded(lang):
self._load_localization(lang)
return self.localization_table.get(lang, {}).get(key.replace(".", "/"))
# inserts translations into a string
def format_str(self, s, lang=None, prefix=None, **kvpairs):
lang = lang or self.default_lang
if not self.isLoaded(lang):
self._load_localization(lang)
ns = Localizer._parse_localization_string(s, self.localization_table.get(lang, {}), prefix)
ns = Localizer._parse_localization_string(ns, self.all_localizations, prefix)
return ns.format_map(SafeDict(kvpairs))
# inserts translations into a values of a dictionary
def format_dict(self, d, lang=None, prefix=None, **kvpairs):
lang = lang or self.default_lang
if not self.isLoaded(lang):
self._load_localization(lang)
nd = copy.deepcopy(d)
cursorQueue = [nd]
while cursorQueue:
@@ -157,12 +157,12 @@ class LocalizerWrapper:
self.localizer = localizer
self.lang = lang
self.prefix = prefix
def format_str(self, s, **kvpairs):
return self.localizer.format_str(s, self.lang, self.prefix, **kvpairs)
def format_dict(self, d, **kvpairs):
return self.localizer.format_dict(d, self.lang, self.prefix, **kvpairs)
def format_embed(self, embed, **kvpairs):
return self.localizer.format_embed(embed, self.lang, self.prefix, **kvpairs)
return self.localizer.format_embed(embed, self.lang, self.prefix, **kvpairs)
+4 -4
View File
@@ -2,6 +2,7 @@ import logging.handlers
import logging
import os
class BotLogger(object):
def __init__(self, debug=None, data_location=None):
self.log_location = data_location
@@ -23,9 +24,9 @@ class BotLogger(object):
os.makedirs(self.log_location)
print(f"Creating logging directory: {self.log_location}")
if self.log_level:
print(os.path.abspath(self.log_location))
file_logger = logging.handlers.RotatingFileHandler(f'{self.log_location}/bot.log',
mode='a', maxBytes=5000, encoding="UTF-8", delay=0, backupCount=5)
print(f"Logging directory: {self.log_location}")
file_logger = logging.handlers.RotatingFileHandler(f'{self.log_location}/bot.log', mode='a',
maxBytes=5000, encoding="UTF-8", delay=0, backupCount=5)
file_logger.setLevel(self.log_level)
file_logger.setFormatter(log_formatter)
self.bot_logger.addHandler(file_logger)
@@ -35,4 +36,3 @@ class BotLogger(object):
console_handler.setFormatter(log_formatter)
self.bot_logger.addHandler(console_handler)
+11 -18
View File
@@ -1,14 +1,10 @@
import time
import lavalink
from collections import OrderedDict, deque
from itertools import cycle, islice, chain
from random import shuffle
from lavalink.events import (TrackStartEvent, TrackStuckEvent,
TrackExceptionEvent, TrackEndEvent,
QueueEndEvent, PlayerUpdateEvent,
NodeChangedEvent)
from lavalink.events import TrackStartEvent, TrackStuckEvent, TrackExceptionEvent, TrackEndEvent, QueueEndEvent
from lavalink import Node, DefaultPlayer, AudioTrack
@@ -22,11 +18,9 @@ class MixPlayer(DefaultPlayer):
self.skip_voters = set()
self.boosted = False
def add(self, requester: int, track: dict, pos: int=None):
def add(self, requester: int, track: dict, pos: int = None):
""" Adds a track to the queue. """
return self.queue.add_track(requester,
AudioTrack.build(track, requester),
pos)
return self.queue.add_track(requester, AudioTrack.build(track, requester), pos)
def add_next(self, requester: int, track: dict):
""" Adds a track to beginning of the queue """
@@ -51,7 +45,7 @@ class MixPlayer(DefaultPlayer):
""" Randomly reorders the queue of requester """
self.queue.shuffle_user_queue(requester)
def user_queue(self, user: int, dual: bool=False):
def user_queue(self, user: int, dual: bool = False):
return self.queue.get_user_queue(user, dual)
def global_queue(self):
@@ -60,7 +54,7 @@ class MixPlayer(DefaultPlayer):
def get_history(self):
return self.queue.history
def queue_duration(self, include_current: bool=True):
def queue_duration(self, include_current: bool = True):
duration = 0
for track in self.queue:
duration += track.duration
@@ -69,7 +63,7 @@ class MixPlayer(DefaultPlayer):
return lavalink.Utils.format_time(duration + remaining)
return lavalink.Utils.format_time(duration)
async def play(self, track: AudioTrack=None, start_time: int=0):
async def play(self, track: AudioTrack = None, start_time: int = 0):
self.current = None
self.last_update = 0
@@ -91,7 +85,7 @@ class MixPlayer(DefaultPlayer):
track=track.track, startTime=start_time)
await self.node._dispatch_event(TrackStartEvent(self, track))
async def skip(self, pos: int=0):
async def skip(self, pos: int = 0):
""" Plays the next track in the queue, if any. """
for i in range(pos):
_ = self.queue.pop_first()
@@ -125,7 +119,7 @@ class MixPlayer(DefaultPlayer):
self.skip_voters.clear()
await self.play()
async def bassboost(self, boost: bool=False):
async def bassboost(self, boost: bool = False):
if boost:
gains = [
(0, 0.15),
@@ -161,7 +155,7 @@ class MixQueue:
def __init__(self):
self.queues = OrderedDict()
self.priority_queue = []
self._history = deque(maxlen=11) # 10 + current
self._history = deque(maxlen=11) # 10 + current
def __str__(self):
tmp = ''
@@ -193,7 +187,7 @@ class MixQueue:
self.priority_queue = []
# if dual is true also returns global positions of tracks
def get_user_queue(self, requester: int, dual: bool=False):
def get_user_queue(self, requester: int, dual: bool = False):
queue = self.queues.get(requester, [])
if dual and queue:
pos = [self._loc_to_glob(requester, i) for i in range(len(queue))]
@@ -215,7 +209,7 @@ class MixQueue:
except KeyError:
pass
def add_track(self, requester: int, track: AudioTrack, pos: int=None):
def add_track(self, requester: int, track: AudioTrack, pos: int = None):
user_queue = self.queues.get(requester)
if user_queue is None:
self.queues[requester] = [track]
@@ -323,4 +317,3 @@ class MixQueue:
@property
def history(self):
return list(reversed(self._history))
+13 -20
View File
@@ -21,10 +21,8 @@ class BasePaginator:
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),
**kvpairs))
page.set_footer(text=localizer.format_str(localizer_str, _current=i,
_total=len(self._pages), **kvpairs))
else:
for i, page in enumerate(self._pages, start=1):
page.set_footer(text=f"{i}/{len(self._pages)}")
@@ -110,31 +108,26 @@ class FieldPaginator(BasePaginator):
class QueuePaginator(TextPaginator):
def __init__(self, localizer, queue, color, user_name: str=None):
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))
title = localizer.format_str("{queue.length}", _length=len(queue))
else:
title = localizer.format_str("{queue.userqueue}",
_user=user_name,
_length=len(queue))
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)
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)
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}")
@@ -286,14 +279,14 @@ class Scroller:
await self.message.delete()
if self.clear_command:
await self.cmdmsg.delete()
except:
except discord.Forbidden:
pass
finally:
break
try:
await self.message.remove_reaction(reaction, user)
except:
except discord.Forbidden:
pass
await self.match()
await self.match()
+6 -5
View File
@@ -1,11 +1,12 @@
import os
import codecs
import locale
import locale as localee
import yaml
class Settings:
def __init__(self, **default_settings):
self._DATA_PATH = 'data/bot/'
def __init__(self, datadir, **default_settings):
self._DATA_PATH = f"{datadir}/bot/"
self._SETTINGS_PATH = self._DATA_PATH + 'settings.yaml'
self.default_prefix = default_settings["prefix"]
@@ -15,7 +16,7 @@ class Settings:
self.default_is_dynamic = default_settings["dynamic max duration"]
if not self.default_locale:
locale, codepage = locale.getlocale()
locale, codepage = localee.getlocale()
default_locale, default_codepage = locale.getdefaultlocale()
self.default_locale = locale or default_locale
@@ -35,7 +36,7 @@ class Settings:
if val is None:
try:
d.pop(key)
except:
except KeyError:
pass
else:
d[key] = val
+1
View File
@@ -6,6 +6,7 @@ bot:
**Python:** [{_python_v}](https://www.python.org/)
**Discord.py:** [{_discord_v}](https://github.com/Rapptz/discord.py/tree/rewrite)
**Lavalink:** [{_lavalink_v}](https://github.com/Devoxin/Lavalink.py)
**ShiteMusicBot:** {_bot_v}
stattext: |-
**Guilds:** {_guilds}
**Users:** {_members}
+1
View File
@@ -6,6 +6,7 @@ bot:
**Python:** [{_python_v}](https://www.python.org/)
**Discord.py:** [{_discord_v}](https://github.com/Rapptz/discord.py/tree/rewrite)
**Lavalink:** [{_lavalink_v}](https://github.com/Devoxin/Lavalink.py)
**ShiteMusicBot:** {_bot_v}
stattext: |-
**Tenarar:** {_guilds}
**Brukere:** {_members}