-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'dev' into adventofcode
- Loading branch information
Showing
16 changed files
with
459 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Contributing | ||
|
||
## Setup Discord Application | ||
|
||
Refer to the official discord.py [documentation](https://discordpy.readthedocs.io/en/stable/discord.html) to create a bot. | ||
|
||
Also, please make sure that the scope application.commands is enabled. | ||
|
||
Make sure to enable intents as well—check the official guide for detailed instructions [here](https://discordpy.readthedocs.io/en/latest/intents.html). | ||
|
||
<img width="1313" alt="Screenshot 2023-11-14 at 12 51 00 PM" src="https://github.com/sarzz2/Discord-Bot/assets/45039724/97fd0d7f-8e6b-4d7b-b4f9-008a07dfb26b"> | ||
|
||
|
||
|
||
## Project Setup & Installation | ||
|
||
1. Fork the repository to your own profile. | ||
2. Set up a local PostgreSQL database or use [Docker](#Docker-Setup). | ||
|
||
```postgresql://username:password@localhost/db_name``` | ||
|
||
Replace username, password, db_name with appropriate values. | ||
|
||
3. To install packages, run: | ||
|
||
```bash | ||
pip install poetry | ||
poetry install | ||
``` | ||
4. Once all the packages are installed, run migrations using: | ||
|
||
```python cli.py migrate up``` | ||
|
||
5. Create a .env file and copy the contents of example.env, setting up the environment variables. | ||
|
||
6. Once the above steps are done, run the bot using the command: | ||
|
||
```bash | ||
python cli.py | ||
``` | ||
|
||
7. Feel free to join the server in case of any issues. | ||
|
||
## Docker-Setup | ||
|
||
1. Ensure you have Docker installed and set up on your system. Refer to the [Docker's official guide](https://docs.docker.com/get-started/overview/) if needed. | ||
2. To run a PostgreSQL instance, execute: | ||
|
||
```bash | ||
docker compose up -d postgres | ||
``` | ||
The `-d` flag runs the instance in detached mode. | ||
|
||
3. Run migrations. | ||
|
||
```python cli.py migrate up``` | ||
# Guidelines | ||
|
||
Please adhere to the following guidelines when contributing: | ||
|
||
- Follow the coding style and conventions used in the project. | ||
- Write clear and concise commit messages. | ||
- Test your changes thoroughly before submitting a pull request. | ||
- Be respectful and constructive in all interactions with other contributors. | ||
|
||
## Code Quality and Testing | ||
|
||
- Ensure your code follows best practices and is well-documented. | ||
- Write unit tests for new features and ensure existing tests pass. | ||
- Perform code reviews and address feedback from other contributors. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,7 @@ | ||
# Discord-Bot | ||
#### Discord bot for Tech With Tim's discord server. | ||
[![Invitation link](https://discord.com/api/guilds/501090983539245061/widget.png?style=banner3)](https://discord.gg/twt) | ||
|
||
# Contributing | ||
|
||
## Contributing | ||
* Fork the repository to your own profile, edit the code there. | ||
* When you are done with a feature open a pull request. | ||
* If you have any questions contact us in our discord server. | ||
|
||
[![Invitation link](https://discord.com/api/guilds/501090983539245061/widget.png?style=banner3)](https://discord.gg/twt) | ||
If you're interested in contributing, please review the [Contributing](CONTRIBUTING.md) section. For specific tasks and opportunities, explore our list of open [issues](https://github.com/SylteA/Discord-Bot/issues). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from bot.core import DiscordBot | ||
|
||
from .commands import CustomRoles | ||
from .events import CustomRoleEvents | ||
|
||
|
||
async def setup(bot: DiscordBot) -> None: | ||
await bot.add_cog(CustomRoles(bot=bot)) | ||
await bot.add_cog(CustomRoleEvents(bot=bot)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
from __future__ import annotations | ||
|
||
import discord | ||
from discord import app_commands, utils | ||
from discord.ext import commands | ||
|
||
from bot import core | ||
from bot.config import settings | ||
from bot.models import CustomRole | ||
|
||
|
||
class CustomRoles(commands.Cog): | ||
def __init__(self, bot): | ||
self.bot = bot | ||
|
||
self.color_converter = commands.ColorConverter() | ||
|
||
@staticmethod | ||
def role_embed(heading: str, role: discord.Role): | ||
embed = discord.Embed( | ||
description=f"**{heading}**", | ||
timestamp=role.created_at, | ||
color=role.color, | ||
) | ||
embed.add_field(name="Name", value=utils.escape_markdown(role.name)) | ||
embed.add_field(name="Color", value=str(role.color)) | ||
embed.set_footer(text="Created at") | ||
return embed | ||
|
||
@app_commands.command() | ||
@app_commands.default_permissions(administrator=True) | ||
@app_commands.describe(name="New name", color="New color") | ||
async def myrole( | ||
self, interaction: core.InteractionType, name: app_commands.Range[str, 2, 100] | None, color: str = None | ||
): | ||
"""Manage your custom role""" | ||
if color is not None: | ||
try: | ||
color = await self.color_converter.convert(None, color) # noqa | ||
except commands.BadColourArgument as e: | ||
return await interaction.response.send_message(str(e), ephemeral=True) | ||
|
||
query = "SELECT * FROM custom_roles WHERE guild_id = $1 AND user_id = $2" | ||
before = await CustomRole.fetchrow(query, interaction.guild.id, interaction.user.id) | ||
|
||
if before is None: | ||
if name is None: | ||
return await interaction.response.send_message("You don't have a custom role yet!", ephemeral=True) | ||
|
||
# Create and assign the role to user | ||
role = await interaction.guild.create_role(name=name, colour=color or discord.Color.random()) | ||
|
||
divider_role = interaction.guild.get_role(settings.custom_roles.divider_role_id) | ||
await role.edit(position=divider_role.position + 1) | ||
|
||
record = await CustomRole.ensure_exists( | ||
guild_id=interaction.guild.id, | ||
user_id=interaction.user.id, | ||
role_id=role.id, | ||
name=role.name, | ||
color=role.color.value, | ||
) | ||
|
||
self.bot.dispatch("custom_role_create", custom_role=record) | ||
self.bot.dispatch( | ||
"persist_roles", | ||
guild_id=interaction.guild.id, | ||
user_id=interaction.user.id, | ||
role_ids=[role.id], | ||
) | ||
|
||
return await interaction.response.send_message( | ||
embed=self.role_embed("**Custom Role has been assigned**", role), | ||
ephemeral=True, | ||
) | ||
|
||
role = interaction.guild.get_role(before.role_id) | ||
|
||
# Return role information if no parameter is passed | ||
if (name is None or name == before.name) and (color is None or color.value == before.color): | ||
return await interaction.response.send_message( | ||
embed=self.role_embed( | ||
f"Custom Role for {interaction.user.mention}", interaction.guild.get_role(before.role_id) | ||
), | ||
ephemeral=True, | ||
) | ||
|
||
await role.edit( | ||
name=name or before.name, | ||
colour=color or discord.Color(int(before.color)), | ||
) | ||
|
||
after = await CustomRole.ensure_exists( | ||
guild_id=interaction.guild.id, | ||
user_id=interaction.user.id, | ||
role_id=role.id, | ||
name=role.name, | ||
color=role.color.value, | ||
) | ||
|
||
self.bot.dispatch("custom_role_update", before, after) | ||
|
||
return await interaction.response.send_message( | ||
embed=self.role_embed("**Custom Role has been updated**", interaction.guild.get_role(before.role_id)), | ||
ephemeral=True, | ||
) | ||
|
||
|
||
async def setup(bot: commands.Bot): | ||
await bot.add_cog(CustomRoles(bot=bot)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import datetime | ||
import time | ||
|
||
import discord | ||
from discord.ext import commands | ||
|
||
from bot import core | ||
from bot.config import settings | ||
from bot.models.custom_roles import CustomRole | ||
|
||
|
||
class CustomRoleEvents(commands.Cog): | ||
"""Events for Levelling in discord.""" | ||
|
||
def __init__(self, bot: core.DiscordBot): | ||
self.bot = bot | ||
self.updated_at: dict[int, datetime] = {} | ||
|
||
@property | ||
def custom_roles_logs_channel(self) -> discord.TextChannel | None: | ||
return self.bot.guild.get_channel(settings.custom_roles.log_channel_id) | ||
|
||
@commands.Cog.listener() | ||
async def on_guild_role_update(self, before: discord.Role, after: discord.Role): | ||
last_update = self.updated_at.get(before.id) | ||
|
||
# Ignore events less than 10 seconds since a user updated their role | ||
if last_update is not None: | ||
if time.time() - last_update < 10: | ||
return | ||
|
||
query = """ | ||
UPDATE custom_roles | ||
SET name = $2, color = $3 | ||
WHERE role_id = $1 | ||
""" | ||
await CustomRole.execute(query, after.id, after.name, after.color.value) | ||
|
||
@commands.Cog.listener() | ||
async def on_custom_role_create(self, custom_role: CustomRole): | ||
"""Logs the creation of new role""" | ||
self.updated_at[custom_role.role_id] = time.time() | ||
|
||
user = await self.bot.fetch_user(custom_role.user_id) | ||
|
||
embed = discord.Embed( | ||
title="Custom Role Created", | ||
color=discord.Color.brand_green(), | ||
timestamp=datetime.datetime.utcnow(), | ||
) | ||
embed.set_author(name=user.display_name, icon_url=user.display_avatar) | ||
embed.add_field(name="Name", value=custom_role.name) | ||
embed.add_field(name="Color", value="#" + hex(custom_role.color)[2:]) | ||
embed.set_thumbnail(url=user.avatar) | ||
embed.set_footer(text=f"user_id: {custom_role.user_id}") | ||
|
||
return await self.custom_roles_logs_channel.send(embed=embed) | ||
|
||
@commands.Cog.listener() | ||
async def on_custom_role_update(self, before: CustomRole, after: CustomRole): | ||
"""Logs the update of custom role.""" | ||
self.updated_at[after.role_id] = time.time() | ||
|
||
user = await self.bot.fetch_user(after.user_id) | ||
|
||
embed = discord.Embed( | ||
title="Custom Role Updated", | ||
color=discord.Color.brand_green(), | ||
timestamp=datetime.datetime.utcnow(), | ||
) | ||
|
||
embed.add_field(name="Old Name", value=before.name) | ||
embed.add_field(name="New Name", value=after.name) | ||
embed.add_field(name="\u200B", value="\u200B") | ||
embed.add_field(name="Old Color", value="#" + hex(before.color)[2:]) | ||
embed.add_field(name="New Color", value="#" + hex(after.color)[2:]) | ||
embed.set_thumbnail(url=user.avatar) | ||
embed.set_footer(text=f"user_id: {after.user_id}") | ||
|
||
return await self.custom_roles_logs_channel.send(embed=embed) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from bot.core import DiscordBot | ||
|
||
from .tasks import YoutubeTasks | ||
|
||
|
||
async def setup(bot: DiscordBot) -> None: | ||
await bot.add_cog(YoutubeTasks(bot=bot)) |
Oops, something went wrong.