diff options
| -rw-r--r-- | .dockerignore | 8 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | azure-pipelines.yml | 30 | ||||
| -rw-r--r-- | bot/__init__.py | 38 | ||||
| -rw-r--r-- | bot/resources/evergreen/magic8ball.json | 22 | ||||
| -rw-r--r-- | bot/seasons/easter/__init__.py | 17 | ||||
| -rw-r--r-- | bot/seasons/evergreen/magic_8ball.py | 36 | ||||
| -rw-r--r-- | bot/seasons/pride/__init__.py | 17 | ||||
| -rw-r--r-- | bot/seasons/valentines/savethedate.py | 23 | ||||
| -rw-r--r-- | docker/Dockerfile | 30 | ||||
| -rw-r--r-- | docker/docker-compose.yml | 3 |
11 files changed, 171 insertions, 54 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 @@ -111,3 +111,4 @@ venv.bak/ # jetbrains .idea/ +.DS_Store
\ No newline at end of file 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..54b242ee 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,44 @@ 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 +54,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') 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/easter/__init__.py b/bot/seasons/easter/__init__.py new file mode 100644 index 00000000..bfad772d --- /dev/null +++ b/bot/seasons/easter/__init__.py @@ -0,0 +1,17 @@ +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/magic_8ball.py b/bot/seasons/evergreen/magic_8ball.py new file mode 100644 index 00000000..88c9fd26 --- /dev/null +++ b/bot/seasons/evergreen/magic_8ball.py @@ -0,0 +1,36 @@ +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?`)") + + +# Required in order to load the cog, use the class name in the add_cog function. +def setup(bot): + bot.add_cog(Magic8ball(bot)) + log.info("Magic 8ball cog loaded") diff --git a/bot/seasons/pride/__init__.py b/bot/seasons/pride/__init__.py new file mode 100644 index 00000000..d8a7e34b --- /dev/null +++ b/bot/seasons/pride/__init__.py @@ -0,0 +1,17 @@ +from bot.seasons import SeasonBase + + +class Pride(SeasonBase): + """ + No matter your origin, identity or sexuality, we come together to celebrate each and everyone's individuality. + Feature contributions to ProudBot is encouraged to commemorate the history and challenges of the LGBTQ+ community. + Happy Pride Month + """ + + name = "pride" + bot_name = "ProudBot" + greeting = "Happy Pride Month!" + + # Duration of season + start_date = "01/06" + end_date = "30/06" diff --git a/bot/seasons/valentines/savethedate.py b/bot/seasons/valentines/savethedate.py index f587c2fc..fbc9eb82 100644 --- a/bot/seasons/valentines/savethedate.py +++ b/bot/seasons/valentines/savethedate.py @@ -12,6 +12,9 @@ log = logging.getLogger(__name__) HEART_EMOJIS = [":heart:", ":gift_heart:", ":revolving_hearts:", ":sparkling_heart:", ":two_hearts:"] +with open(Path('bot', 'resources', 'valentines', 'date_ideas.json'), 'r', encoding="utf8") as f: + VALENTINES_DATES = load(f) + class SaveTheDate(commands.Cog): """ @@ -26,17 +29,15 @@ class SaveTheDate(commands.Cog): """ Gives you ideas for what to do on a date with your valentine. """ - with open(Path('bot', 'resources', 'valentines', 'date_ideas.json'), 'r', encoding="utf8") as f: - valentine_dates = load(f) - random_date = random.choice(valentine_dates['ideas']) - emoji_1 = random.choice(HEART_EMOJIS) - emoji_2 = random.choice(HEART_EMOJIS) - embed = discord.Embed( - title=f"{emoji_1}{random_date['name']}{emoji_2}", - description=f"{random_date['description']}", - colour=Colours.pink - ) - await ctx.send(embed=embed) + random_date = random.choice(VALENTINES_DATES['ideas']) + emoji_1 = random.choice(HEART_EMOJIS) + emoji_2 = random.choice(HEART_EMOJIS) + embed = discord.Embed( + title=f"{emoji_1}{random_date['name']}{emoji_2}", + description=f"{random_date['description']}", + colour=Colours.pink + ) + await ctx.send(embed=embed) def setup(bot): 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 |