mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 18:23:12 +00:00
chore: Update pyproject.toml with python-dotenv and pyyaml dependencies
This commit is contained in:
parent
ecd3c5d14e
commit
10a45dd85c
10 changed files with 148 additions and 136 deletions
|
@ -1,15 +0,0 @@
|
|||
TOKEN=
|
||||
INSTANCE=
|
||||
OWNER_ID=784783517845946429
|
||||
|
||||
XP_GAIN_PER_MESSAGE=
|
||||
XP_GAIN_COOLDOWN=
|
||||
|
||||
DBX_OAUTH2_REFRESH_TOKEN=
|
||||
DBX_APP_KEY=
|
||||
DBX_APP_SECRET=
|
||||
|
||||
MARIADB_USER=wlinator
|
||||
MARIADB_PASSWORD=
|
||||
MARIADB_ROOT_PASSWORD=
|
||||
MARIADB_DATABASE=lumidb
|
42
Luminara.py
42
Luminara.py
|
@ -8,6 +8,7 @@ import Client
|
|||
import config.parser
|
||||
import services.config_service
|
||||
import services.help_service
|
||||
from lib.constants import CONST
|
||||
from services.blacklist_service import BlacklistUserService
|
||||
|
||||
# Remove the default logger configuration
|
||||
|
@ -29,22 +30,16 @@ async def get_prefix(bot, message):
|
|||
except AttributeError:
|
||||
return "."
|
||||
|
||||
_token: str | None = os.environ.get('LUMI_TOKEN')
|
||||
_owner_id: str | None = os.environ.get('LUMI_OWNER_ID')
|
||||
|
||||
if not _token:
|
||||
logger.error("LUMI_TOKEN is not set in the environment variables.")
|
||||
exit(1)
|
||||
|
||||
|
||||
client = Client.LumiBot(
|
||||
owner_id=int(_owner_id) if _owner_id else None,
|
||||
owner_ids=CONST.OWNER_IDS,
|
||||
command_prefix=get_prefix,
|
||||
intents=discord.Intents.all(),
|
||||
status=discord.Status.online,
|
||||
help_command=services.help_service.LumiHelp()
|
||||
help_command=services.help_service.LumiHelp(),
|
||||
)
|
||||
|
||||
|
||||
@client.check
|
||||
async def blacklist_check(ctx):
|
||||
if BlacklistUserService.is_user_blacklisted(ctx.author.id):
|
||||
|
@ -61,8 +56,15 @@ def load_modules():
|
|||
if not os.path.isdir(directory_path):
|
||||
continue
|
||||
|
||||
items = [d for d in os.listdir(directory_path) if os.path.isdir(os.path.join(directory_path, d))] \
|
||||
if directory == "modules" else [f[:-3] for f in os.listdir(directory_path) if f.endswith('.py')]
|
||||
items = (
|
||||
[
|
||||
d
|
||||
for d in os.listdir(directory_path)
|
||||
if os.path.isdir(os.path.join(directory_path, d))
|
||||
]
|
||||
if directory == "modules"
|
||||
else [f[:-3] for f in os.listdir(directory_path) if f.endswith(".py")]
|
||||
)
|
||||
|
||||
for item in items:
|
||||
if item in loaded:
|
||||
|
@ -71,13 +73,13 @@ def load_modules():
|
|||
try:
|
||||
client.load_extension(f"{directory}.{item}")
|
||||
loaded.add(item)
|
||||
logger.debug(f'{item.upper()} loaded.')
|
||||
logger.debug(f"{item.upper()} loaded.")
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(f'Failed to load {item.upper()}: {e}')
|
||||
logger.exception(f"Failed to load {item.upper()}: {e}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
"""
|
||||
This code is only ran when Lumi.py is the primary module,
|
||||
so NOT when main is imported from a cog. (sys.modules)
|
||||
|
@ -86,9 +88,17 @@ if __name__ == '__main__':
|
|||
logger.info("LUMI IS BOOTING")
|
||||
|
||||
# cache all JSON
|
||||
[config.parser.JsonCache.read_json(file[:-5]) for file in os.listdir("config/JSON") if file.endswith(".json")]
|
||||
[
|
||||
config.parser.JsonCache.read_json(file[:-5])
|
||||
for file in os.listdir("config/JSON")
|
||||
if file.endswith(".json")
|
||||
]
|
||||
|
||||
# load command and listener cogs
|
||||
load_modules()
|
||||
|
||||
client.run(_token)
|
||||
if not CONST.TOKEN:
|
||||
logger.error("token is not set in creds.yaml")
|
||||
exit(1)
|
||||
|
||||
client.run(CONST.TOKEN)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import json
|
||||
import yaml
|
||||
from loguru import logger
|
||||
|
||||
|
||||
|
@ -9,8 +10,23 @@ class JsonCache:
|
|||
def read_json(path):
|
||||
"""Read and cache the JSON data if not already cached."""
|
||||
if path not in JsonCache._cache:
|
||||
with open(f"config/JSON/{path}.json", 'r') as file:
|
||||
with open(f"config/JSON/{path}.json", "r") as file:
|
||||
JsonCache._cache[path] = json.load(file)
|
||||
logger.debug(f"{path}.json was loaded and cached.")
|
||||
|
||||
return JsonCache._cache[path]
|
||||
|
||||
|
||||
class YamlCache:
|
||||
_cache = {}
|
||||
|
||||
@staticmethod
|
||||
def read_credentialsl():
|
||||
"""Read and cache the creds.yaml data if not already cached."""
|
||||
path = "creds"
|
||||
if path not in YamlCache._cache:
|
||||
with open(f"{path}.yaml", "r") as file:
|
||||
YamlCache._cache[path] = yaml.safe_load(file)
|
||||
logger.debug(f"{path}.yaml was loaded and cached.")
|
||||
|
||||
return YamlCache._cache[path]
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
from lib.constants import CONST
|
||||
from loguru import logger
|
||||
import os
|
||||
import mysql.connector
|
||||
from mysql.connector import pooling
|
||||
|
||||
|
||||
def create_connection_pool(name: str, size: int) -> pooling.MySQLConnectionPool:
|
||||
pool = pooling.MySQLConnectionPool(
|
||||
return pooling.MySQLConnectionPool(
|
||||
pool_name=name,
|
||||
pool_size=size,
|
||||
host="db",
|
||||
port=3306,
|
||||
database=os.environ.get("MARIADB_DATABASE"),
|
||||
user=os.environ.get("MARIADB_USER"),
|
||||
password=os.environ.get("MARIADB_PASSWORD"),
|
||||
database=CONST.MARIADB_DATABASE,
|
||||
user=CONST.MARIADB_USER,
|
||||
password=CONST.MARIADB_PASSWORD,
|
||||
charset="utf8mb4",
|
||||
collation="utf8mb4_unicode_ci",
|
||||
)
|
||||
|
||||
return pool
|
||||
|
||||
|
||||
try:
|
||||
_cnxpool = create_connection_pool("core-pool", 25)
|
||||
|
@ -28,48 +26,23 @@ except mysql.connector.Error as e:
|
|||
|
||||
|
||||
def execute_query(query, values=None):
|
||||
conn = _cnxpool.get_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
if values:
|
||||
cursor.execute(query, values)
|
||||
else:
|
||||
cursor.execute(query)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return cursor
|
||||
with _cnxpool.get_connection() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(query, values)
|
||||
conn.commit()
|
||||
return cursor
|
||||
|
||||
|
||||
def select_query(query, values=None):
|
||||
conn = _cnxpool.get_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
if values:
|
||||
cursor.execute(query, values)
|
||||
output = cursor.fetchall()
|
||||
else:
|
||||
cursor.execute(query)
|
||||
output = cursor.fetchall()
|
||||
|
||||
conn.close()
|
||||
return output
|
||||
with _cnxpool.get_connection() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(query, values)
|
||||
return cursor.fetchall()
|
||||
|
||||
|
||||
def select_query_one(query, values=None):
|
||||
conn = _cnxpool.get_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
if values:
|
||||
cursor.execute(query, values)
|
||||
output = cursor.fetchone()
|
||||
else:
|
||||
cursor.execute(query)
|
||||
output = cursor.fetchone()
|
||||
|
||||
conn.close()
|
||||
|
||||
if output:
|
||||
return output[0]
|
||||
|
||||
return None
|
||||
with _cnxpool.get_connection() as conn:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute(query, values)
|
||||
output = cursor.fetchone()
|
||||
return output[0] if output else None
|
||||
|
|
|
@ -1,28 +1,15 @@
|
|||
services:
|
||||
core:
|
||||
build: .
|
||||
container_name: lumi_core
|
||||
restart: always
|
||||
environment:
|
||||
LUMI_TOKEN: ${TOKEN}
|
||||
LUMI_INSTANCE: ${INSTANCE}
|
||||
LUMI_OWNER_ID: ${OWNER_ID}
|
||||
LUMI_XP_GAIN_PER_MESSAGE: ${XP_GAIN_PER_MESSAGE}
|
||||
LUMI_XP_GAIN_COOLDOWN: ${XP_GAIN_COOLDOWN}
|
||||
LUMI_DBX_OAUTH2_REFRESH_TOKEN: ${DBX_OAUTH2_REFRESH_TOKEN}
|
||||
LUMI_DBX_APP_KEY: ${DBX_APP_KEY}
|
||||
LUMI_DBX_APP_SECRET: ${DBX_APP_SECRET}
|
||||
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
|
||||
MARIADB_USER: ${MARIADB_USER}
|
||||
MARIADB_PASSWORD: ${MARIADB_PASSWORD}
|
||||
MARIADB_DATABASE: ${MARIADB_DATABASE}
|
||||
volumes:
|
||||
- debug_log:/usr/src/app/logs
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
db:
|
||||
image: mariadb
|
||||
container_name: lumi_db
|
||||
restart: always
|
||||
environment:
|
||||
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
|
||||
|
@ -40,10 +27,10 @@ services:
|
|||
|
||||
adminer:
|
||||
image: adminer
|
||||
container_name: lumi_adminer
|
||||
restart: always
|
||||
ports:
|
||||
- 8080:8080
|
||||
|
||||
volumes:
|
||||
database:
|
||||
debug_log:
|
||||
|
|
|
@ -1,33 +1,68 @@
|
|||
import os
|
||||
from config.parser import JsonCache
|
||||
from typing import Optional, Set
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
art = JsonCache.read_json("art")
|
||||
resources = JsonCache.read_json("resources")
|
||||
|
||||
|
||||
class Constants:
|
||||
# bot credentials
|
||||
TOKEN: Optional[str] = os.environ.get("TOKEN", None)
|
||||
INSTANCE: Optional[str] = os.environ.get("INSTANCE", None)
|
||||
|
||||
OWNER_IDS: Optional[Set[int]] = (
|
||||
{
|
||||
int(id.strip())
|
||||
for id in os.environ.get("OWNER_ID", "").split(",")
|
||||
if id.strip()
|
||||
}
|
||||
if os.environ.get("OWNER_ID")
|
||||
else None
|
||||
)
|
||||
|
||||
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", None)
|
||||
DBX_APP_KEY: Optional[str] = os.environ.get("DBX_APP_KEY", None)
|
||||
DBX_APP_SECRET: Optional[str] = os.environ.get("DBX_APP_SECRET", None)
|
||||
|
||||
MARIADB_USER: Optional[str] = os.environ.get("MARIADB_USER", None)
|
||||
MARIADB_PASSWORD: Optional[str] = os.environ.get("MARIADB_PASSWORD", None)
|
||||
MARIADB_ROOT_PASSWORD: Optional[str] = os.environ.get("MARIADB_ROOT_PASSWORD", None)
|
||||
MARIADB_DATABASE: Optional[str] = os.environ.get("MARIADB_DATABASE", None)
|
||||
|
||||
# emotes
|
||||
EMOTES_GUILD_ID = 1038051105642401812
|
||||
|
||||
|
||||
# color scheme
|
||||
COLOR_DEFAULT = int(0xFF8C00)
|
||||
COLOR_WARNING = int(0xFF7600)
|
||||
COLOR_ERROR = int(0xFF4500)
|
||||
|
||||
|
||||
# strings
|
||||
STRINGS = JsonCache.read_json("strings")
|
||||
|
||||
|
||||
# repository
|
||||
REPO_URL = "https://git.wlinator.org/Luminara/Lumi"
|
||||
INVITE_LINK = "https://discord.com/oauth2/authorize?client_id=1038050427272429588&permissions=8&scope=bot"
|
||||
|
||||
|
||||
# KRC
|
||||
KRC_GUILD_ID: int = 719227135151046699
|
||||
KRC_INTRO_CHANNEL_ID: int = 973619250507972618
|
||||
KRC_QUESTION_MAPPING: dict[str, str] = resources["guild_specific"]["question_mapping"]
|
||||
|
||||
KRC_QUESTION_MAPPING: dict[str, str] = resources["guild_specific"][
|
||||
"question_mapping"
|
||||
]
|
||||
|
||||
# logo
|
||||
LUMI_LOGO_TRANSPARENT = art["logo"]["transparent"]
|
||||
LUMI_LOGO_OPAQUE = art["logo"]["opaque"]
|
||||
|
||||
|
||||
# icons art
|
||||
BOOST_ICON = art["icons"]["boost"]
|
||||
CHECK_ICON = art["icons"]["check"]
|
||||
|
@ -39,18 +74,15 @@ class Constants:
|
|||
QUESTION_ICON = art["icons"]["question"]
|
||||
STREAK_ICON = art["icons"]["streak"]
|
||||
WARNING_ICON = art["icons"]["warning"]
|
||||
|
||||
|
||||
# art by JuicyBblue
|
||||
FLOWERS_ART = art["juicybblue"]["flowers"]
|
||||
TEAPOT_ART = art["juicybblue"]["teapot"]
|
||||
MUFFIN_ART = art["juicybblue"]["muffin"]
|
||||
|
||||
|
||||
# birthdays
|
||||
BIRTHDAY_MESSAGES = JsonCache.read_json("birthday")["birthday_messages"]
|
||||
BIRTHDAY_MONTHS = JsonCache.read_json("birthday")["months"]
|
||||
|
||||
# economy
|
||||
|
||||
|
||||
|
||||
|
||||
CONST = Constants()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from lib.constants import CONST
|
||||
from loguru import logger
|
||||
import os
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
|
@ -7,21 +7,17 @@ from typing import List, Optional
|
|||
import dropbox
|
||||
from dropbox.files import FileMetadata
|
||||
|
||||
# Fetch environment variables once and store them in constants
|
||||
OAUTH2_REFRESH_TOKEN: Optional[str] = os.environ.get("LUMI_DBX_OAUTH2_REFRESH_TOKEN")
|
||||
APP_KEY: Optional[str] = os.environ.get("LUMI_DBX_APP_KEY")
|
||||
APP_SECRET: Optional[str] = os.environ.get("LUMI_DBX_APP_SECRET")
|
||||
INSTANCE: Optional[str] = os.environ.get("LUMI_INSTANCE")
|
||||
MARIADB_USER: Optional[str] = os.environ.get("MARIADB_USER")
|
||||
MARIADB_PASSWORD: Optional[str] = os.environ.get("MARIADB_PASSWORD")
|
||||
|
||||
# Initialize Dropbox client if instance is "main"
|
||||
_dbx: Optional[dropbox.Dropbox] = None
|
||||
if INSTANCE and INSTANCE.lower() == "main":
|
||||
if CONST.INSTANCE and CONST.INSTANCE.lower() == "main":
|
||||
_app_key: Optional[str] = CONST.DBX_APP_KEY
|
||||
_dbx_token: Optional[str] = CONST.DBX_TOKEN
|
||||
_app_secret: Optional[str] = CONST.DBX_APP_SECRET
|
||||
|
||||
_dbx = dropbox.Dropbox(
|
||||
app_key=APP_KEY,
|
||||
app_secret=APP_SECRET,
|
||||
oauth2_refresh_token=OAUTH2_REFRESH_TOKEN
|
||||
app_key=_app_key,
|
||||
app_secret=_app_secret,
|
||||
oauth2_refresh_token=_dbx_token,
|
||||
)
|
||||
|
||||
|
||||
|
@ -29,9 +25,9 @@ async def create_db_backup() -> None:
|
|||
if not _dbx:
|
||||
raise ValueError("Dropbox client is not initialized")
|
||||
|
||||
backup_name: str = datetime.today().strftime('%Y-%m-%d_%H%M') + "_lumi.sql"
|
||||
backup_name: str = datetime.today().strftime("%Y-%m-%d_%H%M") + "_lumi.sql"
|
||||
command: str = (
|
||||
f"mariadb-dump --user={MARIADB_USER} --password={MARIADB_PASSWORD} "
|
||||
f"mariadb-dump --user={CONST.MARIADB_USER} --password={CONST.MARIADB_PASSWORD} "
|
||||
f"--host=db --single-transaction --all-databases > ./db/migrations/100-dump.sql"
|
||||
)
|
||||
|
||||
|
@ -45,17 +41,20 @@ async def backup_cleanup() -> None:
|
|||
if not _dbx:
|
||||
raise ValueError("Dropbox client is not initialized")
|
||||
|
||||
result = _dbx.files_list_folder('')
|
||||
result = _dbx.files_list_folder("")
|
||||
|
||||
all_backup_files: List[str] = [
|
||||
entry.name for entry in result.entries if isinstance(entry, FileMetadata) # type: ignore
|
||||
entry.name
|
||||
for entry in result.entries
|
||||
if isinstance(entry, FileMetadata) # type: ignore
|
||||
]
|
||||
|
||||
for file in sorted(all_backup_files)[:-48]:
|
||||
_dbx.files_delete_v2('/' + file)
|
||||
_dbx.files_delete_v2("/" + file)
|
||||
|
||||
|
||||
async def backup() -> None:
|
||||
if INSTANCE and INSTANCE.lower() == "main":
|
||||
if CONST.INSTANCE and CONST.INSTANCE.lower() == "main":
|
||||
logger.debug("Backing up the database.")
|
||||
try:
|
||||
await create_db_backup()
|
||||
|
@ -64,4 +63,4 @@ async def backup() -> None:
|
|||
except Exception as error:
|
||||
logger.error(f"Backup failed: {error}")
|
||||
else:
|
||||
logger.debug("No backup, instance not \"MAIN\".")
|
||||
logger.debug('No backup, instance not "MAIN".')
|
||||
|
|
16
poetry.lock
generated
16
poetry.lock
generated
|
@ -771,6 +771,20 @@ nodeenv = ">=1.6.0"
|
|||
all = ["twine (>=3.4.1)"]
|
||||
dev = ["twine (>=3.4.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "1.0.1"
|
||||
description = "Read key-value pairs from a .env file and set them as environment variables"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
|
||||
{file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
cli = ["click (>=5.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2024.1"
|
||||
|
@ -1085,4 +1099,4 @@ multidict = ">=4.0"
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "bfcd06ad073bbdf00a8b37ce2297f87380dbd58c59283525bad3908a17269475"
|
||||
content-hash = "f99a624c8fbf0661b2dfe3a937f1182c527ed3d565715bb868b1cbac95221405"
|
||||
|
|
|
@ -17,9 +17,9 @@ psutil = "^6.0.0"
|
|||
py-cord = "2.5.0"
|
||||
pyright = "^1.1.371"
|
||||
python = "^3.12"
|
||||
python-dotenv = "^1.0.1"
|
||||
pytz = "^2024.1"
|
||||
ruff = "^0.5.2"
|
||||
pyyaml = "^6.0.1"
|
||||
|
||||
[build-system]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import os
|
||||
from lib.constants import CONST
|
||||
import time
|
||||
from typing import Callable, Dict, List, Optional, Tuple
|
||||
|
||||
|
@ -7,10 +7,6 @@ from discord.ext import commands
|
|||
from db import database
|
||||
|
||||
|
||||
xp_gain_per_message: int = int(os.environ.get("LUMI_XP_GAIN_PER_MESSAGE", 1))
|
||||
xp_gain_cooldown: int = int(os.environ.get("LUMI_XP_GAIN_COOLDOWN", 8))
|
||||
|
||||
|
||||
class XpService:
|
||||
"""
|
||||
Manages XP for a user, including storing, retrieving, and updating XP in the database.
|
||||
|
@ -29,8 +25,8 @@ class XpService:
|
|||
self.xp: int = 0
|
||||
self.level: int = 0
|
||||
self.cooldown_time: Optional[float] = None
|
||||
self.xp_gain: int = xp_gain_per_message
|
||||
self.new_cooldown: int = xp_gain_cooldown
|
||||
self.xp_gain: int = CONST.XP_GAIN_PER_MESSAGE
|
||||
self.new_cooldown: int = CONST.XP_GAIN_COOLDOWN
|
||||
|
||||
self.fetch_or_create_xp()
|
||||
|
||||
|
|
Loading…
Reference in a new issue