Skip to content
This repository has been archived by the owner on Sep 14, 2022. It is now read-only.

Commit

Permalink
Merge pull request #105 from yannickgloster/logging
Browse files Browse the repository at this point in the history
Add logging
  • Loading branch information
lexesj authored Nov 16, 2020
2 parents 99248fb + eacd1c4 commit 57565a2
Show file tree
Hide file tree
Showing 10 changed files with 312 additions and 82 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ result.png
# Config Files
config.json

# Logs
bot.log
everything.log

# Database
main.sqlite

Expand Down
21 changes: 12 additions & 9 deletions bot.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import discord
import logging
import pprint

from databases import Database
from discord.ext import commands
from logging.config import fileConfig
from typing import List
from utils.server import WebServer
from utils.csgo_server import CSGOServer


__version__ = '1.6.3'
__version__ = '1.7.0'
__dev__ = 745000319942918303


class Discord_10man(commands.Bot):
def __init__(self, config: dict, startup_extensions: List[str]):
# commands.when_mentioned_or('e!')
Expand All @@ -22,6 +24,11 @@ def __init__(self, config: dict, startup_extensions: List[str]):
reactions=True, guild_reactions=True, dm_reactions=True, typing=True, guild_typing=True,
dm_typing=True
))
fileConfig('logging.conf')
self.logger = logging.getLogger(f'10man.{__name__}')
self.logger.debug(f'Version = {__version__}')
self.logger.debug(f'config.json = \n {pprint.pformat(config)}')

self.token: str = config['discord_token']
self.bot_IP: str = config['bot_IP']
if 'bot_port' in config:
Expand All @@ -46,12 +53,6 @@ def __init__(self, config: dict, startup_extensions: List[str]):
self.connect_dm = False
self.queue_captains: List[discord.Member] = []

logger = logging.getLogger('discord')
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler(filename='discord.log', encoding='utf-8', mode='w')
handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
logger.addHandler(handler)

for extension in startup_extensions:
self.load_extension(f'cogs.{extension}')

Expand All @@ -71,9 +72,10 @@ async def on_ready(self):
name='CSGO Pug'))

self.dev = self.user.id == __dev__
self.logger.debug(f'Dev = {self.dev}')

await self.web_server.http_start()
print(f'{self.user} connected.')
self.logger.info(f'{self.user} connected.')

async def load(self, extension: str):
self.load_extension(f'cogs.{extension}')
Expand All @@ -82,6 +84,7 @@ async def unload(self, extension: str):
self.unload_extension(f'cogs.{extension}')

async def close(self):
self.logger.warning('Stopping Bot')
await self.web_server.http_stop()
await super().close()

Expand Down
4 changes: 3 additions & 1 deletion checks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging

from databases import Database
from discord.ext import commands

from logging.config import fileConfig

async def voice_channel(ctx: commands.Context):
if ctx.author.voice is None:
Expand Down
84 changes: 70 additions & 14 deletions cogs/csgo.py

Large diffs are not rendered by default.

82 changes: 70 additions & 12 deletions cogs/setup.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
import checks
import discord
import logging
import traceback
import valve.rcon

from bot import Discord_10man
from databases import Database
from discord.ext import commands
from logging.config import fileConfig
from steam.steamid import SteamID, from_url
from typing import List


class Setup(commands.Cog):
def __init__(self, bot: Discord_10man):
fileConfig('logging.conf')
self.logger = logging.getLogger(f'10man.{__name__}')
self.bot: Discord_10man = bot

self.logger.debug(f'Loaded {__name__}')

