-
-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Look at GH/#38 for changelog if you brave enough (186 commits - im not going to list all changes) Co-authored-by: notKqi <[email protected]> Co-authored-by: Predeactor <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: aikaterna <[email protected]> Co-authored-by: Moose <[email protected]>
- Loading branch information
1 parent
28bf72c
commit f88312c
Showing
36 changed files
with
4,793 additions
and
3,639 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
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,169 @@ | ||
from abc import ABC, abstractmethod | ||
from asyncio import Lock | ||
from io import BytesIO | ||
from logging import Logger | ||
from typing import List | ||
|
||
from aiohttp import ClientSession | ||
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase | ||
from redbot.core import Config, commands | ||
from redbot.core.bot import Red | ||
|
||
|
||
class MixinMeta(ABC): | ||
""" | ||
Base class for well behaved type hint detection with composite class. | ||
Basically, to keep developers sane when not all attributes are defined in each mixin. | ||
""" | ||
|
||
bot: Red | ||
log: Logger | ||
|
||
config: Config | ||
|
||
_db_ready: bool | ||
_db_lock: Lock | ||
client: AsyncIOMotorClient | ||
db: AsyncIOMotorDatabase | ||
session: ClientSession | ||
|
||
@abstractmethod | ||
async def _connect_to_mongo(self): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _create_user(self, user, server): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _hex_to_rgb(self, hex_num: str, a: int) -> tuple: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _badge_convert_dict(self, userinfo): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _process_purchase(self, ctx) -> bool: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def _truncate_text(self, text, max_length) -> str: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def asyncify(self, func, *args, **kwargs): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def asyncify_thread(self, func, *args, **kwargs): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def asyncify_process(self, func, *args, **kwargs): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def hash_with_md5(self, string): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _handle_levelup(self, user, userinfo, server, channel): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _required_exp(self, level: int) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _level_exp(self, level: int) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _find_level(self, total_exp) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _find_server_rank(self, user, server) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _find_global_rank(self, user) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _find_server_exp(self, user, server) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _find_server_rep_rank(self, user, server) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _find_global_rep_rank(self, user) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def draw_profile(self, user, server) -> BytesIO: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def draw_rank(self, user, server) -> BytesIO: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def draw_levelup(self, user, server) -> BytesIO: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _process_exp(self, message, userinfo, exp: int): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _give_chat_credit(self, user, server): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _valid_image_url(self, url): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
async def _auto_color(self, ctx, url: str, ranks) -> List[str]: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def _center(self, start, end, text, font) -> int: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def char_in_font(self, unicode_char, font) -> bool: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def _contrast(self, bg_color, color1, color2): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def _luminance(self, color): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def _contrast_ratio(self, bgcolor, foreground): | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def _name(self, user, max_length) -> str: | ||
raise NotImplementedError | ||
|
||
@abstractmethod | ||
def _add_corners(self, im, rad, multiplier=6): | ||
raise NotImplementedError | ||
|
||
|
||
class CompositeMetaClass(type(commands.Cog), type(ABC)): | ||
""" | ||
This allows the metaclass used for proper type detection to | ||
coexist with discord.py's metaclass | ||
""" | ||
|
||
pass |
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,27 @@ | ||
import argparse | ||
from shlex import split | ||
|
||
from redbot.core import commands | ||
|
||
|
||
class NoExitParser(argparse.ArgumentParser): | ||
def error(self, message): | ||
raise commands.BadArgument(message) | ||
|
||
|
||
class TopParser(commands.Converter): | ||
page: int | ||
global_top: bool | ||
rep: bool | ||
server: str | ||
|
||
async def convert(self, ctx, argument): | ||
parser = NoExitParser(description="top command arguments parser", add_help=False) | ||
parser.add_argument("page", nargs="?", type=int, default="1") | ||
parser.add_argument("-g", "--global", dest="global_top", action="store_true") | ||
parser.add_argument("-r", "--rep", action="store_true") | ||
parser.add_argument("-s", "--server", "--guild", type=str, nargs="*") | ||
try: | ||
return parser.parse_args(split(argument)) | ||
except ValueError as e: | ||
raise commands.BadArgument(*e.args) |
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,21 @@ | ||
from ..abc import CompositeMetaClass | ||
from .database import DataBase | ||
from .db_converters import DBConverters | ||
from .lvladmin import LevelAdmin | ||
from .lvlset import LevelSet | ||
from .other import Other | ||
from .profiles import Profiles | ||
from .top import Top | ||
|
||
|
||
class LevelerCommands( | ||
Profiles, | ||
DataBase, | ||
Top, | ||
LevelAdmin, | ||
LevelSet, | ||
DBConverters, | ||
Other, | ||
metaclass=CompositeMetaClass, | ||
): | ||
"""Class joining all command subclasses""" |
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,114 @@ | ||
import discord | ||
from redbot.core import commands | ||
from redbot.core.utils import chat_formatting as chat | ||
from tabulate import tabulate | ||
|
||
from ..abc import CompositeMetaClass, MixinMeta | ||
|
||
concurrency = commands.MaxConcurrency(1, per=commands.BucketType.default, wait=False) | ||
|
||
|
||
def levelerset_concurrency(): | ||
"""Custom concurrency pool for levelerset commands""" | ||
|
||
def decorator(func): | ||
if isinstance(func, commands.Command): | ||
func._max_concurrency = concurrency | ||
else: | ||
func.__commands_max_concurrency__ = concurrency | ||
return func | ||
|
||
return decorator | ||
|
||
|
||
class DataBase(MixinMeta, metaclass=CompositeMetaClass): | ||
@commands.is_owner() | ||
@commands.group() | ||
async def levelerset(self, ctx): | ||
""" | ||
MongoDB server configuration options. | ||
Use that command in DM to see current settings. | ||
""" | ||
if not ctx.invoked_subcommand and ctx.channel.type == discord.ChannelType.private: | ||
settings = [ | ||
(setting.replace("_", " ").title(), value) | ||
for setting, value in (await self.config.custom("MONGODB").get_raw()).items() | ||
if value | ||
] | ||
await ctx.send(chat.box(tabulate(settings, tablefmt="plain"))) | ||
|
||
@levelerset.command() | ||
@levelerset_concurrency() | ||
async def reconnect(self, ctx): | ||
"""Attempt to reconnect to MongoDB without changing settings""" | ||
message = await ctx.send("Reconnecting...") | ||
client = await self._connect_to_mongo() | ||
if not client: | ||
return await message.edit(content="Failed to connect...") | ||
await message.edit(content="Reconnected.") | ||
|
||
@levelerset.command() | ||
@levelerset_concurrency() | ||
async def host(self, ctx, host: str = "localhost"): | ||
"""Set the MongoDB server host.""" | ||
await self.config.custom("MONGODB").host.set(host) | ||
message = await ctx.send( | ||
f"MongoDB host set to {host}.\nNow trying to connect to the new host..." | ||
) | ||
client = await self._connect_to_mongo() | ||
if not client: | ||
return await message.edit( | ||
content=message.content.replace("Now trying to connect to the new host...", "") | ||
+ "Failed to connect. Please try again with a valid host." | ||
) | ||
await message.edit( | ||
content=message.content.replace("Now trying to connect to the new host...", "") | ||
) | ||
|
||
@levelerset.command() | ||
@levelerset_concurrency() | ||
async def port(self, ctx, port: int = 27017): | ||
"""Set the MongoDB server port.""" | ||
await self.config.custom("MONGODB").port.set(port) | ||
message = await ctx.send( | ||
f"MongoDB port set to {port}.\nNow trying to connect to the new port..." | ||
) | ||
client = await self._connect_to_mongo() | ||
if not client: | ||
return await message.edit( | ||
content=message.content.replace("Now trying to connect to the new port...", "") | ||
+ "Failed to connect. Please try again with a valid port." | ||
) | ||
await message.edit( | ||
content=message.content.replace("Now trying to connect to the new port...", "") | ||
) | ||
|
||
@levelerset.command(aliases=["creds"]) | ||
@levelerset_concurrency() | ||
async def credentials(self, ctx, username: str = None, password: str = None): | ||
"""Set the MongoDB server credentials.""" | ||
await self.config.custom("MONGODB").username.set(username) | ||
await self.config.custom("MONGODB").password.set(password) | ||
message = await ctx.send("MongoDB credentials set.\nNow trying to connect...") | ||
client = await self._connect_to_mongo() | ||
if not client: | ||
return await message.edit( | ||
content=message.content.replace("Now trying to connect...", "") | ||
+ "Failed to connect. Please try again with valid credentials." | ||
) | ||
await message.edit(content=message.content.replace("Now trying to connect...", "")) | ||
|
||
@levelerset.command() | ||
@levelerset_concurrency() | ||
async def dbname(self, ctx, dbname: str = "leveler"): | ||
"""Set the MongoDB db name.""" | ||
await self.config.custom("MONGODB").db_name.set(dbname) | ||
message = await ctx.send("MongoDB db name set.\nNow trying to connect...") | ||
client = await self._connect_to_mongo() | ||
if not client: | ||
return await message.edit( | ||
content=message.content.replace("Now trying to connect...", "") | ||
+ "Failed to connect. Please try again with a valid db name." | ||
) | ||
await message.edit(content=message.content.replace("Now trying to connect...", "")) |
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 leveler.abc import CompositeMetaClass | ||
|
||
from .meesix import MeeSix | ||
|
||
|
||
class DBConverters(MeeSix, metaclass=CompositeMetaClass): | ||
"""Database converters commands""" |
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,10 @@ | ||
from redbot.core import commands | ||
|
||
from leveler.abc import CompositeMetaClass | ||
|
||
|
||
class DBConvertersBaseCMD(metaclass=CompositeMetaClass): | ||
@commands.group() | ||
@commands.is_owner() | ||
async def lvlconvert(self, ctx): | ||
"""Convert levels from other leveling systems.""" |
Oops, something went wrong.