Skip to content

Commit

Permalink
chore: rewrite codebase (#4)
Browse files Browse the repository at this point in the history
- Switch bot framework from discord.py to hikari
- Use pydantic for data type validation
- Use rich for prettier console logging
- Add settings module for storing constants used accross Dayong's modules
- Rename extensions directory from cogs to components
- Separate bot config from bot session
- Implement interfaces

NOTE: For interfaces, see PEP 544 -- Protocols: Structural subtyping (static duck typing)
  • Loading branch information
huenique committed Oct 12, 2021
1 parent 75f70f7 commit 9f34e7c
Show file tree
Hide file tree
Showing 27 changed files with 382 additions and 820 deletions.
4 changes: 1 addition & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Create a copy of this file inside the project root directory. Remove the
# .example at the end.

BOT_COMMAND_PREFIX=.
TOKEN=your_bot_token
APPLICATION_ID=your_application_id
BOT_TOKEN=your_bot_token
DATABASE_URI=postgresql+asyncpg://[userspec@][hostspec][/dbname][?paramspec]
12 changes: 0 additions & 12 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,12 @@ Ready to contribute? Here's how to set up `Dayong` for local development.

Now you can make your changes locally.

<<<<<<< HEAD
5. When you're done making changes, check that your changes pass flake8, pylint, and pyright.

```
$ flake8 dayong
$ pylint dayong
$ pyright dayong
=======
5. When you're done making changes, check that your changes pass flake8, pylint and mypy.

```
$ flake8 Dayong
$ pylint Dayong
$ mypy Dayong
>>>>>>> 9368de9... docs: add contributing guidelines
```

## Commit Message Guidelines
Expand All @@ -88,10 +79,7 @@ Dayong uses precise rules over how git commit messages can be formatted. This le
```
$ git add .
$ git commit -m "<type>(<scope>): <subject>"
<<<<<<< HEAD
=======
$ git push origin name-of-your-bugfix-or-feature
>>>>>>> 9368de9... docs: add contributing guidelines
```

## Pull Request Guidelines
Expand Down
12 changes: 0 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,3 @@ Dayong is dedicated to helping Discord servers build and manage their communitie
- Self-hosted and easy to deploy —just a few more steps to take.
- Free and open-source —tinker with it, and feel free to contribute to its improvement!
- Modular —easily add extensions and features.

> For setup and installation instructions, please refer to the [documentation](./docs).
## Usage

1. From the project root directory, run:

```
python dayong
```

2. Open your Discord application. Go to the server where you invited the bot and run `<your command prefix>help`. For instance: `.help` or `!help`. The dot prefix is the default.
3 changes: 2 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"bot_prefix": ".",
"embeddings": {
"greetings_channel": "welcome",
"readme_channel_id": 790110106809401344,
Expand Down Expand Up @@ -31,4 +32,4 @@
}
}
}
}
}
10 changes: 0 additions & 10 deletions dayong/__init__.py

This file was deleted.

8 changes: 2 additions & 6 deletions dayong/__main__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
"""
Dayong's entry point.
"""
from dayong.cli import SetupCLI, command_line, display_banner
from dayong import bot

if __name__ == "__main__":
args = command_line()
display_banner()
setup = SetupCLI()
setup.check_configs()
setup.run_dayong()
bot.run()
28 changes: 0 additions & 28 deletions dayong/banner.txt

This file was deleted.

112 changes: 47 additions & 65 deletions dayong/bot.py
Original file line number Diff line number Diff line change
@@ -1,85 +1,67 @@
"""
dayong.bot
~~~~~~~~~~
This module defines the startup logic for Dayong.
"""
import os
from pathlib import Path
from typing import Union

from discord import Intents # type: ignore
from discord.ext.commands import Bot # type: ignore
from dotenv import load_dotenv

from dayong.exceptions import exception_handler

# Parse the .env file and load the environment variables.
load_dotenv()

BASE_DIR = Path(__file__).resolve().parent
ROOT_DIR = BASE_DIR.parent
CONFIG_FILE = os.path.join(ROOT_DIR, "config.json")
EMBEDDINGS: dict

with open(CONFIG_FILE, encoding="utf-8") as cfp:
config = json.load(cfp)
EMBEDDINGS = config["embeddings"]

# Environment variables or secrets.
BOT_COMMAND_PREFIX: Union[str, None] = os.getenv("BOT_COMMAND_PREFIX")
TOKEN: Union[str, None] = os.getenv("TOKEN")
APPLICATION_ID: Union[str, None] = os.getenv("APPLICATION_ID")
DATABASE_URI: Union[str, None] = os.getenv("DATABASE_URI")
import hikari
import tanjun

from dayong.config import DayongConfig, DayongConfigLoader
from dayong.impls import DatabaseImpl
from dayong.protocols import DatabaseProto
from dayong.settings import BASE_DIR

class Setup:
"""Base Setup class."""
if os.name != "nt":
import uvloop

dayong: Bot
uvloop.install()

@staticmethod
def check_configs() -> None:
"""Check if `config.json` exists."""
if not os.path.isfile(CONFIG_FILE):
sys.exit(f"config.json missing from {ROOT_DIR}!")

@staticmethod
def load_extensions() -> list[str]:
"""Traverse the `cogs` directory and collect cog modules.
async def get_prefix(
ctx: tanjun.abc.MessageContext,
db: DatabaseProto = tanjun.injected(type=DatabaseProto),
) -> Union[list[str], tuple[()]]:
if ctx.guild_id and (guild_info := await db.get_guild_info(ctx.guild_id)):
return guild_info.prefixes

Returns:
list[str]: A list of Python modules. The `.py` extension should be
omitted.
"""
extensions: list[str] = []
return ()

for file in os.listdir(os.path.join(BASE_DIR, "cogs")):
# Append cog modules and ignore dunder files.
if file.endswith(".py") and "__" not in file:
extensions.append(file.replace(".py", ""))

return extensions
def fetch_component() -> list[str]:
"""Traverse the components directory and collect component modules.
@exception_handler
def run_dayong(self) -> None:
"""Run Dayong with the configurations and the owner's bot credentials."""
pref = BOT_COMMAND_PREFIX
exts = self.load_extensions()
This will fetch the module from the components directory, remove its
extension and convert it to `sys.path`.
intents = Intents.default()
intents.members = True # pylint: disable=E0237
Returns:
list[str]: Sequence of python modules.
"""
extensions: list[str] = []
components = os.path.join(BASE_DIR, "components")

self.dayong = Bot(pref, intents=intents)
for file in os.listdir(components):
if file.endswith(".py") and "__" not in file:
file = f"components.{file}".replace(".py", "")
extensions.append(file)

for ext in exts:
self.dayong.load_extension(f"cogs.{ext}")
return extensions

if TOKEN is None:
raise Exception("Bot token missing: {TOKEN}")

self.dayong.run(TOKEN)
def run() -> None:
"""Run Dayong using configs and deps."""
loaded_config = DayongConfig(**DayongConfigLoader().__dict__)
bot = hikari.GatewayBot(loaded_config.bot_token)
(
tanjun.Client.from_gateway_bot(bot)
.load_modules(*fetch_component())
.add_prefix(loaded_config.bot_prefix)
.set_prefix_getter(get_prefix)
.set_type_dependency(DayongConfig, lambda: loaded_config)
.set_type_dependency(
DatabaseProto,
tanjun.cache_callback(DatabaseImpl.connect),
)
)
bot.run()


if __name__ == "__main__":
pass
run()
34 changes: 0 additions & 34 deletions dayong/cli.py

This file was deleted.

0 comments on commit 9f34e7c

Please sign in to comment.