diff options
36 files changed, 252 insertions, 167 deletions
diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..159e4f4c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +# Exclude everything +* + +# Make exceptions for what's needed +!bot +!Pipfile +!Pipfile.lock +!LICENSE @@ -4,7 +4,7 @@ verify_ssl = true name = "pypi" [packages] -discord-py = {ref = "3f06f24",git = "https://github.com/Rapptz/discord.py",editable = true} +discord-py = {ref = "42a7c4f",git = "https://github.com/Rapptz/discord.py",editable = true} arrow = "*" beautifulsoup4 = "*" aiodns = "*" diff --git a/Pipfile.lock b/Pipfile.lock index bedfcbc1..5b57c32e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "fddb61c7f26286f78d74b41302f5afab456b3630bd93796030690dd87b22dec3" + "sha256": "d8e3a7f796632bf80bc0c0b8ed2162d3f39aa91e8afa424d3ae85f2210a71923" }, "pipfile-spec": 6, "requires": { @@ -125,7 +125,7 @@ "discord-py": { "editable": true, "git": "https://github.com/Rapptz/discord.py", - "ref": "3f06f247c039a23948e7bb0014ea31db533b4ba2" + "ref": "42a7c4f7e5caa7baf555e86b52249419ce33acfc" }, "fuzzywuzzy": { "hashes": [ @@ -267,29 +267,29 @@ }, "websockets": { "hashes": [ - "sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136", - "sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6", - "sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1", - "sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538", - "sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4", - "sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908", - "sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0", - "sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d", - "sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c", - "sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d", - "sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c", - "sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb", - "sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf", - "sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e", - "sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96", - "sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584", - "sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484", - "sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d", - "sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559", - "sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff", - "sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454" - ], - "version": "==6.0" + "sha256:04b42a1b57096ffa5627d6a78ea1ff7fad3bc2c0331ffc17bc32a4024da7fea0", + "sha256:08e3c3e0535befa4f0c4443824496c03ecc25062debbcf895874f8a0b4c97c9f", + "sha256:10d89d4326045bf5e15e83e9867c85d686b612822e4d8f149cf4840aab5f46e0", + "sha256:232fac8a1978fc1dead4b1c2fa27c7756750fb393eb4ac52f6bc87ba7242b2fa", + "sha256:4bf4c8097440eff22bc78ec76fe2a865a6e658b6977a504679aaf08f02c121da", + "sha256:51642ea3a00772d1e48fb0c492f0d3ae3b6474f34d20eca005a83f8c9c06c561", + "sha256:55d86102282a636e195dad68aaaf85b81d0bef449d7e2ef2ff79ac450bb25d53", + "sha256:564d2675682bd497b59907d2205031acbf7d3fadf8c763b689b9ede20300b215", + "sha256:5d13bf5197a92149dc0badcc2b699267ff65a867029f465accfca8abab95f412", + "sha256:5eda665f6789edb9b57b57a159b9c55482cbe5b046d7db458948370554b16439", + "sha256:5edb2524d4032be4564c65dc4f9d01e79fe8fad5f966e5b552f4e5164fef0885", + "sha256:79691794288bc51e2a3b8de2bc0272ca8355d0b8503077ea57c0716e840ebaef", + "sha256:7fcc8681e9981b9b511cdee7c580d5b005f3bb86b65bde2188e04a29f1d63317", + "sha256:8e447e05ec88b1b408a4c9cde85aa6f4b04f06aa874b9f0b8e8319faf51b1fee", + "sha256:90ea6b3e7787620bb295a4ae050d2811c807d65b1486749414f78cfd6fb61489", + "sha256:9e13239952694b8b831088431d15f771beace10edfcf9ef230cefea14f18508f", + "sha256:d40f081187f7b54d7a99d8a5c782eaa4edc335a057aa54c85059272ed826dc09", + "sha256:e1df1a58ed2468c7b7ce9a2f9752a32ad08eac2bcd56318625c3647c2cd2da6f", + "sha256:e98d0cec437097f09c7834a11c69d79fe6241729b23f656cfc227e93294fc242", + "sha256:f8d59627702d2ff27cb495ca1abdea8bd8d581de425c56e93bff6517134e0a9b", + "sha256:fc30cdf2e949a2225b012a7911d1d031df3d23e99b7eda7dfc982dc4a860dae9" + ], + "version": "==7.0" }, "yarl": { "hashes": [ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f81f1139..c98bc4fc 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,12 +1,5 @@ # https://aka.ms/yaml -variables: - LIBRARY_PATH: /lib:/usr/lib - PIPENV_HIDE_EMOJIS: 1 - PIPENV_IGNORE_VIRTUALENVS: 1 - PIPENV_NOSPIN: 1 - PIPENV_VENV_IN_PROJECT: 1 - jobs: - job: test displayName: 'Lint & Test' @@ -15,37 +8,34 @@ jobs: vmImage: 'Ubuntu 16.04' variables: - PIPENV_CACHE_DIR: ".cache/pipenv" PIP_CACHE_DIR: ".cache/pip" PIP_SRC: ".cache/src" + PIPENV_CACHE_DIR: ".cache/pipenv" + PIPENV_DONT_USE_PYENV: 1 + PIPENV_HIDE_EMOJIS: 1 + PIPENV_IGNORE_VIRTUALENVS: 1 + PIPENV_NOSPIN: 1 steps: - - script: sudo apt-get install build-essential curl docker libffi-dev libfreetype6-dev libxml2 libxml2-dev libxslt1-dev zlib1g zlib1g-dev - displayName: 'Install base dependencies' - - task: UsePythonVersion@0 displayName: 'Set Python version' inputs: versionSpec: '3.7.x' addToPath: true - - script: sudo pip install pipenv + - script: pip3 install pipenv displayName: 'Install pipenv' - script: pipenv install --dev --deploy --system displayName: 'Install project using pipenv' - - script: python -m flake8 + - script: python3 -m flake8 displayName: 'Run linter' - job: build displayName: 'Build Containers' dependsOn: 'test' - variables: - PIPENV_CACHE_DIR: ".cache/pipenv" - PIP_CACHE_DIR: ".cache/pip" - steps: - task: Docker@1 displayName: 'Login: Docker Hub' @@ -55,12 +45,6 @@ jobs: dockerRegistryEndpoint: 'DockerHub' command: 'login' - - script: sudo apt-get install python3-setuptools - displayName: 'Install setuptools' - - - script: sudo pip3 install salt-pepper - displayName: 'Install pepper' - - task: ShellScript@2 displayName: 'Build and deploy containers' diff --git a/bot/__init__.py b/bot/__init__.py index dc97df3d..21ff8c97 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -1,3 +1,4 @@ +import logging import logging.handlers import os from pathlib import Path @@ -6,25 +7,45 @@ import arrow from bot.constants import Client -# start datetime + +# Configure the "TRACE" logging level (e.g. "log.trace(message)") +logging.TRACE = 5 +logging.addLevelName(logging.TRACE, "TRACE") + + +def monkeypatch_trace(self, msg, *args, **kwargs): + """ + Log 'msg % args' with severity 'TRACE'. + + To pass exception information, use the keyword argument exc_info with a true value, e.g. + logger.trace("Houston, we have an %s", "interesting problem", exc_info=1) + """ + + if self.isEnabledFor(logging.TRACE): + self._log(logging.TRACE, msg, args, **kwargs) + + +logging.Logger.trace = monkeypatch_trace + +# Set timestamp of when execution started (approximately) start_time = arrow.utcnow() -# set up logging +# Set up file logging log_dir = Path("bot", "log") log_file = log_dir / "hackbot.log" os.makedirs(log_dir, exist_ok=True) -# file handler sets up rotating logs every 5 MB +# File handler rotates logs every 5 MB file_handler = logging.handlers.RotatingFileHandler( log_file, maxBytes=5*(2**20), backupCount=10) -file_handler.setLevel(logging.DEBUG) +file_handler.setLevel(logging.TRACE if Client.debug else logging.DEBUG) -# console handler prints to terminal +# Console handler prints to terminal console_handler = logging.StreamHandler() -level = logging.DEBUG if Client.debug else logging.INFO +level = logging.TRACE if Client.debug else logging.INFO console_handler.setLevel(level) -# remove old loggers if any +# Remove old loggers, if any root = logging.getLogger() if root.handlers: for handler in root.handlers: @@ -34,11 +55,11 @@ if root.handlers: logging.getLogger("discord").setLevel(logging.ERROR) logging.getLogger("websockets").setLevel(logging.ERROR) -# setup new logging configuration +# Setup new logging configuration logging.basicConfig( format='%(asctime)s - %(name)s %(levelname)s: %(message)s', datefmt="%D %H:%M:%S", - level=logging.DEBUG, + level=logging.TRACE if Client.debug else logging.DEBUG, handlers=[console_handler, file_handler] ) logging.getLogger().info('Logging initialization complete') @@ -6,7 +6,6 @@ from typing import List from aiohttp import AsyncResolver, ClientSession, TCPConnector from discord import Embed from discord.ext import commands -from discord.ext.commands import Bot from bot import constants @@ -15,16 +14,13 @@ log = logging.getLogger(__name__) __all__ = ('SeasonalBot',) -class SeasonalBot(Bot): +class SeasonalBot(commands.Bot): """Base bot instance.""" def __init__(self, **kwargs): super().__init__(**kwargs) self.http_session = ClientSession( - connector=TCPConnector( - resolver=AsyncResolver(), - family=socket.AF_INET, - ) + connector=TCPConnector(resolver=AsyncResolver(), family=socket.AF_INET) ) def load_extensions(self, exts: List[str]): diff --git a/bot/resources/evergreen/magic8ball.json b/bot/resources/evergreen/magic8ball.json new file mode 100644 index 00000000..6fe86950 --- /dev/null +++ b/bot/resources/evergreen/magic8ball.json @@ -0,0 +1,22 @@ +[ + "It is certain", + "It is decidedly so", + "Without a doubt", + "Yes definitely", + "You may rely on it", + "As I see it, yes", + "Most likely", + "Outlook good", + "Yes", + "Signs point to yes", + "Reply hazy try again", + "Ask again later", + "Better not tell you now", + "Cannot predict now", + "Concentrate and ask again", + "Don't count on it", + "My reply is no", + "My sources say no", + "Outlook not so good", + "Very doubtful" +]
\ No newline at end of file diff --git a/bot/seasons/__init__.py b/bot/seasons/__init__.py index c43334a4..1512fae2 100644 --- a/bot/seasons/__init__.py +++ b/bot/seasons/__init__.py @@ -9,4 +9,4 @@ log = logging.getLogger(__name__) def setup(bot): bot.add_cog(SeasonManager(bot)) - log.debug("SeasonManager cog loaded") + log.info("SeasonManager cog loaded") diff --git a/bot/seasons/christmas/adventofcode.py b/bot/seasons/christmas/adventofcode.py index 2fd474db..f61f34b5 100644 --- a/bot/seasons/christmas/adventofcode.py +++ b/bot/seasons/christmas/adventofcode.py @@ -714,4 +714,4 @@ def setup(bot: commands.Bot) -> None: """Advent of Code Cog load.""" bot.add_cog(AdventOfCode(bot)) - log.info("Cog loaded: adventofcode") + log.info("AdventOfCode cog loaded") diff --git a/bot/seasons/easter/__init__.py b/bot/seasons/easter/__init__.py new file mode 100644 index 00000000..c1de5811 --- /dev/null +++ b/bot/seasons/easter/__init__.py @@ -0,0 +1,18 @@ +from bot.seasons import SeasonBase + + +class Easter(SeasonBase): + """ + Easter is a beautiful time of the year often celebrated after the first Full Moon of the new spring season. + + This time is quite beautiful due to the colorful flowers coming out to greet us. So let's greet Spring + in an Easter celebration of contributions. + """ + + name = "easter" + bot_name = "BunnyBot" + greeting = "Happy Easter to us all!" + + # Duration of season + start_date = "01/04" + end_date = "30/04" diff --git a/bot/seasons/evergreen/error_handler.py b/bot/seasons/evergreen/error_handler.py index dcdbe4e9..b0d05c41 100644 --- a/bot/seasons/evergreen/error_handler.py +++ b/bot/seasons/evergreen/error_handler.py @@ -14,101 +14,93 @@ class CommandErrorHandler: def __init__(self, bot):
self.bot = bot
+ @staticmethod
+ def revert_cooldown_counter(command, message):
+ """Undoes the last cooldown counter for user-error cases."""
+ if command._buckets.valid:
+ bucket = command._buckets.get_bucket(message)
+ bucket._tokens = min(bucket.rate, bucket._tokens + 1)
+ logging.debug(
+ "Cooldown counter reverted as the command was not used correctly."
+ )
+
+ @commands.Cog.listener()
async def on_command_error(self, ctx, error):
"""Activates when a command opens an error."""
if hasattr(ctx.command, 'on_error'):
return logging.debug(
- "A command error occured but "
- "the command had it's own error handler"
+ "A command error occured but the command had it's own error handler."
)
+
error = getattr(error, 'original', error)
+
if isinstance(error, commands.CommandNotFound):
return logging.debug(
- f"{ctx.author} called '{ctx.message.content}' "
- "but no command was found"
+ f"{ctx.author} called '{ctx.message.content}' but no command was found."
)
+
if isinstance(error, commands.UserInputError):
logging.debug(
- f"{ctx.author} called the command '{ctx.command}' "
- "but entered invalid input!"
+ f"{ctx.author} called the command '{ctx.command}' but entered invalid input!"
)
+
+ self.revert_cooldown_counter(ctx.command, ctx.message)
+
return await ctx.send(
- ":no_entry: The command you specified failed to run."
+ ":no_entry: The command you specified failed to run. "
"This is because the arguments you provided were invalid."
)
+
if isinstance(error, commands.CommandOnCooldown):
logging.debug(
- f"{ctx.author} called the command '{ctx.command}' "
- "but they were on cooldown!"
+ f"{ctx.author} called the command '{ctx.command}' but they were on cooldown!"
)
- seconds = error.retry_after
- remaining_minutes, remaining_seconds = divmod(seconds, 60)
- time_remaining = f'{int(remaining_minutes)} minutes {math.ceil(remaining_seconds)} seconds'
+ remaining_minutes, remaining_seconds = divmod(error.retry_after, 60)
+
return await ctx.send(
- "This command is on cooldown,"
- f" please retry in {time_remaining}."
+ "This command is on cooldown, please retry in "
+ f"{int(remaining_minutes)} minutes {math.ceil(remaining_seconds)} seconds."
)
+
if isinstance(error, commands.DisabledCommand):
logging.debug(
- f"{ctx.author} called the command '{ctx.command}' "
- "but the command was disabled!"
- )
- return await ctx.send(
- ":no_entry: This command has been disabled."
+ f"{ctx.author} called the command '{ctx.command}' but the command was disabled!"
)
+ return await ctx.send(":no_entry: This command has been disabled.")
+
if isinstance(error, commands.NoPrivateMessage):
logging.debug(
f"{ctx.author} called the command '{ctx.command}' "
"in a private message however the command was guild only!"
)
- return await ctx.author.send(
- ":no_entry: This command can only be used inside a server."
- )
+ return await ctx.author.send(":no_entry: This command can only be used in the server.")
+
if isinstance(error, commands.BadArgument):
- if ctx.command.qualified_name == 'tag list':
- logging.debug(
- f"{ctx.author} called the command '{ctx.command}' "
- "but entered an invalid user!"
- )
- return await ctx.send(
- "I could not find that member. Please try again."
- )
- else:
- logging.debug(
- f"{ctx.author} called the command '{ctx.command}' "
- "but entered a bad argument!"
- )
- return await ctx.send(
- "The argument you provided was invalid."
- )
- if isinstance(error, commands.CheckFailure):
+ self.revert_cooldown_counter(ctx.command, ctx.message)
+
logging.debug(
- f"{ctx.author} called the command '{ctx.command}' "
- "but the checks failed!"
- )
- return await ctx.send(
- ":no_entry: You are not authorized to use this command."
+ f"{ctx.author} called the command '{ctx.command}' but entered a bad argument!"
)
- print(
- f"Ignoring exception in command {ctx.command}:",
- file=sys.stderr
- )
+ return await ctx.send("The argument you provided was invalid.")
+
+ if isinstance(error, commands.CheckFailure):
+ logging.debug(f"{ctx.author} called the command '{ctx.command}' but the checks failed!")
+ return await ctx.send(":no_entry: You are not authorized to use this command.")
+
+ print(f"Ignoring exception in command {ctx.command}:", file=sys.stderr)
+
logging.warning(
f"{ctx.author} called the command '{ctx.command}' "
"however the command failed to run with the error:"
f"-------------\n{error}"
)
- traceback.print_exception(
- type(error),
- error,
- error.__traceback__,
- file=sys.stderr
- )
+
+ traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
def setup(bot):
"""Error handler Cog load."""
bot.add_cog(CommandErrorHandler(bot))
- log.debug("CommandErrorHandler cog loaded")
+ log.info("CommandErrorHandler cog loaded")
diff --git a/bot/seasons/evergreen/fun.py b/bot/seasons/evergreen/fun.py index f5814a80..286d8462 100644 --- a/bot/seasons/evergreen/fun.py +++ b/bot/seasons/evergreen/fun.py @@ -33,4 +33,4 @@ def setup(bot): """Fun Cog load.""" bot.add_cog(Fun(bot)) - log.debug("Fun cog loaded") + log.info("Fun cog loaded") diff --git a/bot/seasons/evergreen/magic_8ball.py b/bot/seasons/evergreen/magic_8ball.py new file mode 100644 index 00000000..7b5f8e1a --- /dev/null +++ b/bot/seasons/evergreen/magic_8ball.py @@ -0,0 +1,33 @@ +import json +import logging +import random +from pathlib import Path + +from discord.ext import commands + +log = logging.getLogger(__name__) + + +class Magic8ball: + """A Magic 8ball command to respond to a users question.""" + + def __init__(self, bot): + self.bot = bot + with open(Path("bot", "resources", "evergreen", "magic8ball.json"), "r") as file: + self.answers = json.load(file) + + @commands.command(name="8ball") + async def output_answer(self, ctx, *, question): + """Return a magic 8 ball answer from answers list.""" + if len(question.split()) >= 3: + answer = random.choice(self.answers) + await ctx.send(answer) + else: + await ctx.send("Usage: .8ball <question> (minimum length of 3 eg: `will I win?`)") + + +def setup(bot): + """Magic 8ball cog load.""" + + bot.add_cog(Magic8ball(bot)) + log.info("Magic8ball cog loaded") diff --git a/bot/seasons/evergreen/snakes/__init__.py b/bot/seasons/evergreen/snakes/__init__.py index 88793308..5188200e 100644 --- a/bot/seasons/evergreen/snakes/__init__.py +++ b/bot/seasons/evergreen/snakes/__init__.py @@ -9,4 +9,4 @@ def setup(bot): """Snakes Cog load.""" bot.add_cog(Snakes(bot)) - log.info("Cog loaded: Snakes") + log.info("Snakes cog loaded") diff --git a/bot/seasons/evergreen/snakes/snakes_cog.py b/bot/seasons/evergreen/snakes/snakes_cog.py index dc5fb104..3ffdf1bf 100644 --- a/bot/seasons/evergreen/snakes/snakes_cog.py +++ b/bot/seasons/evergreen/snakes/snakes_cog.py @@ -15,7 +15,7 @@ import aiohttp import async_timeout from PIL import Image, ImageDraw, ImageFont from discord import Colour, Embed, File, Member, Message, Reaction -from discord.ext.commands import BadArgument, Bot, Context, bot_has_permissions, group +from discord.ext.commands import BadArgument, Bot, Cog, Context, bot_has_permissions, group from bot.constants import ERROR_REPLIES, Tokens from bot.decorators import locked @@ -132,7 +132,7 @@ CARD = { # endregion -class Snakes: +class Snakes(Cog): """ Commands related to snakes, created by our community during the first code jam. @@ -1198,10 +1198,3 @@ class Snakes: await ctx.send(embed=embed) # endregion - - -def setup(bot): - """Snake Cog load.""" - - bot.add_cog(Snakes(bot)) - log.info("Cog loaded: Snakes") diff --git a/bot/seasons/evergreen/uptime.py b/bot/seasons/evergreen/uptime.py index d6b59a69..4d5ac584 100644 --- a/bot/seasons/evergreen/uptime.py +++ b/bot/seasons/evergreen/uptime.py @@ -33,4 +33,4 @@ def setup(bot): """Uptime Cog load.""" bot.add_cog(Uptime(bot)) - log.debug("Uptime cog loaded") + log.info("Uptime cog loaded") diff --git a/bot/seasons/halloween/candy_collection.py b/bot/seasons/halloween/candy_collection.py index 1bfbc00a..2e010cbc 100644 --- a/bot/seasons/halloween/candy_collection.py +++ b/bot/seasons/halloween/candy_collection.py @@ -33,6 +33,7 @@ class CandyCollection: userid = userinfo['userid'] self.get_candyinfo[userid] = userinfo + @commands.Cog.listener() async def on_message(self, message): """Randomly adds candy or skull reaction to non-bot messages in the Event channel.""" @@ -54,6 +55,7 @@ class CandyCollection: self.msg_reacted.append(d) return await message.add_reaction('\N{CANDY}') + @commands.Cog.listener() async def on_reaction_add(self, reaction, user): """Add/remove candies from a person if the reaction satisfies criteria.""" @@ -225,4 +227,4 @@ def setup(bot): """Candy Collection game Cog load.""" bot.add_cog(CandyCollection(bot)) - log.debug("CandyCollection cog loaded") + log.info("CandyCollection cog loaded") diff --git a/bot/seasons/halloween/hacktoberstats.py b/bot/seasons/halloween/hacktoberstats.py index 3e2a261d..ce32ad9f 100644 --- a/bot/seasons/halloween/hacktoberstats.py +++ b/bot/seasons/halloween/hacktoberstats.py @@ -341,4 +341,4 @@ def setup(bot): """Hacktoberstats Cog load.""" bot.add_cog(HacktoberStats(bot)) - log.debug("HacktoberStats cog loaded") + log.info("HacktoberStats cog loaded") diff --git a/bot/seasons/halloween/halloween_facts.py b/bot/seasons/halloween/halloween_facts.py index 21c70e76..3ec65b87 100644 --- a/bot/seasons/halloween/halloween_facts.py +++ b/bot/seasons/halloween/halloween_facts.py @@ -36,6 +36,7 @@ class HalloweenFacts: self.facts = list(enumerate(self.halloween_facts)) random.shuffle(self.facts) + @commands.Cog.listener() async def on_ready(self): """Get event Channel object and initialize fact task loop.""" @@ -68,4 +69,4 @@ def setup(bot): """Halloween facts Cog load.""" bot.add_cog(HalloweenFacts(bot)) - log.debug("HalloweenFacts cog loaded") + log.info("HalloweenFacts cog loaded") diff --git a/bot/seasons/halloween/halloweenify.py b/bot/seasons/halloween/halloweenify.py index 5b710f7f..daf64ac0 100644 --- a/bot/seasons/halloween/halloweenify.py +++ b/bot/seasons/halloween/halloweenify.py @@ -11,7 +11,7 @@ log = logging.getLogger(__name__) class Halloweenify: - """A cog to change a invokers nickname to a spooky one.""" + """A cog to change a invokers nickname to a spooky one!""" def __init__(self, bot): self.bot = bot @@ -51,4 +51,4 @@ def setup(bot): """Halloweenify Cog load.""" bot.add_cog(Halloweenify(bot)) - log.debug("Halloweenify cog loaded") + log.info("Halloweenify cog loaded") diff --git a/bot/seasons/halloween/monstersurvey.py b/bot/seasons/halloween/monstersurvey.py index 44400a72..2ae98f6e 100644 --- a/bot/seasons/halloween/monstersurvey.py +++ b/bot/seasons/halloween/monstersurvey.py @@ -4,7 +4,7 @@ import os from discord import Embed from discord.ext import commands -from discord.ext.commands import Bot, Context +from discord.ext.commands import Bot, Cog, Context log = logging.getLogger(__name__) @@ -14,7 +14,7 @@ EMOJIS = { } -class MonsterSurvey: +class MonsterSurvey(Cog): """ Vote for your favorite monster. @@ -227,4 +227,4 @@ def setup(bot): """Monster survey Cog load.""" bot.add_cog(MonsterSurvey(bot)) - log.debug("MonsterSurvey cog loaded") + log.info("MonsterSurvey cog loaded") diff --git a/bot/seasons/halloween/scarymovie.py b/bot/seasons/halloween/scarymovie.py index 9108c76f..5651c9bb 100644 --- a/bot/seasons/halloween/scarymovie.py +++ b/bot/seasons/halloween/scarymovie.py @@ -133,4 +133,4 @@ def setup(bot): """Scary movie Cog load.""" bot.add_cog(ScaryMovie(bot)) - log.debug("ScaryMovie cog loaded") + log.info("ScaryMovie cog loaded") diff --git a/bot/seasons/halloween/spookyavatar.py b/bot/seasons/halloween/spookyavatar.py index 5c13ad77..042df701 100644 --- a/bot/seasons/halloween/spookyavatar.py +++ b/bot/seasons/halloween/spookyavatar.py @@ -52,4 +52,4 @@ def setup(bot): """Spooky avatar Cog load.""" bot.add_cog(SpookyAvatar(bot)) - log.debug("SpookyAvatar cog loaded") + log.info("SpookyAvatar cog loaded") diff --git a/bot/seasons/halloween/spookygif.py b/bot/seasons/halloween/spookygif.py index f898d28b..ce8aef06 100644 --- a/bot/seasons/halloween/spookygif.py +++ b/bot/seasons/halloween/spookygif.py @@ -10,7 +10,7 @@ log = logging.getLogger(__name__) class SpookyGif: - """A cog to fetch a random spooky gif from the web.""" + """A cog to fetch a random spooky gif from the web!""" def __init__(self, bot): self.bot = bot @@ -38,4 +38,4 @@ def setup(bot): """Spooky GIF Cog load.""" bot.add_cog(SpookyGif(bot)) - log.debug("SpookyGif cog loaded") + log.info("SpookyGif cog loaded") diff --git a/bot/seasons/halloween/spookyreact.py b/bot/seasons/halloween/spookyreact.py index 553bd285..f1dbb905 100644 --- a/bot/seasons/halloween/spookyreact.py +++ b/bot/seasons/halloween/spookyreact.py @@ -2,6 +2,7 @@ import logging import re import discord +from discord.ext.commands import Cog log = logging.getLogger(__name__) @@ -22,6 +23,7 @@ class SpookyReact: def __init__(self, bot): self.bot = bot + @Cog.listener() async def on_message(self, ctx: discord.Message): """ A command to send the seasonalbot github project. @@ -70,4 +72,4 @@ def setup(bot): """Spooky reaction Cog load.""" bot.add_cog(SpookyReact(bot)) - log.debug("SpookyReact cog loaded") + log.info("SpookyReact cog loaded") diff --git a/bot/seasons/halloween/spookysound.py b/bot/seasons/halloween/spookysound.py index cff50897..b62a9893 100644 --- a/bot/seasons/halloween/spookysound.py +++ b/bot/seasons/halloween/spookysound.py @@ -47,4 +47,4 @@ def setup(bot): """Spooky sound Cog load.""" bot.add_cog(SpookySound(bot)) - log.debug("SpookySound cog loaded") + log.info("SpookySound cog loaded") diff --git a/bot/seasons/valentines/be_my_valentine.py b/bot/seasons/valentines/be_my_valentine.py index 6abccceb..d90e73aa 100644 --- a/bot/seasons/valentines/be_my_valentine.py +++ b/bot/seasons/valentines/be_my_valentine.py @@ -16,7 +16,7 @@ HEART_EMOJIS = [":heart:", ":gift_heart:", ":revolving_hearts:", ":sparkling_hea class BeMyValentine: - """A cog that sends Valentines to other users.""" + """A cog that sends Valentines to other users!""" def __init__(self, bot): self.bot = bot @@ -243,4 +243,4 @@ def setup(bot): """Be my Valentine Cog load.""" bot.add_cog(BeMyValentine(bot)) - log.debug("Be My Valentine cog loaded") + log.info("BeMyValentine cog loaded") diff --git a/bot/seasons/valentines/lovecalculator.py b/bot/seasons/valentines/lovecalculator.py index 56cb551d..cd684f9d 100644 --- a/bot/seasons/valentines/lovecalculator.py +++ b/bot/seasons/valentines/lovecalculator.py @@ -9,7 +9,7 @@ from typing import Union import discord from discord import Member from discord.ext import commands -from discord.ext.commands import BadArgument, clean_content +from discord.ext.commands import BadArgument, Cog, clean_content from bot.constants import Roles @@ -20,7 +20,7 @@ with Path('bot', 'resources', 'valentines', 'love_matches.json').open() as file: LOVE_DATA = sorted((int(key), value) for key, value in LOVE_DATA.items()) -class LoveCalculator: +class LoveCalculator(Cog): """A cog for calculating the love between two people.""" def __init__(self, bot): @@ -104,3 +104,4 @@ def setup(bot): """Love calculator Cog load.""" bot.add_cog(LoveCalculator(bot)) + log.info("LoveCalculator cog loaded") diff --git a/bot/seasons/valentines/movie_generator.py b/bot/seasons/valentines/movie_generator.py index 19fbf25e..1b1a4a2d 100644 --- a/bot/seasons/valentines/movie_generator.py +++ b/bot/seasons/valentines/movie_generator.py @@ -62,4 +62,4 @@ def setup(bot): """Romance movie Cog load.""" bot.add_cog(RomanceMovieFinder(bot)) - log.debug("Random romance movie cog loaded!") + log.info("RomanceMovieFinder cog loaded") diff --git a/bot/seasons/valentines/myvalenstate.py b/bot/seasons/valentines/myvalenstate.py index 46fdebbc..0ea8fbab 100644 --- a/bot/seasons/valentines/myvalenstate.py +++ b/bot/seasons/valentines/myvalenstate.py @@ -87,4 +87,4 @@ def setup(bot): """Valenstate Cog load.""" bot.add_cog(MyValenstate(bot)) - log.debug("MyValenstate cog loaded") + log.info("MyValenstate cog loaded") diff --git a/bot/seasons/valentines/pickuplines.py b/bot/seasons/valentines/pickuplines.py index bce5cdcc..193eb788 100644 --- a/bot/seasons/valentines/pickuplines.py +++ b/bot/seasons/valentines/pickuplines.py @@ -44,4 +44,4 @@ def setup(bot): """Pickup lines Cog load.""" bot.add_cog(PickupLine(bot)) - log.info('Pickup line cog loaded') + log.info('PickupLine cog loaded') diff --git a/bot/seasons/valentines/savethedate.py b/bot/seasons/valentines/savethedate.py index 9f1dbaaa..76f418a2 100644 --- a/bot/seasons/valentines/savethedate.py +++ b/bot/seasons/valentines/savethedate.py @@ -41,4 +41,4 @@ def setup(bot): """Save the date Cog Load.""" bot.add_cog(SaveTheDate(bot)) - log.debug("Save the date cog loaded") + log.info("SaveTheDate cog loaded") diff --git a/bot/seasons/valentines/valentine_zodiac.py b/bot/seasons/valentines/valentine_zodiac.py index e18196fc..764c8ccc 100644 --- a/bot/seasons/valentines/valentine_zodiac.py +++ b/bot/seasons/valentines/valentine_zodiac.py @@ -58,4 +58,4 @@ def setup(bot): """Valentine Zodiac Cog load.""" bot.add_cog(ValentineZodiac(bot)) - log.debug("Valentine Zodiac cog loaded") + log.info("ValentineZodiac cog loaded") diff --git a/bot/seasons/valentines/whoisvalentine.py b/bot/seasons/valentines/whoisvalentine.py index 9ac2ee94..b7c47121 100644 --- a/bot/seasons/valentines/whoisvalentine.py +++ b/bot/seasons/valentines/whoisvalentine.py @@ -53,3 +53,4 @@ def setup(bot): """Who is Valentine Cog load.""" bot.add_cog(ValentineFacts(bot)) + log.info("ValentineFacts cog loaded") diff --git a/docker/Dockerfile b/docker/Dockerfile index edeb5b50..1445441c 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,15 +1,25 @@ -FROM python:3.7-alpine3.7 -RUN apk add --update libffi-dev tini build-base git jpeg-dev zlib zlib-dev +FROM python:3.7.2-alpine3.9 -RUN mkdir /bot -COPY . /bot -WORKDIR /bot +ENTRYPOINT ["python"] +CMD ["-m", "bot"] -ENV LIBRARY_PATH=/lib:/usr/lib \ - PIPENV_VENV_IN_PROJECT=1 +ENV PIP_NO_CACHE_DIR="false" \ + PIPENV_DONT_USE_PYENV="1" \ + PIPENV_HIDE_EMOJIS="1" \ + PIPENV_IGNORE_VIRTUALENVS="1" \ + PIPENV_NOSPIN="1" +RUN apk add --no-cache --update \ + build-base \ + git \ + libffi-dev \ + # Pillow dependencies + freetype-dev \ + libjpeg-turbo-dev \ + zlib-dev RUN pip install pipenv -RUN pipenv install --deploy --system -ENTRYPOINT ["/sbin/tini", "--"] -CMD ["python", "-m", "bot"] +COPY . /bot +WORKDIR /bot + +RUN pipenv install --deploy --system diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index de1f4cf2..6e274451 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,8 +1,9 @@ -version: "3" +version: "3.7" services: dumbo: image: pythondiscord/seasonalbot:latest container_name: seasonalbot + init: true restart: always |