From 18f16b3b856f3d76cd7e34eb71c607a31fed1f06 Mon Sep 17 00:00:00 2001 From: imcompiling Date: Fri, 8 Sep 2023 16:27:23 -0400 Subject: [PATCH] Create template for discord bots --- .gitea/template | 2 + .gitea/workflows/build_develop.yml | 24 ++++++ .gitea/workflows/build_latest.yml | 26 ++++++ .gitea/workflows/build_release.yml | 28 ++++++ .gitignore | 133 +++++++++++++++++++++++++++++ Dockerfile | 16 ++++ bot.py | 58 +++++++++++++ cogs/commands/__init__.py | 16 ++++ cogs/commands/hi.py | 29 +++++++ config.py | 22 +++++ requirements.txt | 2 + 11 files changed, 356 insertions(+) create mode 100644 .gitea/template create mode 100644 .gitea/workflows/build_develop.yml create mode 100644 .gitea/workflows/build_latest.yml create mode 100644 .gitea/workflows/build_release.yml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 bot.py create mode 100644 cogs/commands/__init__.py create mode 100644 cogs/commands/hi.py create mode 100644 config.py create mode 100644 requirements.txt diff --git a/.gitea/template b/.gitea/template new file mode 100644 index 0000000..dde8dec --- /dev/null +++ b/.gitea/template @@ -0,0 +1,2 @@ +.gitea/workflows/*.yml +bot.py \ No newline at end of file diff --git a/.gitea/workflows/build_develop.yml b/.gitea/workflows/build_develop.yml new file mode 100644 index 0000000..a3742b3 --- /dev/null +++ b/.gitea/workflows/build_develop.yml @@ -0,0 +1,24 @@ +name: build_develop + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install Docker + uses: https://github.com/papodaca/install-docker-action@v1 + - name: Log into container registry + uses: docker/login-action@v2 + with: + registry: gitea.cheezers.org + username: ${REPO_OWNER} + password: ${{ secrets.PASSWORD }} + - name: Build Docker Image + run: docker build -t gitea.cheezers.org/${REPO_OWNER}/${REPO_NAME}:develop . + - name: Push Docker Image + run: docker push gitea.cheezers.org/${REPO_OWNER}/${REPO_NAME}:develop diff --git a/.gitea/workflows/build_latest.yml b/.gitea/workflows/build_latest.yml new file mode 100644 index 0000000..50042c5 --- /dev/null +++ b/.gitea/workflows/build_latest.yml @@ -0,0 +1,26 @@ +name: build_latest + +on: + push: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install Docker + uses: https://github.com/papodaca/install-docker-action@v1 + - name: Log into container registry + uses: docker/login-action@v2 + with: + registry: gitea.cheezers.org + username: ${REPO_OWNER} + password: ${{ secrets.PASSWORD }} + - name: Build Docker Image + run: docker build -t gitea.cheezers.org/${REPO_OWNER}/${REPO_NAME}:latest . + - name: Push Docker Image + run: docker push gitea.cheezers.org/${REPO_OWNER}/${REPO_NAME}:latest diff --git a/.gitea/workflows/build_release.yml b/.gitea/workflows/build_release.yml new file mode 100644 index 0000000..d6389c0 --- /dev/null +++ b/.gitea/workflows/build_release.yml @@ -0,0 +1,28 @@ +name: build_release + +on: + push: + tags: ["v[0-9].[0-9].[0-9]"] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install Docker + uses: https://github.com/papodaca/install-docker-action@v1 + - name: Log into container registry + uses: docker/login-action@v2 + with: + registry: gitea.cheezers.org + username: ${REPO_OWNER} + password: ${{ secrets.PASSWORD }} + - name: Set env + run: echo "GIT_TAG=$${GITHUB_REF#refs/*/}" >> $$GITHUB_ENV + - name: Build Docker Image + run: docker build -t gitea.cheezers.org/${REPO_OWNER}/${REPO_NAME}:${{env.GIT_TAG}} . + - name: Push Tagged Image + run: docker push gitea.cheezers.org/${REPO_OWNER}/${REPO_NAME}:${{env.GIT_TAG}} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..872ffcc --- /dev/null +++ b/.gitignore @@ -0,0 +1,133 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +conf/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# IDE +.vscode/ + +# logging +nextcord.log +outputs/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6688c05 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.10.6-slim + +RUN pip install --upgrade pip + +WORKDIR /home + +COPY requirements.txt requirements.txt + +COPY config.py config.py +COPY bot.py bot.py + +COPY cogs cogs/ + +RUN pip install -r requirements.txt + +CMD ["python3", "-u", "./bot.py"] \ No newline at end of file diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..2e1bb82 --- /dev/null +++ b/bot.py @@ -0,0 +1,58 @@ +import logging +import os +import sys + +import hydra +import nextcord +from hydra.core.config_store import ConfigStore +from nextcord.ext import commands + +from config import BotConfig + +cs = ConfigStore.instance() +cs.store(name="${REPO_NAME}_config", node=BotConfig) + +logger = logging.getLogger("nextcord") +logger.setLevel(logging.DEBUG) +handler = logging.FileHandler(filename="nextcord.log", encoding="utf-8", mode="w") +handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s")) +logger.addHandler(handler) + + +@hydra.main(config_path="conf", config_name="config") +def main(cfg: BotConfig): + # Allows privledged intents for monitoring members joining, roles editing, and role assignments + # These need to be enabled in the developer portal as well + intents = nextcord.Intents.default() + + # Required in order to read messages (eg. prefix commands) + intents.message_content = True + + # To enable the guilds priveleged intent: + # intents.guilds = True + + # To enable the members priveleged intent: + intents.members = True + + bot = commands.Bot(intents=intents) + bot.config = cfg + + # Get the modules of all cogs whose directory structure is ./cogs/ + for folder in os.listdir("cogs"): + bot.load_extension(f"cogs.{folder}") + + @bot.listen() + async def on_ready(): + """When Discord is connected""" + assert bot.user is not None + print(f"{bot.user.name} has connected to Discord!") + + # Run Discord bot + bot.run(bot.config.params.discord_token) + + +if __name__ == "__main__": + sys.argv.append("hydra.job.chdir=False") + sys.argv.append("hydra/job_logging=none") + sys.argv.append("hydra/hydra_logging=none") + main() # pylint: disable=no-value-for-parameter diff --git a/cogs/commands/__init__.py b/cogs/commands/__init__.py new file mode 100644 index 0000000..7a7cad0 --- /dev/null +++ b/cogs/commands/__init__.py @@ -0,0 +1,16 @@ +""" +Cog loader. Adds all command cogs to the bot. +""" + +from nextcord.ext import commands + +from cogs.commands.hi import HiCog + + +# This function will be called when this extension is loaded. +# It is necessary to add these functions to the bot. +def setup(bot: commands.Bot): + """ + Adds all command classes to bot. + """ + bot.add_cog(HiCog(bot)) diff --git a/cogs/commands/hi.py b/cogs/commands/hi.py new file mode 100644 index 0000000..4a193a7 --- /dev/null +++ b/cogs/commands/hi.py @@ -0,0 +1,29 @@ +""" +Example command file. +""" + +import nextcord +from nextcord.ext import commands + + +class HiCog(commands.Cog, name="Test commands."): + """ + Class holds commands for testing. + """ + + def __init__(self, bot) -> None: + """ + Default constructor for HelpCog class. Does nothing. + """ + self.bot = bot + + @nextcord.slash_command() + async def hi(self, interaction: nextcord.Interaction): + """ + Says hi + + Args: + interaction (nextcord.Interaction): Interaction to reply to. + """ + + await interaction.response.send_message("Hi!", ephemeral=True) diff --git a/config.py b/config.py new file mode 100644 index 0000000..99a61a5 --- /dev/null +++ b/config.py @@ -0,0 +1,22 @@ +""" +File contains classes defining the Hydra configuraton structure. +""" +from dataclasses import dataclass + + +@dataclass +class Params: + """ + Class defines the various configuration parameters. + """ + + discord_token: str + + +@dataclass +class BotConfig: + """ + Class defines all configs required for Dakiny Bot. + """ + + params: Params diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3a68d82 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +nextcord==2.4.2 +hydra-core==1.3.2