@commands.command(aliases=['login'],
help='This command connects users steam account to the bot.',
brief='Connect your SteamID to the bot', usage='<SteamID or CommunityURL>')
async def link(self, ctx: commands.Context, steamID_input: str):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
steamID = SteamID(steamID_input)
if not steamID.is_valid():
steamID = from_url(steamID_input, http_timeout=15)
Expand All @@ -33,36 +40,44 @@ async def link(self, ctx: commands.Context, steamID_input: str):
''', {"discord_id": str(ctx.author.id), "steam_id": str(steamID.as_steam2_zero)})
embed = discord.Embed(description=f'Connected {ctx.author.mention} \n `{steamID.as_steam2}`', color=0x00FF00)
await ctx.send(embed=embed)
self.logger.info(f'{ctx.author} connected to {steamID.as_steam2}')

@link.error
async def link_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.UserInputError):
await ctx.send(str(error))
traceback.print_exc()
self.logger.warning(f'{ctx.author} did not enter a valid SteamID')
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(aliases=['spectator', 'spec'],
help='Adds this user as a spectator in the config for the next map.',
brief='Add user as spectator', usage='<@User>')
@commands.has_permissions(administrator=True)
async def add_spectator(self, ctx: commands.Context, spec: discord.Member):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
db = Database('sqlite:///main.sqlite')
await db.connect()
data = await db.fetch_one('SELECT 1 FROM users WHERE discord_id = :spectator', {"spectator": str(spec.id)})
if data is None:
raise commands.UserInputError(message=f'<@{spec.id}> needs to `.link` their account.')
self.bot.spectators.append(spec)
await ctx.send(f'<@{spec.id}> was added as a spectator.')
self.logger.info(f'{ctx.author} was added as a spectator')

@add_spectator.error
async def add_spectator_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.UserInputError):
await ctx.send(str(error))
traceback.print_exc()
self.logger.warning(str(error))
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(aliases=['queue_captain', 'captain'],
help='Set\'s the queue captain for the next match', usage='<@User> ?<@User>')
@commands.has_permissions(administrator=True)
async def set_queue_captain(self, ctx: commands.Context, *args: discord.Member):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
db = Database('sqlite:///main.sqlite')
await db.connect()
for captain in args:
Expand All @@ -71,25 +86,36 @@ async def set_queue_captain(self, ctx: commands.Context, *args: discord.Member):
raise commands.UserInputError(message=f'<@{captain.id}> needs to `.link` their account.')
self.bot.queue_captains.append(captain)
await ctx.send(f'<@{captain.id}> was added as a captain for the next queue.')
self.logger.debug(f'<@{captain.id}> was added as a captain for the next queue.')
self.logger.debug(f'Current Queue Captains: {self.bot.queue_captains}')

@set_queue_captain.error
async def set_queue_captain_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.UserInputError):
await ctx.send(str(error))
traceback.print_exc()
self.logger.debug(str(error))
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(aliases=['empty'],
help='Empties the queue')
@commands.has_permissions(administrator=True)
async def empty_queue(self, ctx: commands.Context):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
for member in self.bot.queue_voice_channel.members:
await member.move_to(channel=None, reason=f'Admin cleared the queue')
self.logger.debug(f'Admin cleared the queue')

@empty_queue.error
async def empty_queue_error(self, ctx: commands.Context, error: Exception):
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(aliases=['remove_spec'],
help='Removes this user as a spectator from the config.',
brief='Removes user as spectator', usage='<@User>')
@commands.has_permissions(administrator=True)
async def remove_spectator(self, ctx: commands.Context, spec: discord.Member):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
db = Database('sqlite:///main.sqlite')
await db.connect()
data = await db.fetch_one('SELECT 1 FROM users WHERE discord_id = :spectator',
Expand All @@ -99,21 +125,25 @@ async def remove_spectator(self, ctx: commands.Context, spec: discord.Member):
message=f'User did not `.link` their account and probably is not a spectator.')
if data[0] in self.bot.spectators:
self.bot.spectators.remove(spec)
await ctx.send(f'<@{spec.id}> was added as a spectator.')
await ctx.send(f'<@{spec.id}> was removed as a spectator.')
self.logger.debug(f'<@{spec.id}> was removed as a spectator.')
else:
raise commands.CommandError(message=f'<@{spec.id}> is not a spectator.')

@remove_spectator.error
async def remove_spectator_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.UserInputError) or isinstance(error, commands.CommandError):
await ctx.send(str(error))
traceback.print_exc()
self.logger.warning(str(error))
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(aliases=['dm'],
help='Command to enable or disable sending a dm with the connect ip vs posting it in the channel',
brief='Enable or disable connect via dm')
@commands.has_permissions(administrator=True)
async def connect_dm(self, ctx: commands.Context, enabled: bool = False):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
self.bot.connect_dm = enabled
await ctx.send(f'Connect message will {"not" if not enabled else ""} be sent via a DM.')

Expand All @@ -123,17 +153,23 @@ async def connect_dm(self, ctx: commands.Context, enabled: bool = False):
@commands.has_permissions(administrator=True)
@commands.check(checks.voice_channel)
async def setup_queue(self, ctx: commands.Context, enabled: bool = True):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
self.bot.queue_voice_channel = ctx.author.voice.channel
self.bot.queue_ctx = ctx
if enabled:
if self.bot.cogs['CSGO'].queue_check.is_running():
self.bot.cogs['CSGO'].queue_check.restart()
self.logger.warning(f'Queue Restarted')
else:
self.bot.cogs['CSGO'].queue_check.start()
self.logger.debug('Queue Started')
self.bot.cogs['CSGO'].pug.enabled = False
self.logger.debug('Pug Disabled')
self.logger.debug(f'Queue Channel: {self.bot.queue_ctx.author.voice.channel}')
else:
self.bot.cogs['CSGO'].queue_check.stop()
self.bot.cogs['CSGO'].pug.enabled = True
self.logger.debug('Queue Disabled, Pug Enabled')
await ctx.send(
f'{self.bot.queue_ctx.author.voice.channel} is the queue channel.\n'
f'Queue is {"enabled" if enabled else "disabled"}.\n'
Expand All @@ -143,30 +179,37 @@ async def setup_queue(self, ctx: commands.Context, enabled: bool = True):
async def setup_queue_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.CommandError):
await ctx.send(str(error))
traceback.print_exc()
self.logger.warning(str(error))
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(aliases=['restart_queue'],
help='The command forcefully restarts the queue.',
brief='Restart\'s the queue')
@commands.has_permissions(administrator=True)
@commands.check(checks.queue_running)
async def force_restart_queue(self, ctx: commands.Context):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
self.bot.cogs['CSGO'].queue_check.cancel()
self.bot.cogs['CSGO'].queue_check.start()
self.bot.cogs['CSGO'].pug.enabled = False
await ctx.send('Queue forcefully restarted')
self.logger.warning('Queue forcefully restarted')

@force_restart_queue.error
async def force_restart_queue_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.CommandError):
await ctx.send(str(error))
traceback.print_exc()
self.logger.warning(str(error))
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(aliases=['setup_queue_size', 'match_size', 'queue_size', 'set_match_size', 'set_queue_size'],
help='This command sets the size of the match and the queue.',
brief='Sets the size of the match & queue', usage='<size>')
@commands.has_permissions(administrator=True)
async def setup_match_size(self, ctx: commands.Context, size: int):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
if size <= 0:
raise commands.CommandError(message=f'Invalid match size.')
if size % 2 != 0:
Expand All @@ -175,60 +218,75 @@ async def setup_match_size(self, ctx: commands.Context, size: int):
if self.bot.cogs['CSGO'].queue_check.is_running():
self.bot.cogs['CSGO'].queue_check.restart()
await ctx.send(f'Set match size to {self.bot.match_size}.')
self.logger.debug(f'Set match size to {self.bot.match_size}.')

@setup_match_size.error
async def setup_match_size_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.BadArgument):
await ctx.send('Invalid Argument')
self.logger.warning('Invalid Argument')
elif isinstance(error, commands.CommandError):
await ctx.send(str(error))
traceback.print_exc()
self.logger.warning(str(error))
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(help='Command to send a test message to the server to verify that RCON is working.',
brief='Sends a message to the server to test RCON', usage='<message>')
@commands.has_permissions(administrator=True)
async def RCON_message(self, ctx: commands.Context, *, message: str):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
for server in self.bot.servers:
test_message = valve.rcon.execute((server.server_address, server.server_port), server.RCON_password,
f'say {message}')
print(f'Server #{server.id} | {test_message}')
self.logger.debug(f'Server #{server.id} | {test_message}')

@RCON_message.error
async def RCON_message_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.MissingPermissions):
await ctx.send('Only an administrator can send a message using the console')
if isinstance(error, commands.MissingRequiredArgument):
self.logger.warning('Only an administrator can send a message using the console')
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send('Please specify the message')
traceback.print_exc()
self.logger.warning('Please specify the message')
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(help='This command unbans everyone on the server. Useful fix.',
brief='Unbans everyone from the server', hidden=True)
@commands.has_permissions(administrator=True)
async def RCON_unban(self, ctx: commands.Context):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
for server in self.bot.servers:
unban = valve.rcon.execute((server.server_address, server.server_port), server.RCON_password,
'removeallids')
print(f'Server #{server.id} | {unban}')
self.logger.debug(f'Server #{server.id} | {unban}')

@RCON_unban.error
async def RCON_unban_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.MissingPermissions):
await ctx.send('Only an administrator can unban every player')
traceback.print_exc()
self.logger.warning('Only an administrator can unban every player')
else:
self.logger.exception(f'{ctx.command} caused an exception')

@commands.command(aliases=['end', 'stop'],
help='This command force ends a match.',
brief='Force ends a match', usage='<ServerID>')
@commands.has_permissions(administrator=True)
async def force_end(self, ctx: commands.Context, server_id: int = 0):
self.logger.debug(f'{ctx.author}: {ctx.prefix}{ctx.invoked_with} {ctx.args[2:]}')
valve.rcon.execute((self.bot.servers[server_id].server_address, self.bot.servers[server_id].server_port),
self.bot.servers[server_id].RCON_password, 'get5_endmatch')

@force_end.error
async def force_end_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.MissingPermissions):
await ctx.send('Only an administrator can force end a match.')
traceback.print_exc()
else:
self.logger.exception(f'{ctx.command} caused an exception')


def setup(client):
Expand Down
Loading

0 comments on commit 57565a2

Please sign in to comment.