diff --git a/lib/const.py b/lib/const.py
index 2255c79..318a974 100644
--- a/lib/const.py
+++ b/lib/const.py
@@ -2,14 +2,14 @@ import os
import json
import yaml
from functools import lru_cache
-from typing import Optional, Callable, Set
+from typing import Optional, Callable, Set, List, Dict
class _parser:
"""Internal parses class. Not intended to be used outside of this module."""
@lru_cache(maxsize=1024)
- def read_settings(self) -> dict:
+ def read_s(self) -> dict:
return self._read_file("settings.yaml", yaml.safe_load)
def read_json(self, path: str) -> dict:
@@ -22,10 +22,20 @@ class _parser:
class _constants:
_p = _parser()
- _s = _parser().read_settings()
+ _s = _parser().read_s()
# bot credentials
- TOKEN: Optional[str] = os.getenv("TOKEN")
+ TOKEN: Optional[str] = os.environ.get("TOKEN")
+ INSTANCE: Optional[str] = os.environ.get("INSTANCE")
+ XP_GAIN_PER_MESSAGE: int = int(os.environ.get("XP_GAIN_PER_MESSAGE", 1))
+ XP_GAIN_COOLDOWN: int = int(os.environ.get("XP_GAIN_COOLDOWN", 8))
+ DBX_TOKEN: Optional[str] = os.environ.get("DBX_OAUTH2_REFRESH_TOKEN")
+ DBX_APP_KEY: Optional[str] = os.environ.get("DBX_APP_KEY")
+ DBX_APP_SECRET: Optional[str] = os.environ.get("DBX_APP_SECRET")
+ MARIADB_USER: Optional[str] = os.environ.get("MARIADB_USER")
+ MARIADB_PASSWORD: Optional[str] = os.environ.get("MARIADB_PASSWORD")
+ MARIADB_ROOT_PASSWORD: Optional[str] = os.environ.get("MARIADB_ROOT_PASSWORD")
+ MARIADB_DATABASE: Optional[str] = os.environ.get("MARIADB_DATABASE")
OWNER_IDS: Optional[Set[int]] = (
{int(id.strip()) for id in os.environ.get("OWNER_IDS", "").split(",") if id}
@@ -33,13 +43,76 @@ class _constants:
else None
)
- # settings
+ # metadata
+ TITLE: str = _s["info"]["title"]
+ AUTHOR: str = _s["info"]["author"]
+ LICENSE: str = _s["info"]["license"]
+ VERSION: str = _s["info"]["version"]
+ REPO_URL: str = _s["info"]["repository_url"]
+ INVITE_URL: str = _s["info"]["invite_url"]
+
+ # loguru
LOG_LEVEL: str = _s["logs"]["level"] or "DEBUG"
LOG_FORMAT: str = _s["logs"]["format"]
+
+ # cogs
COG_IGNORE_LIST: Set[str] = (
set(_s["cogs"]["ignore"]) if _s["cogs"]["ignore"] else set()
)
+ # images
+ ALLOWED_IMAGE_EXTENSIONS: List[str] = _s["images"]["allowed_image_extensions"]
+ BIRTHDAY_GIF_URL: str = _s["images"]["birthday_gif_url"]
+
+ # colors
+ COLOR_DEFAULT: int = _s["colors"]["color_default"]
+ COLOR_WARNING: int = _s["colors"]["color_warning"]
+ COLOR_ERROR: int = _s["colors"]["color_error"]
+
+ # economy
+ DAILY_REWARD: int = _s["economy"]["daily_reward"]
+ BLACKJACK_MULTIPLIER: float = _s["economy"]["blackjack_multiplier"]
+ BLACKJACK_HIT_EMOJI: str = _s["economy"]["blackjack_hit_emoji"]
+ BLACKJACK_STAND_EMOJI: str = _s["economy"]["blackjack_stand_emoji"]
+ SLOTS_MULTIPLIERS: Dict[str, float] = _s["economy"]["slots_multipliers"]
+
+ # art from git repository
+ _fetch_url: str = _s["art"]["fetch_url"]
+
+ LUMI_LOGO_OPAQUE: str = _fetch_url + _s["art"]["logo"]["opaque"]
+ LUMI_LOGO_TRANSPARENT: str = _fetch_url + _s["art"]["logo"]["transparent"]
+ BOOST_ICON: str = _fetch_url + _s["art"]["icons"]["boost"]
+ CHECK_ICON: str = _fetch_url + _s["art"]["icons"]["check"]
+ CROSS_ICON: str = _fetch_url + _s["art"]["icons"]["cross"]
+ EXCLAIM_ICON: str = _fetch_url + _s["art"]["icons"]["exclaim"]
+ HAMMER_ICON: str = _fetch_url + _s["art"]["icons"]["hammer"]
+ MONEY_BAG_ICON: str = _fetch_url + _s["art"]["icons"]["money_bag"]
+ MONEY_COINS_ICON: str = _fetch_url + _s["art"]["icons"]["money_coins"]
+ QUESTION_ICON: str = _fetch_url + _s["art"]["icons"]["question"]
+ STREAK_ICON: str = _fetch_url + _s["art"]["icons"]["streak"]
+ STREAK_BRONZE_ICON: str = _fetch_url + _s["art"]["icons"]["streak_bronze"]
+ STREAK_GOLD_ICON: str = _fetch_url + _s["art"]["icons"]["streak_gold"]
+ STREAK_SILVER_ICON: str = _fetch_url + _s["art"]["icons"]["streak_silver"]
+ WARNING_ICON: str = _fetch_url + _s["art"]["icons"]["warning"]
+
+ # art from imgur
+ FLOWERS_ART: str = _s["art"]["juicybblue"]["flowers"]
+ TEAPOT_ART: str = _s["art"]["juicybblue"]["teapot"]
+ MUFFIN_ART: str = _s["art"]["juicybblue"]["muffin"]
+ CLOUD_ART: str = _s["art"]["other"]["cloud"]
+ TROPHY_ART: str = _s["art"]["other"]["trophy"]
+
+ # emotes
+ EMOTES_SERVER_ID: int = _s["emotes"]["guild_id"]
+ EMOTE_IDS: Dict[str, int] = _s["emotes"]["emote_ids"]
+
+ # introductions (currently only usable in ONE guild)
+ INTRODUCTIONS_GUILD_ID: int = _s["introductions"]["intro_guild_id"]
+ INTRODUCTIONS_CHANNEL_ID: int = _s["introductions"]["intro_channel_id"]
+ INTRODUCTIONS_QUESTION_MAPPING: Dict[str, str] = _s["introductions"][
+ "intro_question_mapping"
+ ]
+
# Reponse strings
# TODO: Implement switching between languages
STRINGS = _p.read_json("strings.en-US")
diff --git a/modules/misc/ping.py b/modules/misc/ping.py
index 7cfe18e..8ba78e0 100644
--- a/modules/misc/ping.py
+++ b/modules/misc/ping.py
@@ -1,4 +1,6 @@
from discord.ext import commands
+from lib.const import CONST
+from ui.embeds import builder
class Ping(commands.Cog):
@@ -10,7 +12,16 @@ class Ping(commands.Cog):
usage="ping",
)
async def ping(self, ctx: commands.Context[commands.Bot]) -> None:
- await ctx.send(f"Pong! Latency: {self.bot.latency * 1000:.2f}ms")
+ embed = builder.create_success_embed(
+ ctx,
+ author_text=CONST.STRINGS["ping_author"],
+ description=CONST.STRINGS["ping_pong"],
+ footer_text=CONST.STRINGS["ping_footer"].format(
+ round(1000 * self.bot.latency),
+ ),
+ )
+
+ await ctx.send(embed=embed)
async def setup(bot: commands.Bot) -> None:
diff --git a/settings.yaml b/settings.yaml
index 93a1781..11e567d 100644
--- a/settings.yaml
+++ b/settings.yaml
@@ -1,6 +1,110 @@
+info:
+ title: Luminara
+ author: wlinator
+ license: GNU General Public License v3.0
+ version: "2.9.0" # "Settings & Customizability" update
+ repository_url: https://git.wlinator.org/Luminara/Lumi
+ invite_url: https://discord.com/oauth2/authorize?client_id=1038050427272429588&permissions=8&scope=bot
+
logs:
level: DEBUG
format: "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}"
cogs:
ignore: # add cogs to ignore here
+
+images:
+ allowed_image_extensions:
+ - .jpg
+ - .png
+ birthday_gif_url: https://media1.tenor.com/m/NXvU9jbBUGMAAAAC/fireworks.gif
+
+colors:
+ color_default: 0xFF8C00
+ color_warning: 0xFF7600
+ color_error: 0xFF4500
+
+economy:
+ daily_reward: 500
+ blackjack_multiplier: 1.4
+ blackjack_hit_emoji: <:hit:1119262723285467156>
+ blackjack_stand_emoji: <:stand:1118923298298929154>
+ slots_multipliers:
+ pair: 1.5
+ three_of_a_kind: 4
+ three_diamonds: 6
+ jackpot: 15
+
+art:
+ fetch_url: https://git.wlinator.org/Luminara/Art/raw/branch/main/
+ logo:
+ opaque: lumi_logo.png
+ transparent: lumi_logo_transparent.png
+ icons:
+ boost: lumi_boost.png
+ check: lumi_check.png
+ cross: lumi_cross.png
+ exclaim: lumi_exclaim.png
+ hammer: lumi_hammer.png
+ money_bag: lumi_money_bag.png
+ money_coins: lumi_money_coins.png
+ question: lumi_question.png
+ streak: lumi_streak.png
+ streak_bronze: lumi_streak_bronze.png
+ streak_gold: lumi_streak_gold.png
+ streak_silver: lumi_streak_silver.png
+ warning: lumi_warning.png
+ juicybblue:
+ flowers: https://i.imgur.com/79XfsbS.png
+ teapot: https://i.imgur.com/wFsgSnr.png
+ muffin: https://i.imgur.com/hSauh7K.png
+ other:
+ cloud: https://i.imgur.com/rc68c43.png
+ trophy: https://i.imgur.com/dvIIr2G.png
+
+emotes:
+ guild_id: 1038051105642401812
+ emote_ids:
+ slots_animated_id: 1119262805309259776
+ slots_0_id: 1119262803816095825
+ slots_1_id: 1119262801261760592
+ slots_2_id: 1119262800049614939
+ slots_3_id: 1119262796497039510
+ slots_4_id: 1119262794676715681
+ slots_5_id: 1119262792386621555
+ slots_6_id: 1119262791061229669
+ S_Wide: 1119286730302955651
+ L_Wide: 1119286763802857533
+ O_Wide: 1119286787169329203
+ T_Wide: 1119286804634406942
+ CBorderBLeft: 1119286973572595712
+ CBorderBRight: 1119286918459445408
+ CBorderTLeft: 1119287006464331806
+ CBorderTRight: 1119286865284051035
+ HBorderB: 1119286936155213835
+ HBorderT: 1119287027662344322
+ VBorder: 1119286889854279680
+ WSmall: 1119288536282173490
+ ISmall: 1119288552673517608
+ NSmall: 1119288579382857830
+ LCentered: 1119287296127156325
+ OCentered: 1119287563245584394
+ SCentered: 1119287327588634647
+ ECentered: 1119287343833165945
+ Blank: 1119287267001905283
+ lost: 1119288454212243607
+
+introductions:
+ intro_guild_id: 719227135151046700
+ intro_channel_id: 973619250507972600
+ intro_question_mapping:
+ Nickname: how would you like to be identified in the server? (nickname)
+ Age: how old are you?
+ Region: where do you live?
+ Languages: which languages do you speak?
+ Pronouns: what are your preferred pronouns?
+ Sexuality: what's your sexuality?
+ Relationship status: what's your current relationship status?
+ Likes & interests: likes & interests
+ Dislikes: dislikes
+ EXTRAS: "EXTRAS: job status, zodiac sign, hobbies, etc. Tell us about yourself!"
diff --git a/ui/embeds.py b/ui/embeds.py
new file mode 100644
index 0000000..da8cb9b
--- /dev/null
+++ b/ui/embeds.py
@@ -0,0 +1,206 @@
+import datetime
+
+import discord
+
+from lib.const import CONST
+
+
+class builder:
+ @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,
+ ) -> discord.Embed:
+ if not hide_author:
+ if not author_text:
+ author_text = ctx.author.name
+ elif show_name:
+ description = f"**{ctx.author.name}** {description}"
+
+ if not hide_author_icon and not author_icon_url:
+ author_icon_url = ctx.author.display_avatar.url
+
+ if not footer_text:
+ footer_text = "Luminara"
+ if not footer_icon_url:
+ footer_icon_url = CONST.LUMI_LOGO_TRANSPARENT
+
+ embed = discord.Embed(
+ title=title,
+ description=description,
+ color=color or CONST.COLOR_DEFAULT,
+ )
+ if not hide_author:
+ embed.set_author(
+ name=author_text,
+ icon_url=None if hide_author_icon else author_icon_url,
+ url=author_url,
+ )
+ embed.set_footer(text=footer_text, icon_url=footer_icon_url)
+ if not hide_timestamp:
+ embed.timestamp = timestamp or datetime.datetime.now()
+
+ if image_url:
+ embed.set_image(url=image_url)
+ if thumbnail_url:
+ embed.set_thumbnail(url=thumbnail_url)
+
+ return embed
+
+ @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,
+ ) -> discord.Embed:
+ return builder.create_embed(
+ ctx,
+ title=title,
+ author_text=author_text,
+ author_icon_url=author_icon_url or CONST.CROSS_ICON,
+ author_url=author_url,
+ description=description,
+ color=CONST.COLOR_ERROR,
+ footer_text=footer_text,
+ footer_icon_url=CONST.LUMI_LOGO_TRANSPARENT,
+ show_name=show_name,
+ image_url=image_url,
+ thumbnail_url=thumbnail_url,
+ timestamp=timestamp,
+ hide_author=hide_author,
+ hide_author_icon=hide_author_icon,
+ hide_timestamp=hide_timestamp,
+ )
+
+ @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,
+ ) -> discord.Embed:
+ return builder.create_embed(
+ ctx,
+ title=title,
+ author_text=author_text,
+ author_icon_url=author_icon_url or CONST.CHECK_ICON,
+ author_url=author_url,
+ description=description,
+ color=CONST.COLOR_DEFAULT,
+ footer_text=footer_text,
+ footer_icon_url=CONST.LUMI_LOGO_TRANSPARENT,
+ show_name=show_name,
+ image_url=image_url,
+ thumbnail_url=thumbnail_url,
+ timestamp=timestamp,
+ hide_author=hide_author,
+ hide_author_icon=hide_author_icon,
+ hide_timestamp=hide_timestamp,
+ )
+
+ @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,
+ ) -> discord.Embed:
+ return builder.create_embed(
+ ctx,
+ title=title,
+ author_text=author_text,
+ author_icon_url=author_icon_url or CONST.EXCLAIM_ICON,
+ author_url=author_url,
+ description=description,
+ color=CONST.COLOR_DEFAULT,
+ footer_text=footer_text,
+ footer_icon_url=CONST.LUMI_LOGO_TRANSPARENT,
+ show_name=show_name,
+ image_url=image_url,
+ thumbnail_url=thumbnail_url,
+ timestamp=timestamp,
+ hide_author=hide_author,
+ hide_author_icon=hide_author_icon,
+ hide_timestamp=hide_timestamp,
+ )
+
+ @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,
+ ) -> discord.Embed:
+ return builder.create_embed(
+ ctx,
+ title=title,
+ author_text=author_text,
+ author_icon_url=author_icon_url or CONST.WARNING_ICON,
+ author_url=author_url,
+ description=description,
+ color=CONST.COLOR_WARNING,
+ footer_text=footer_text,
+ footer_icon_url=CONST.LUMI_LOGO_TRANSPARENT,
+ show_name=show_name,
+ image_url=image_url,
+ thumbnail_url=thumbnail_url,
+ timestamp=timestamp,
+ hide_author=hide_author,
+ hide_author_icon=hide_author_icon,
+ hide_timestamp=hide_timestamp,
+ )