mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 18:23:12 +00:00
commit
994959618e
61 changed files with 1028 additions and 990 deletions
15
.github/workflows/docker-image.yml
vendored
15
.github/workflows/docker-image.yml
vendored
|
@ -17,8 +17,7 @@ jobs:
|
|||
packages: write
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Docker meta
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
|
@ -31,25 +30,21 @@ jobs:
|
|||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Login to GHCR
|
||||
- name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
|
|
|
@ -16,7 +16,7 @@ repos:
|
|||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
args: [--fix]
|
||||
args: [ --fix ]
|
||||
# Run the formatter.
|
||||
- id: ruff-format
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
|
|||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Contributing to Luminara
|
||||
|
||||
Thank you for your interest in contributing to Lumi! We welcome contributions from the community to help improve and expand the bot's functionality. Please follow these guidelines when contributing:
|
||||
Thank you for your interest in contributing to Lumi! We welcome contributions from the community to help improve and
|
||||
expand the bot's functionality. Please follow these guidelines when contributing:
|
||||
|
||||
## Getting Started
|
||||
|
||||
|
@ -10,35 +11,39 @@ Thank you for your interest in contributing to Lumi! We welcome contributions fr
|
|||
|
||||
3. **Set Up Development Environment:**
|
||||
|
||||
* **Docker:** To run the bot, use this command to run your newly edited code:
|
||||
* **Docker:** To run the bot, use this command to run your newly edited code:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml up --build
|
||||
```
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml up --build
|
||||
```
|
||||
|
||||
* **Poetry:** While developing, it is recommended to install & configure poetry locally:
|
||||
* **Poetry:** While developing, it is recommended to install & configure poetry locally:
|
||||
|
||||
```bash
|
||||
poetry install
|
||||
poetry shell
|
||||
poetry pre-commit install
|
||||
```
|
||||
```bash
|
||||
poetry install
|
||||
poetry shell
|
||||
poetry pre-commit install
|
||||
```
|
||||
|
||||
## Making Changes
|
||||
|
||||
1. **Create a Branch:** Create a new branch for your changes.
|
||||
2. **Code Style:** Adhere to the existing code style and formatting conventions.
|
||||
3. **Strict Typing:** Always use strict typing (e.g., `str`, `int`, `List[str]`) for better code quality and maintainability.
|
||||
4. **Pre-Commit Checks:** Before committing, run pre-commit checks to ensure your code passes linting and formatting standards.
|
||||
3. **Strict Typing:** Always use strict typing (e.g., `str`, `int`, `List[str]`) for better code quality and
|
||||
maintainability.
|
||||
4. **Pre-Commit Checks:** Before committing, run pre-commit checks to ensure your code passes linting and formatting
|
||||
standards.
|
||||
5. **Clear Commit Messages:** Write clear and concise commit messages that describe the changes you made.
|
||||
|
||||
## Submitting Changes
|
||||
|
||||
1. **Create a Pull Request:** Create a pull request (PR) from your branch to the `main` branch of the original repository.
|
||||
1. **Create a Pull Request:** Create a pull request (PR) from your branch to the `main` branch of the original
|
||||
repository.
|
||||
2. **Review:** Your PR will be reviewed by the Sourcery & Lumi maintainers. Address any feedback or requested changes.
|
||||
3. **Merge:** Once approved, your PR will be merged into the main branch.
|
||||
|
||||
## Additional Notes
|
||||
|
||||
* **Documentation:** If you add new functionality or change existing behavior, update or add the docstrings accordingly.
|
||||
|
||||
Thank you for your contributions!
|
||||
|
|
|
@ -9,10 +9,10 @@ import Client
|
|||
import config.parser
|
||||
import services.config_service
|
||||
import services.help_service
|
||||
from lib.constants import CONST
|
||||
from services.blacklist_service import BlacklistUserService
|
||||
from lib.exceptions.LumiExceptions import Blacklisted
|
||||
from db.database import run_migrations
|
||||
from lib.constants import CONST
|
||||
from lib.exceptions.LumiExceptions import Blacklisted
|
||||
from services.blacklist_service import BlacklistUserService
|
||||
|
||||
# Remove the default logger configuration
|
||||
logger.remove()
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
|
||||
![Lumi art](https://git.wlinator.org/assets/img/logo.png)
|
||||
|
||||
|
||||
## Self-Hosting
|
||||
|
||||
Self-hosting refers to running Luminara on your own server or computer, rather than using the publicly hosted version. This approach offers the ability to manage your own instance of the bot and give it a custom name and avatar.
|
||||
Self-hosting refers to running Luminara on your own server or computer, rather than using the publicly hosted version.
|
||||
This approach offers the ability to manage your own instance of the bot and give it a custom name and avatar.
|
||||
|
||||
### Requirements
|
||||
|
||||
Before you begin, make sure you have the following installed on your system:
|
||||
|
||||
- [Docker](https://docs.docker.com/get-docker/)
|
||||
- [Docker Compose](https://docs.docker.com/compose/install/)
|
||||
|
||||
|
@ -25,7 +26,8 @@ Additionally, you'll need to create a Discord bot application and obtain a token
|
|||
|
||||
### Running Luminara:
|
||||
|
||||
1. Copy the contents from [`docker-compose.prod.yml`](docker-compose.prod.yml) to a new file named `docker-compose.yml` in an empty directory.
|
||||
1. Copy the contents from [`docker-compose.prod.yml`](docker-compose.prod.yml) to a new file named `docker-compose.yml`
|
||||
in an empty directory.
|
||||
|
||||
2. Copy the contents from [`.env.example`](.env.example) to a new file named `.env` in the same directory.
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
Versions currently being supported with security updates.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 2.x | :white_check_mark: |
|
||||
| 1.x | :x: |
|
||||
|---------|--------------------|
|
||||
| 2.x | :white_check_mark: |
|
||||
| 1.x | :x: |
|
||||
| < 1.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import mysql.connector
|
||||
from loguru import logger
|
||||
from mysql.connector import pooling
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
|
||||
import mysql.connector
|
||||
from loguru import logger
|
||||
from mysql.connector import pooling
|
||||
|
||||
from lib.constants import CONST
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import contextlib
|
||||
|
||||
from discord import Message
|
||||
from discord.ext.commands import Cog
|
||||
from loguru import logger
|
||||
|
@ -76,7 +77,7 @@ class ReactionListener(Cog):
|
|||
:param message: The message to process.
|
||||
"""
|
||||
if not message.author.bot and not BlacklistUserService.is_user_blacklisted(
|
||||
message.author.id,
|
||||
message.author.id,
|
||||
):
|
||||
await ReactionHandler(self.client, message).run_checks()
|
||||
|
||||
|
|
|
@ -103,9 +103,9 @@ class XPHandler:
|
|||
|
||||
if role := self.guild.get_role(role_id):
|
||||
with contextlib.suppress(
|
||||
discord.Forbidden,
|
||||
discord.NotFound,
|
||||
discord.HTTPException,
|
||||
discord.Forbidden,
|
||||
discord.NotFound,
|
||||
discord.HTTPException,
|
||||
):
|
||||
if isinstance(self.author, discord.Member):
|
||||
await self.author.add_roles(role, reason=reason)
|
||||
|
@ -114,16 +114,16 @@ class XPHandler:
|
|||
if replace and isinstance(self.author, discord.Member):
|
||||
if role := self.guild.get_role(previous or role_id):
|
||||
with contextlib.suppress(
|
||||
discord.Forbidden,
|
||||
discord.NotFound,
|
||||
discord.HTTPException,
|
||||
discord.Forbidden,
|
||||
discord.NotFound,
|
||||
discord.HTTPException,
|
||||
):
|
||||
await self.author.remove_roles(role, reason=reason)
|
||||
|
||||
async def get_level_channel(
|
||||
self,
|
||||
message: discord.Message,
|
||||
guild_config: GuildConfig,
|
||||
self,
|
||||
message: discord.Message,
|
||||
guild_config: GuildConfig,
|
||||
) -> Optional[discord.TextChannel]:
|
||||
"""
|
||||
Retrieves the level up notification channel for the guild.
|
||||
|
@ -147,9 +147,9 @@ class XPHandler:
|
|||
|
||||
@staticmethod
|
||||
async def get_level_message(
|
||||
guild_config: GuildConfig,
|
||||
level_config: XpService,
|
||||
author: discord.Member,
|
||||
guild_config: GuildConfig,
|
||||
level_config: XpService,
|
||||
author: discord.Member,
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
Retrieves the level up message for the user.
|
||||
|
|
|
@ -8,22 +8,22 @@ from lib.constants import CONST
|
|||
class EmbedBuilder:
|
||||
@staticmethod
|
||||
def create_embed(
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
color=None,
|
||||
footer_text=None,
|
||||
footer_icon_url=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
color=None,
|
||||
footer_text=None,
|
||||
footer_icon_url=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
):
|
||||
if not hide_author:
|
||||
if not author_text:
|
||||
|
@ -63,20 +63,20 @@ class EmbedBuilder:
|
|||
|
||||
@staticmethod
|
||||
def create_error_embed(
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
footer_text=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
footer_text=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
):
|
||||
return EmbedBuilder.create_embed(
|
||||
ctx,
|
||||
|
@ -99,20 +99,20 @@ class EmbedBuilder:
|
|||
|
||||
@staticmethod
|
||||
def create_success_embed(
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
footer_text=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
footer_text=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
):
|
||||
return EmbedBuilder.create_embed(
|
||||
ctx,
|
||||
|
@ -135,20 +135,20 @@ class EmbedBuilder:
|
|||
|
||||
@staticmethod
|
||||
def create_info_embed(
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
footer_text=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
footer_text=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
):
|
||||
return EmbedBuilder.create_embed(
|
||||
ctx,
|
||||
|
@ -171,20 +171,20 @@ class EmbedBuilder:
|
|||
|
||||
@staticmethod
|
||||
def create_warning_embed(
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
footer_text=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
ctx,
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
author_url=None,
|
||||
description=None,
|
||||
footer_text=None,
|
||||
show_name=True,
|
||||
image_url=None,
|
||||
thumbnail_url=None,
|
||||
timestamp=None,
|
||||
hide_author=False,
|
||||
hide_author_icon=False,
|
||||
hide_timestamp=False,
|
||||
):
|
||||
return EmbedBuilder.create_embed(
|
||||
ctx,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from discord.ext import commands
|
||||
|
||||
from lib.constants import CONST
|
||||
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@ import textwrap
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
from pytimeparse import parse
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from lib.constants import CONST
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
|
||||
|
|
|
@ -51,9 +51,9 @@ class IntroductionFinishButtons(View):
|
|||
|
||||
@discord.ui.button(label="Post it!", style=discord.ButtonStyle.green)
|
||||
async def short_button_callback(
|
||||
self,
|
||||
button: discord.ui.Button,
|
||||
interaction: discord.Interaction,
|
||||
self,
|
||||
button: discord.ui.Button,
|
||||
interaction: discord.Interaction,
|
||||
) -> None:
|
||||
await interaction.response.edit_message(view=None)
|
||||
self.clickedConfirm = True
|
||||
|
@ -61,9 +61,9 @@ class IntroductionFinishButtons(View):
|
|||
|
||||
@discord.ui.button(label="Stop", style=discord.ButtonStyle.red)
|
||||
async def extended_button_callback(
|
||||
self,
|
||||
button: discord.ui.Button,
|
||||
interaction: discord.Interaction,
|
||||
self,
|
||||
button: discord.ui.Button,
|
||||
interaction: discord.Interaction,
|
||||
) -> None:
|
||||
await interaction.response.edit_message(view=None)
|
||||
self.stop()
|
||||
|
|
|
@ -30,7 +30,7 @@ class ReactionHandler:
|
|||
content = message.content.lower()
|
||||
|
||||
if (
|
||||
content.startswith("Lumi ") or content.startswith("Lumi, ")
|
||||
content.startswith("Lumi ") or content.startswith("Lumi, ")
|
||||
) and content.endswith("?"):
|
||||
response = random.choice(self.eightball)
|
||||
await message.reply(content=response)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import discord
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.currency_service import Currency
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
from typing import Optional
|
||||
|
||||
import discord
|
||||
|
||||
from lib.constants import CONST
|
||||
from services.blacklist_service import BlacklistUserService
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.blacklist_service import BlacklistUserService
|
||||
|
||||
|
||||
async def blacklist_user(
|
||||
ctx,
|
||||
user: discord.User,
|
||||
reason: Optional[str] = None,
|
||||
ctx,
|
||||
user: discord.User,
|
||||
reason: Optional[str] = None,
|
||||
) -> None:
|
||||
blacklist_service = BlacklistUserService(user.id)
|
||||
blacklist_service.add_to_blacklist(reason)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import mysql.connector
|
||||
|
||||
from db import database
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.formatter import shorten
|
||||
|
||||
from db import database
|
||||
|
||||
|
||||
async def select_cmd(ctx, query: str):
|
||||
if query.lower().startswith("select "):
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import discord
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from lib.constants import CONST
|
||||
|
||||
|
||||
async def sync_commands(client, ctx):
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import datetime
|
||||
import pytz
|
||||
|
||||
import discord
|
||||
import pytz
|
||||
from discord.commands import SlashCommandGroup
|
||||
from discord.ext import commands, tasks
|
||||
|
||||
from lib import checks
|
||||
from lib.constants import CONST
|
||||
from modules.birthdays import birthday, daily_check
|
||||
|
|
|
@ -4,8 +4,8 @@ import datetime
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.birthday_service import Birthday
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import asyncio
|
||||
import random
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.birthday_service import Birthday
|
||||
from services.config_service import GuildConfig
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
|
||||
|
||||
async def daily_birthday_check(client):
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import discord
|
||||
from discord.ext.commands import guild_only
|
||||
from discord.commands import SlashCommandGroup
|
||||
from discord.ext import bridge, commands
|
||||
from discord.ext.commands import guild_only
|
||||
|
||||
from modules.config import (
|
||||
c_birthday,
|
||||
c_boost,
|
||||
|
@ -38,11 +39,11 @@ class Config(commands.Cog):
|
|||
@guild_only()
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
async def xp_reward_command_add(
|
||||
self,
|
||||
ctx,
|
||||
level: int,
|
||||
role: discord.Role,
|
||||
persistent: bool = False,
|
||||
self,
|
||||
ctx,
|
||||
level: int,
|
||||
role: discord.Role,
|
||||
persistent: bool = False,
|
||||
):
|
||||
await xp_reward.add_reward(ctx, level, role.id, persistent)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import discord
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import discord
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from services.config_service import GuildConfig
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
|
||||
import lib.formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
|
||||
async def set_boost_channel(ctx, channel: discord.TextChannel):
|
||||
|
@ -103,9 +104,9 @@ async def set_boost_image(ctx, image_url: str | None):
|
|||
|
||||
|
||||
async def create_boost_embed(
|
||||
member: discord.Member,
|
||||
template: str | None = None,
|
||||
image_url: str | None = None,
|
||||
member: discord.Member,
|
||||
template: str | None = None,
|
||||
image_url: str | None = None,
|
||||
):
|
||||
embed = discord.Embed(
|
||||
color=discord.Color.nitro_pink(),
|
||||
|
|
|
@ -77,8 +77,8 @@ async def set_welcome_template(ctx, text: str) -> None:
|
|||
|
||||
|
||||
def create_greet_embed(
|
||||
member: discord.Member,
|
||||
template: Optional[str] = None,
|
||||
member: discord.Member,
|
||||
template: Optional[str] = None,
|
||||
) -> discord.Embed:
|
||||
embed: discord.Embed = discord.Embed(
|
||||
color=discord.Color.embed_background(),
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import discord
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
from lib import formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
|
||||
async def set_level_channel(ctx, channel: discord.TextChannel):
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import discord
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
|
||||
from lib.constants import CONST
|
||||
from services.moderation.modlog_service import ModLogService
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from services.moderation.modlog_service import ModLogService
|
||||
|
||||
|
||||
async def set_mod_log_channel(ctx, channel: discord.TextChannel):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import discord
|
||||
from typing import List, Tuple, Optional
|
||||
|
||||
import discord
|
||||
from discord import Guild
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.config_service import GuildConfig
|
||||
from services.moderation.modlog_service import ModLogService
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import discord
|
||||
|
||||
from services.xp_service import XpRewardService
|
||||
from lib.constants import CONST
|
||||
from services.xp_service import XpRewardService
|
||||
|
||||
|
||||
async def show(ctx):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import discord
|
||||
from discord.ext.commands import guild_only
|
||||
from discord.ext import bridge, commands
|
||||
from discord.ext.commands import guild_only
|
||||
|
||||
from modules.economy import balance, blackjack, daily, give, slots
|
||||
|
||||
|
||||
|
@ -13,7 +14,7 @@ class Economy(commands.Cog):
|
|||
aliases=["bal", "$"],
|
||||
description="Shows your current Lumi balance.",
|
||||
help="Shows your current Lumi balance. The economy system is global, meaning your balance will be synced in "
|
||||
"all servers.",
|
||||
"all servers.",
|
||||
contexts={discord.InteractionContextType.guild},
|
||||
)
|
||||
@guild_only()
|
||||
|
|
|
@ -7,10 +7,10 @@ from discord.ext import commands
|
|||
from loguru import logger
|
||||
|
||||
from lib import interaction
|
||||
from lib.constants import CONST
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from services.currency_service import Currency
|
||||
from services.stats_service import BlackJackStats
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from lib.constants import CONST
|
||||
|
||||
est = pytz.timezone("US/Eastern")
|
||||
active_blackjack_games = {}
|
||||
|
@ -178,12 +178,12 @@ async def cmd(ctx, bet: int):
|
|||
|
||||
|
||||
def blackjack_show(
|
||||
ctx,
|
||||
bet,
|
||||
player_hand,
|
||||
dealer_hand,
|
||||
player_hand_value,
|
||||
dealer_hand_value,
|
||||
ctx,
|
||||
bet,
|
||||
player_hand,
|
||||
dealer_hand,
|
||||
player_hand_value,
|
||||
dealer_hand_value,
|
||||
):
|
||||
current_time = datetime.now(est).strftime("%I:%M %p")
|
||||
embed = discord.Embed(
|
||||
|
|
|
@ -7,11 +7,10 @@ import discord
|
|||
import pytz
|
||||
from discord.ext import commands
|
||||
|
||||
from lib.constants import CONST
|
||||
from services.currency_service import Currency
|
||||
from services.stats_service import SlotsStats
|
||||
|
||||
from lib.constants import CONST
|
||||
|
||||
est = pytz.timezone("US/Eastern")
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import discord
|
||||
from discord.ext.commands import guild_only
|
||||
from discord.ext import bridge, commands
|
||||
from discord.ext.commands import guild_only
|
||||
|
||||
from modules.levels import leaderboard, level
|
||||
|
||||
|
|
|
@ -132,8 +132,8 @@ class LeaderboardCommandView(discord.ui.View):
|
|||
embed.set_author(name=CONST.STRINGS["xp_lb_author"], icon_url=icon)
|
||||
|
||||
for rank, (user_id, xp, level, xp_needed_for_next_level) in enumerate(
|
||||
xp_lb[:5],
|
||||
start=1,
|
||||
xp_lb[:5],
|
||||
start=1,
|
||||
):
|
||||
try:
|
||||
member = await self.ctx.guild.fetch_member(user_id)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from datetime import datetime
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import guild_only
|
||||
from discord.commands import SlashCommandGroup
|
||||
from discord.ext import bridge, commands, tasks
|
||||
from discord.ext.commands import guild_only
|
||||
|
||||
from Client import LumiBot
|
||||
from modules.config import c_prefix
|
||||
|
@ -99,7 +99,7 @@ class Misc(commands.Cog):
|
|||
aliases=["intro", "introduce"],
|
||||
description="This command can only be used in DMs.",
|
||||
help="Introduce yourself. For now this command "
|
||||
"can only be done in ONE server and only in Lumi's DMs.",
|
||||
"can only be done in ONE server and only in Lumi's DMs.",
|
||||
contexts={discord.InteractionContextType.bot_dm},
|
||||
)
|
||||
@commands.dm_only()
|
||||
|
|
|
@ -35,8 +35,8 @@ async def cmd(self, ctx: bridge.Context) -> None:
|
|||
)
|
||||
|
||||
if not channel or isinstance(
|
||||
channel,
|
||||
(discord.ForumChannel, discord.CategoryChannel),
|
||||
channel,
|
||||
(discord.ForumChannel, discord.CategoryChannel),
|
||||
):
|
||||
await ctx.respond(
|
||||
embed=EmbedBuilder.create_error_embed(
|
||||
|
|
|
@ -10,9 +10,9 @@ _xkcd = Client()
|
|||
|
||||
|
||||
async def print_comic(
|
||||
ctx: bridge.Context,
|
||||
latest: bool = False,
|
||||
number: Optional[int] = None,
|
||||
ctx: bridge.Context,
|
||||
latest: bool = False,
|
||||
number: Optional[int] = None,
|
||||
) -> None:
|
||||
try:
|
||||
if latest:
|
||||
|
|
|
@ -20,11 +20,11 @@ class Moderation(commands.Cog):
|
|||
@commands.bot_has_permissions(ban_members=True)
|
||||
@guild_only()
|
||||
async def ban_command(
|
||||
self,
|
||||
ctx,
|
||||
target: discord.User,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
self,
|
||||
ctx,
|
||||
target: discord.User,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
):
|
||||
await ban.ban_user(self, ctx, target, reason)
|
||||
|
||||
|
@ -75,11 +75,11 @@ class Moderation(commands.Cog):
|
|||
@commands.bot_has_permissions(kick_members=True)
|
||||
@guild_only()
|
||||
async def kick_command(
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
):
|
||||
await kick.kick_user(self, ctx, target, reason)
|
||||
|
||||
|
@ -106,11 +106,11 @@ class Moderation(commands.Cog):
|
|||
@commands.bot_has_permissions(ban_members=True)
|
||||
@guild_only()
|
||||
async def softban_command(
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
):
|
||||
await softban.softban_user(ctx, target, reason)
|
||||
|
||||
|
@ -125,12 +125,12 @@ class Moderation(commands.Cog):
|
|||
@commands.bot_has_permissions(moderate_members=True)
|
||||
@guild_only()
|
||||
async def timeout_command(
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
duration: str,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
duration: str,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
):
|
||||
await timeout.timeout_user(self, ctx, target, duration, reason)
|
||||
|
||||
|
@ -145,11 +145,11 @@ class Moderation(commands.Cog):
|
|||
@commands.bot_has_permissions(ban_members=True)
|
||||
@guild_only()
|
||||
async def unban_command(
|
||||
self,
|
||||
ctx,
|
||||
target: discord.User,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
self,
|
||||
ctx,
|
||||
target: discord.User,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
):
|
||||
await ban.unban_user(ctx, target, reason)
|
||||
|
||||
|
@ -164,11 +164,11 @@ class Moderation(commands.Cog):
|
|||
@commands.bot_has_permissions(moderate_members=True)
|
||||
@guild_only()
|
||||
async def untimeout_command(
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
):
|
||||
await timeout.untimeout_user(ctx, target, reason)
|
||||
|
||||
|
@ -182,11 +182,11 @@ class Moderation(commands.Cog):
|
|||
@bridge.has_permissions(kick_members=True)
|
||||
@guild_only()
|
||||
async def warn_command(
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
self,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
*,
|
||||
reason: str | None = None,
|
||||
):
|
||||
await warn.warn_user(ctx, target, reason)
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import asyncio
|
||||
from typing import Optional
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import MemberConverter
|
||||
|
||||
from lib import formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from modules.moderation.utils.actionable import async_actionable
|
||||
from modules.moderation.utils.case_handler import create_case
|
||||
from typing import Optional
|
||||
from discord.ext.commands import MemberConverter
|
||||
|
||||
|
||||
async def ban_user(cog, ctx, target: discord.User, reason: Optional[str] = None):
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import asyncio
|
||||
|
||||
import discord
|
||||
from discord.ext import pages
|
||||
from discord.ext.commands import UserConverter
|
||||
from services.moderation.case_service import CaseService
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.formatter import format_case_number
|
||||
from modules.moderation.utils.case_embed import (
|
||||
create_case_embed,
|
||||
create_case_list_embed,
|
||||
)
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from discord.ext import pages
|
||||
from lib.formatter import format_case_number
|
||||
from modules.moderation.utils.case_handler import edit_case_modlog
|
||||
from services.moderation.case_service import CaseService
|
||||
|
||||
case_service = CaseService()
|
||||
|
||||
|
@ -52,7 +54,7 @@ async def view_all_cases_in_guild(ctx, guild_id: int):
|
|||
|
||||
pages_list = []
|
||||
for i in range(0, len(cases), 10):
|
||||
chunk = cases[i : i + 10]
|
||||
chunk = cases[i: i + 10]
|
||||
embed = create_case_list_embed(
|
||||
ctx,
|
||||
chunk,
|
||||
|
@ -77,7 +79,7 @@ async def view_all_cases_by_mod(ctx, guild_id: int, moderator: discord.Member):
|
|||
|
||||
pages_list = []
|
||||
for i in range(0, len(cases), 10):
|
||||
chunk = cases[i : i + 10]
|
||||
chunk = cases[i: i + 10]
|
||||
embed = create_case_list_embed(
|
||||
ctx,
|
||||
chunk,
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import asyncio
|
||||
from typing import Optional
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import UserConverter, MemberConverter
|
||||
|
||||
from lib import formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from modules.moderation.utils.actionable import async_actionable
|
||||
from modules.moderation.utils.case_handler import create_case
|
||||
from typing import Optional
|
||||
from discord.ext.commands import UserConverter, MemberConverter
|
||||
|
||||
|
||||
async def kick_user(cog, ctx, target: discord.Member, reason: Optional[str] = None):
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import asyncio
|
||||
import discord
|
||||
from typing import Optional
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import MemberConverter, UserConverter
|
||||
|
||||
from lib import formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
import asyncio
|
||||
import discord
|
||||
import datetime
|
||||
from typing import Optional
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import UserConverter, MemberConverter
|
||||
|
||||
from lib import formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.formatter import format_duration_to_seconds, format_seconds_to_duration_string
|
||||
from modules.moderation.utils.actionable import async_actionable
|
||||
from modules.moderation.utils.case_handler import create_case
|
||||
from typing import Optional
|
||||
from discord.ext.commands import UserConverter, MemberConverter
|
||||
from lib.formatter import format_duration_to_seconds, format_seconds_to_duration_string
|
||||
|
||||
|
||||
async def timeout_user(
|
||||
cog,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
duration: str,
|
||||
reason: Optional[str] = None,
|
||||
cog,
|
||||
ctx,
|
||||
target: discord.Member,
|
||||
duration: str,
|
||||
reason: Optional[str] = None,
|
||||
):
|
||||
bot_member = await MemberConverter().convert(ctx, str(ctx.bot.user.id))
|
||||
await async_actionable(target, ctx.author, bot_member)
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import discord
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
|
||||
|
||||
async def async_actionable(
|
||||
target: discord.Member,
|
||||
invoker: discord.Member,
|
||||
bot_user: discord.Member,
|
||||
target: discord.Member,
|
||||
invoker: discord.Member,
|
||||
bot_user: discord.Member,
|
||||
) -> None:
|
||||
"""
|
||||
Checks if the invoker and client have a higher role than the target user.
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
import discord
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from lib.formatter import format_case_number
|
||||
from typing import Optional
|
||||
import datetime
|
||||
from typing import Optional
|
||||
|
||||
import discord
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.formatter import format_case_number
|
||||
from lib.formatter import format_seconds_to_duration_string
|
||||
|
||||
|
||||
def create_case_embed(
|
||||
ctx,
|
||||
target: discord.User,
|
||||
case_number: int,
|
||||
action_type: str,
|
||||
reason: Optional[str],
|
||||
timestamp: Optional[datetime.datetime] = None,
|
||||
duration: Optional[int] = None,
|
||||
ctx,
|
||||
target: discord.User,
|
||||
case_number: int,
|
||||
action_type: str,
|
||||
reason: Optional[str],
|
||||
timestamp: Optional[datetime.datetime] = None,
|
||||
duration: Optional[int] = None,
|
||||
) -> discord.Embed:
|
||||
embed = EmbedBuilder.create_warning_embed(
|
||||
ctx,
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
from typing import Optional
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import TextChannelConverter, UserConverter
|
||||
from loguru import logger
|
||||
|
||||
from modules.moderation.utils.case_embed import create_case_embed
|
||||
from services.moderation.case_service import CaseService
|
||||
from services.moderation.modlog_service import ModLogService
|
||||
from modules.moderation.utils.case_embed import create_case_embed
|
||||
from typing import Optional
|
||||
from discord.ext.commands import TextChannelConverter, UserConverter
|
||||
|
||||
case_service = CaseService()
|
||||
modlog_service = ModLogService()
|
||||
|
||||
|
||||
async def create_case(
|
||||
ctx,
|
||||
target: discord.User,
|
||||
action_type: str,
|
||||
reason: Optional[str] = None,
|
||||
duration: Optional[int] = None,
|
||||
expires_at: Optional[str] = None,
|
||||
ctx,
|
||||
target: discord.User,
|
||||
action_type: str,
|
||||
reason: Optional[str] = None,
|
||||
duration: Optional[int] = None,
|
||||
expires_at: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
Creates a new moderation case and logs it to the modlog channel if configured.
|
||||
|
@ -88,10 +90,10 @@ async def create_case(
|
|||
|
||||
|
||||
async def edit_case_modlog(
|
||||
ctx,
|
||||
guild_id: int,
|
||||
case_number: int,
|
||||
new_reason: str,
|
||||
ctx,
|
||||
guild_id: int,
|
||||
case_number: int,
|
||||
new_reason: str,
|
||||
) -> bool:
|
||||
"""
|
||||
Edits the reason for an existing case and updates the modlog message if it exists.
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import discord
|
||||
from typing import Optional
|
||||
from discord.ext.commands import UserConverter, MemberConverter
|
||||
import asyncio
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from typing import Optional
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import UserConverter, MemberConverter
|
||||
|
||||
from lib.constants import CONST
|
||||
from modules.moderation.utils.case_handler import create_case
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from modules.moderation.utils.actionable import async_actionable
|
||||
from modules.moderation.utils.case_handler import create_case
|
||||
|
||||
|
||||
async def warn_user(ctx, target: discord.Member, reason: Optional[str]):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import discord
|
||||
from discord.ext.commands import guild_only
|
||||
from discord.commands import SlashCommandGroup
|
||||
from discord.ext import commands
|
||||
from discord.ext.commands import guild_only
|
||||
|
||||
from Client import LumiBot
|
||||
from modules.triggers.add import add_reaction
|
||||
|
@ -28,11 +28,11 @@ class Triggers(commands.Cog):
|
|||
)
|
||||
@guild_only()
|
||||
async def add_text_reaction_command(
|
||||
self,
|
||||
ctx,
|
||||
trigger_text: str,
|
||||
response: str,
|
||||
is_full_match: bool,
|
||||
self,
|
||||
ctx,
|
||||
trigger_text: str,
|
||||
response: str,
|
||||
is_full_match: bool,
|
||||
):
|
||||
await add_reaction(ctx, trigger_text, response, None, False, is_full_match)
|
||||
|
||||
|
@ -43,11 +43,11 @@ class Triggers(commands.Cog):
|
|||
)
|
||||
@guild_only()
|
||||
async def add_emoji_reaction_command(
|
||||
self,
|
||||
ctx,
|
||||
trigger_text: str,
|
||||
emoji: discord.Emoji,
|
||||
is_full_match: bool,
|
||||
self,
|
||||
ctx,
|
||||
trigger_text: str,
|
||||
emoji: discord.Emoji,
|
||||
is_full_match: bool,
|
||||
):
|
||||
await add_reaction(ctx, trigger_text, None, emoji.id, True, is_full_match)
|
||||
|
||||
|
@ -58,9 +58,9 @@ class Triggers(commands.Cog):
|
|||
)
|
||||
@guild_only()
|
||||
async def delete_reaction_command(
|
||||
self,
|
||||
ctx,
|
||||
reaction_id: int,
|
||||
self,
|
||||
ctx,
|
||||
reaction_id: int,
|
||||
):
|
||||
await delete_reaction(ctx, reaction_id)
|
||||
|
||||
|
@ -71,8 +71,8 @@ class Triggers(commands.Cog):
|
|||
)
|
||||
@guild_only()
|
||||
async def list_reactions_command(
|
||||
self,
|
||||
ctx,
|
||||
self,
|
||||
ctx,
|
||||
):
|
||||
await list_reactions(ctx)
|
||||
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
from typing import Optional
|
||||
|
||||
from discord.ext import bridge
|
||||
from services.reactions_service import CustomReactionsService
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
|
||||
from lib import formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib import formatter
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from services.reactions_service import CustomReactionsService
|
||||
|
||||
|
||||
async def add_reaction(
|
||||
ctx: bridge.Context,
|
||||
trigger_text: str,
|
||||
response: Optional[str],
|
||||
emoji_id: Optional[int],
|
||||
is_emoji: bool,
|
||||
is_full_match: bool,
|
||||
ctx: bridge.Context,
|
||||
trigger_text: str,
|
||||
response: Optional[str],
|
||||
emoji_id: Optional[int],
|
||||
is_emoji: bool,
|
||||
is_full_match: bool,
|
||||
) -> None:
|
||||
if ctx.guild is None:
|
||||
return
|
||||
|
@ -24,15 +25,15 @@ async def add_reaction(
|
|||
creator_id: int = ctx.author.id
|
||||
|
||||
if not await check_reaction_limit(
|
||||
reaction_service,
|
||||
guild_id,
|
||||
reaction_service,
|
||||
guild_id,
|
||||
):
|
||||
return
|
||||
|
||||
if not await check_existing_trigger(
|
||||
reaction_service,
|
||||
guild_id,
|
||||
trigger_text,
|
||||
reaction_service,
|
||||
guild_id,
|
||||
trigger_text,
|
||||
):
|
||||
return
|
||||
|
||||
|
@ -82,8 +83,8 @@ async def add_reaction(
|
|||
|
||||
|
||||
async def check_reaction_limit(
|
||||
reaction_service: CustomReactionsService,
|
||||
guild_id: int,
|
||||
reaction_service: CustomReactionsService,
|
||||
guild_id: int,
|
||||
) -> bool:
|
||||
limit_reached = await reaction_service.count_custom_reactions(guild_id) >= 100
|
||||
|
||||
|
@ -94,9 +95,9 @@ async def check_reaction_limit(
|
|||
|
||||
|
||||
async def check_existing_trigger(
|
||||
reaction_service: CustomReactionsService,
|
||||
guild_id: int,
|
||||
trigger_text: str,
|
||||
reaction_service: CustomReactionsService,
|
||||
guild_id: int,
|
||||
trigger_text: str,
|
||||
) -> bool:
|
||||
existing_trigger = await reaction_service.find_trigger(guild_id, trigger_text)
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from discord.ext import bridge
|
||||
from services.reactions_service import CustomReactionsService
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
from services.reactions_service import CustomReactionsService
|
||||
|
||||
|
||||
async def delete_reaction(ctx: bridge.Context, reaction_id: int) -> None:
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
from typing import Any, Dict, List
|
||||
|
||||
import discord
|
||||
from discord.ext import bridge, pages
|
||||
|
||||
from lib import formatter
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from services.reactions_service import CustomReactionsService
|
||||
from typing import Any, Dict, List
|
||||
from lib import formatter
|
||||
|
||||
import discord
|
||||
|
||||
|
||||
async def list_reactions(ctx: bridge.Context) -> None:
|
||||
|
|
1210
poetry.lock
generated
1210
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@ from datetime import datetime, timedelta
|
|||
from typing import List, Optional, Tuple
|
||||
|
||||
import pytz
|
||||
|
||||
from db import database
|
||||
from lib.constants import CONST
|
||||
from services.currency_service import Currency
|
||||
|
@ -68,14 +69,14 @@ class Dailies:
|
|||
"""
|
||||
|
||||
check_1: bool = (
|
||||
self.claimed_at.date() == (self.time_now - timedelta(days=1)).date()
|
||||
self.claimed_at.date() == (self.time_now - timedelta(days=1)).date()
|
||||
)
|
||||
check_2: bool = (
|
||||
self.claimed_at.date() == (self.time_now - timedelta(days=2)).date()
|
||||
self.claimed_at.date() == (self.time_now - timedelta(days=2)).date()
|
||||
)
|
||||
check_3: bool = (
|
||||
self.claimed_at.date() == self.time_now.date()
|
||||
and self.claimed_at < self.reset_time
|
||||
self.claimed_at.date() == self.time_now.date()
|
||||
and self.claimed_at < self.reset_time
|
||||
)
|
||||
|
||||
return check_1 or check_2 or check_3
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.exceptions.LumiExceptions import LumiException
|
||||
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
from db.database import execute_query, select_query_one, select_query_dict
|
||||
from typing import Optional, Dict, Any, List
|
||||
|
||||
from db.database import execute_query, select_query_one, select_query_dict
|
||||
|
||||
|
||||
class CaseService:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def create_case(
|
||||
self,
|
||||
guild_id: int,
|
||||
target_id: int,
|
||||
moderator_id: int,
|
||||
action_type: str,
|
||||
reason: Optional[str] = None,
|
||||
duration: Optional[int] = None,
|
||||
expires_at: Optional[str] = None,
|
||||
modlog_message_id: Optional[int] = None,
|
||||
self,
|
||||
guild_id: int,
|
||||
target_id: int,
|
||||
moderator_id: int,
|
||||
action_type: str,
|
||||
reason: Optional[str] = None,
|
||||
duration: Optional[int] = None,
|
||||
expires_at: Optional[str] = None,
|
||||
modlog_message_id: Optional[int] = None,
|
||||
) -> int:
|
||||
# Get the next case number for the guild
|
||||
query: str = """
|
||||
|
@ -62,10 +63,10 @@ class CaseService:
|
|||
execute_query(query, (guild_id, case_number))
|
||||
|
||||
def edit_case_reason(
|
||||
self,
|
||||
guild_id: int,
|
||||
case_number: int,
|
||||
new_reason: Optional[str] = None,
|
||||
self,
|
||||
guild_id: int,
|
||||
case_number: int,
|
||||
new_reason: Optional[str] = None,
|
||||
) -> bool:
|
||||
query = """
|
||||
UPDATE cases
|
||||
|
@ -102,9 +103,9 @@ class CaseService:
|
|||
return result[0] if result else None
|
||||
|
||||
def fetch_case_by_guild_and_number(
|
||||
self,
|
||||
guild_id: int,
|
||||
case_number: int,
|
||||
self,
|
||||
guild_id: int,
|
||||
case_number: int,
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
query: str = """
|
||||
SELECT * FROM cases
|
||||
|
@ -125,9 +126,9 @@ class CaseService:
|
|||
return results
|
||||
|
||||
def fetch_cases_by_target(
|
||||
self,
|
||||
guild_id: int,
|
||||
target_id: int,
|
||||
self,
|
||||
guild_id: int,
|
||||
target_id: int,
|
||||
) -> List[Dict[str, Any]]:
|
||||
query: str = """
|
||||
SELECT * FROM cases
|
||||
|
@ -138,9 +139,9 @@ class CaseService:
|
|||
return results
|
||||
|
||||
def fetch_cases_by_moderator(
|
||||
self,
|
||||
guild_id: int,
|
||||
moderator_id: int,
|
||||
self,
|
||||
guild_id: int,
|
||||
moderator_id: int,
|
||||
) -> List[Dict[str, Any]]:
|
||||
query: str = """
|
||||
SELECT * FROM cases
|
||||
|
@ -154,9 +155,9 @@ class CaseService:
|
|||
return results
|
||||
|
||||
def fetch_cases_by_action_type(
|
||||
self,
|
||||
guild_id: int,
|
||||
action_type: str,
|
||||
self,
|
||||
guild_id: int,
|
||||
action_type: str,
|
||||
) -> List[Dict[str, Any]]:
|
||||
query: str = """
|
||||
SELECT * FROM cases
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from db.database import execute_query, select_query_one
|
||||
from typing import Optional
|
||||
|
||||
from db.database import execute_query, select_query_one
|
||||
|
||||
|
||||
class ModLogService:
|
||||
def __init__(self):
|
||||
|
|
|
@ -9,9 +9,9 @@ class CustomReactionsService:
|
|||
pass
|
||||
|
||||
async def find_trigger(
|
||||
self,
|
||||
guild_id: int,
|
||||
message_content: str,
|
||||
self,
|
||||
guild_id: int,
|
||||
message_content: str,
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
message_content = message_content.lower()
|
||||
query = """
|
||||
|
@ -24,8 +24,8 @@ class CustomReactionsService:
|
|||
LIMIT 1
|
||||
"""
|
||||
if result := database.select_query(
|
||||
query,
|
||||
(guild_id, message_content, message_content, guild_id),
|
||||
query,
|
||||
(guild_id, message_content, message_content, guild_id),
|
||||
):
|
||||
reaction = result[0] # Get the first result from the list
|
||||
return {
|
||||
|
@ -96,15 +96,15 @@ class CustomReactionsService:
|
|||
]
|
||||
|
||||
async def create_custom_reaction(
|
||||
self,
|
||||
guild_id: int,
|
||||
creator_id: int,
|
||||
trigger_text: str,
|
||||
response: Optional[str] = None,
|
||||
emoji_id: Optional[int] = None,
|
||||
is_emoji: bool = False,
|
||||
is_full_match: bool = False,
|
||||
is_global: bool = True,
|
||||
self,
|
||||
guild_id: int,
|
||||
creator_id: int,
|
||||
trigger_text: str,
|
||||
response: Optional[str] = None,
|
||||
emoji_id: Optional[int] = None,
|
||||
is_emoji: bool = False,
|
||||
is_full_match: bool = False,
|
||||
is_global: bool = True,
|
||||
) -> bool:
|
||||
if await self.count_custom_reactions(guild_id) >= 100:
|
||||
return False
|
||||
|
@ -130,13 +130,13 @@ class CustomReactionsService:
|
|||
return True
|
||||
|
||||
async def edit_custom_reaction(
|
||||
self,
|
||||
reaction_id: int,
|
||||
new_response: Optional[str] = None,
|
||||
new_emoji_id: Optional[int] = None,
|
||||
is_emoji: Optional[bool] = None,
|
||||
is_full_match: Optional[bool] = None,
|
||||
is_global: Optional[bool] = None,
|
||||
self,
|
||||
reaction_id: int,
|
||||
new_response: Optional[str] = None,
|
||||
new_emoji_id: Optional[int] = None,
|
||||
is_emoji: Optional[bool] = None,
|
||||
is_full_match: Optional[bool] = None,
|
||||
is_global: Optional[bool] = None,
|
||||
) -> bool:
|
||||
query = """
|
||||
UPDATE custom_reactions
|
||||
|
|
|
@ -30,11 +30,11 @@ class Comic:
|
|||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
xkcd_dict: dict[str, Any],
|
||||
raw_image: bytes | None = None,
|
||||
comic_url: str | None = None,
|
||||
explanation_url: str | None = None,
|
||||
self,
|
||||
xkcd_dict: dict[str, Any],
|
||||
raw_image: bytes | None = None,
|
||||
comic_url: str | None = None,
|
||||
explanation_url: str | None = None,
|
||||
) -> None:
|
||||
self.id: int | None = xkcd_dict.get("num")
|
||||
self.date: datetime.date | None = self._determine_date(xkcd_dict)
|
||||
|
@ -104,9 +104,9 @@ class Comic:
|
|||
|
||||
class Client:
|
||||
def __init__(
|
||||
self,
|
||||
api_url: str = "https://xkcd.com",
|
||||
explanation_wiki_url: str = "https://www.explainxkcd.com/wiki/index.php/",
|
||||
self,
|
||||
api_url: str = "https://xkcd.com",
|
||||
explanation_wiki_url: str = "https://www.explainxkcd.com/wiki/index.php/",
|
||||
) -> None:
|
||||
self._api_url = api_url
|
||||
self._explanation_wiki_url = explanation_wiki_url
|
||||
|
|
|
@ -132,9 +132,9 @@ class XpService:
|
|||
|
||||
@staticmethod
|
||||
def generate_progress_bar(
|
||||
current_value: int,
|
||||
target_value: int,
|
||||
bar_length: int = 10,
|
||||
current_value: int,
|
||||
target_value: int,
|
||||
bar_length: int = 10,
|
||||
) -> str:
|
||||
"""
|
||||
Generates an XP progress bar based on the current level and XP.
|
||||
|
|
Loading…
Reference in a new issue