mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 18:23:12 +00:00
Cleanup
This commit is contained in:
parent
1ac95af5e6
commit
4cea4eb426
25 changed files with 98 additions and 81 deletions
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022-2024 wl.inator
|
||||
Copyright (c) 2022-2024 wlinator
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
import os
|
||||
|
||||
import discord
|
||||
|
||||
import Client
|
||||
import config.parser
|
||||
import services.config_service
|
||||
import services.help_service
|
||||
import services.logging_service
|
||||
import config.parser
|
||||
|
||||
_logs = services.logging_service.setup_logger()
|
||||
|
||||
|
||||
async def get_prefix(bot, message):
|
||||
try:
|
||||
return services.GuildConfig.GuildConfig.get_prefix(message.guild.id)
|
||||
return services.config_service.GuildConfig.get_prefix(message.guild.id)
|
||||
except AttributeError:
|
||||
return "."
|
||||
|
||||
|
||||
client = Client.LumiBot(
|
||||
owner_id=int(os.environ.get('LUMI_OWNER_ID')),
|
||||
command_prefix=get_prefix,
|
||||
|
|
30
README.md
30
README.md
|
@ -7,41 +7,47 @@
|
|||
**The next part of this README explains how to self-host Lumi, this allows you to host your own version of my code and
|
||||
create a personalized Discord bot.**
|
||||
|
||||
**Note: because the `.slots` and `.blackjack` commands use custom (animated) emoji, these commands will break when you self-host Lumi. Please replace the ID values in `config/JSON/resources.json` with your own set of emotes.**
|
||||
**Note: because the `.slots` and `.blackjack` commands use custom (animated) emoji, these commands will break when you
|
||||
self-host Lumi. Please replace the ID values in `config/JSON/resources.json` with your own set of emotes.**
|
||||
|
||||
### Installation
|
||||
|
||||
#### Docker
|
||||
Lumi comes containerized with essential components such as MariaDB, its core application and Adminer.
|
||||
|
||||
Lumi comes containerized with essential components such as MariaDB, its core application and Adminer.
|
||||
|
||||
To install Lumi, run these commands:
|
||||
|
||||
```commandline
|
||||
```bash
|
||||
git clone https://git.wlinator.org/Luminara/Lumi && cd Lumi
|
||||
```
|
||||
|
||||
Copy `.env.template` to `.env` and fill out the [variables](#environment-variables).
|
||||
Copy `.env.template` to `.env` and fill out the [variables](#environment-variables-env).
|
||||
|
||||
```commandline
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Please note that it's highly recommended to establish a reverse proxy setup for Adminer, ensuring better security and accessibility.
|
||||
Please note that it's highly recommended to establish a reverse proxy setup for Adminer, ensuring better security and
|
||||
accessibility.
|
||||
|
||||
- Adminer should be directed to port 8080.
|
||||
|
||||
#### Alternative
|
||||
You can run Lumi without Docker, however I don't provide support or documentation for this. Here are some requirements to get you started.
|
||||
|
||||
You can run Lumi without Docker, however I don't provide support or documentation for this. Here are some requirements
|
||||
to get you started.
|
||||
|
||||
- MariaDB server on port 3306.
|
||||
- Python 3.11 with the [required pip packages](requirements.txt).
|
||||
- See the environment variables in [docker-compose.yml](docker-compose.yml) and set them manually.
|
||||
|
||||
|
||||
## Environment variables (.env)
|
||||
|
||||
- `TOKEN`: your Discord Bot Token, you can get this [here](https://discord.com/developers/applications).
|
||||
- `DBX_*`: set these up if you want to make database backups to your Dropbox app.
|
||||
- `MARIADB_USER`: the username for your MariaDB database.
|
||||
- `MARIADB_PASSWORD`: the password for your database.
|
||||
- `TOKEN`: your Discord Bot Token, you can get this [here](https://discord.com/developers/applications).
|
||||
- `DBX_*`: set these up if you want to make database backups to your Dropbox app.
|
||||
- `MARIADB_USER`: the username for your MariaDB database.
|
||||
- `MARIADB_PASSWORD`: the password for your database.
|
||||
- `MARIADB_ROOT_PASSWORD`: can be ignored unless you have a specific use for it.
|
||||
- `MARIADB_DATABASE`: the name of your database.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"transparent": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_logo_transparent.png?_=1"
|
||||
},
|
||||
"icons": {
|
||||
"exclaim": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_exclaim.png?_=2",
|
||||
"exclaim": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_exclaim.png?_=3",
|
||||
"question": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_question.png?_=2",
|
||||
"hammer": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_hammer.png?_=1",
|
||||
"cross": "https://git.wlinator.org/Luminara/Art/raw/branch/main/lumi_cross.png?_=1",
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
{
|
||||
"months": [
|
||||
"January", "February", "March", "April",
|
||||
"May", "June", "July", "August",
|
||||
"September", "October", "November", "December"
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December"
|
||||
],
|
||||
"birthday_messages": [
|
||||
"🎂 Happy Birthday, **{0}**! 🎉 Wishing you a day filled with joy and laughter.",
|
||||
|
|
|
@ -24,8 +24,27 @@
|
|||
"stand": "<:stand:1118923298298929154>"
|
||||
},
|
||||
"reward_multiplier": 1.4,
|
||||
"deck_suits": ["♠", "♡", "♢", "♣"],
|
||||
"deck_ranks": ["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
|
||||
"deck_suits": [
|
||||
"♠",
|
||||
"♡",
|
||||
"♢",
|
||||
"♣"
|
||||
],
|
||||
"deck_ranks": [
|
||||
"A",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"J",
|
||||
"Q",
|
||||
"K"
|
||||
]
|
||||
},
|
||||
"slots": {
|
||||
"emotes": {
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
"stats_all_title": "Total Lumi Stats - {0}",
|
||||
"stats_all_footer": "Want to see your own stats? Do '/stats me'.",
|
||||
"stats_games": "Games played: {0}",
|
||||
"stats_games_valuet": "Games played: **{0}**\nGames won: **{1}**\nGames lost: **{2}**",
|
||||
"stats_games_valued": "Games played: **{0}**\nGames won: **{1}**\nGames lost: **{2}**",
|
||||
"stats_games_value": "`{0}` wins & `{1}` losses.",
|
||||
"stats_cashflow": "Cashflow",
|
||||
"stats_cashflow_value": "Total bets/payouts: `${0}` / `${1}`",
|
||||
|
|
|
@ -9,7 +9,6 @@ from discord.ext.commands import Cog
|
|||
from lib.embeds.error import GenericErrors, BdayErrors
|
||||
from lib.exceptions import LumiExceptions
|
||||
|
||||
logs = logging.getLogger('Lumi.Core')
|
||||
_logs = logging.getLogger('Lumi.Core')
|
||||
|
||||
|
||||
|
@ -60,8 +59,8 @@ async def on_command_error(ctx, error):
|
|||
|
||||
|
||||
async def on_error(event: str, *args, **kwargs) -> None:
|
||||
logs.error(f"[EventHandler] on_error INFO: errors.event.{event} | '*args': {args} | '**kwargs': {kwargs}")
|
||||
logs.error(f"[EventHandler] on_error EXCEPTION: {sys.exc_info()}")
|
||||
_logs.error(f"[EventHandler] on_error INFO: errors.event.{event} | '*args': {args} | '**kwargs': {kwargs}")
|
||||
_logs.error(f"[EventHandler] on_error EXCEPTION: {sys.exc_info()}")
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
|
|
|
@ -3,9 +3,8 @@ import logging
|
|||
|
||||
from discord.ext.commands import Cog
|
||||
|
||||
from lib.embeds.greet import Greet
|
||||
from lib.embeds.boost import Boost
|
||||
import lib.embeds.boost
|
||||
from lib.embeds.greet import Greet
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
_logs = logging.getLogger('Lumi.Core')
|
||||
|
|
|
@ -159,11 +159,11 @@ class XpListener(Cog):
|
|||
leveled_up = _xp.process()
|
||||
|
||||
if leveled_up:
|
||||
coros = [
|
||||
coroutines = [
|
||||
asyncio.create_task(_xp.notify()),
|
||||
asyncio.create_task(_xp.reward())
|
||||
]
|
||||
await asyncio.wait(coros)
|
||||
await asyncio.wait(coroutines)
|
||||
|
||||
|
||||
def setup(client):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import discord
|
||||
|
||||
from config.parser import JsonCache
|
||||
import lib.formatter
|
||||
from config.parser import JsonCache
|
||||
|
||||
resources = JsonCache.read_json("art")
|
||||
exclaim_icon = resources["icons"]["exclaim"]
|
||||
|
|
|
@ -114,9 +114,6 @@ class Confirm(View):
|
|||
await interaction.response.edit_message(view=None)
|
||||
self.stop()
|
||||
|
||||
# async def on_timeout(self):
|
||||
# await self.ctx.
|
||||
|
||||
async def interaction_check(self, interaction) -> bool:
|
||||
if interaction.user != self.ctx.author:
|
||||
await interaction.response.send_message("You can't use these buttons, they're someone else's!",
|
||||
|
|
|
@ -3,8 +3,8 @@ import logging
|
|||
import random
|
||||
|
||||
import discord
|
||||
from discord.ext import commands, tasks, bridge
|
||||
from discord.commands import SlashCommandGroup
|
||||
from discord.ext import commands, tasks
|
||||
|
||||
from config.parser import JsonCache
|
||||
from lib import time, checks
|
||||
|
@ -70,7 +70,7 @@ class Birthdays(commands.Cog):
|
|||
await channel.send(embed=embed, content=member.mention)
|
||||
_logs.info(f"[BirthdayHandler] Success! user/guild/channel ID: {member.id}/{guild.id}/{channel.id}")
|
||||
|
||||
except Exception as error:
|
||||
except Exception:
|
||||
_logs.info(f"[BirthdayHandler] Skipped processing user/guild {user_id}/{guild_id}")
|
||||
|
||||
# wait one second to avoid rate limits
|
||||
|
|
|
@ -6,9 +6,9 @@ from discord.ext import commands, bridge
|
|||
|
||||
from config.parser import JsonCache
|
||||
from lib import formatter
|
||||
from lib.embeds.greet import Greet
|
||||
from lib.embeds.boost import Boost
|
||||
from lib.embeds.error import GenericErrors
|
||||
from lib.embeds.greet import Greet
|
||||
from modules.config import config, set_prefix, xp_reward
|
||||
from services.config_service import GuildConfig
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ from config.parser import JsonCache
|
|||
from lib import interaction
|
||||
from lib.embeds.error import EconErrors
|
||||
from lib.embeds.error import GenericErrors
|
||||
from services.stats_service import BlackJackStats
|
||||
from services.currency_service import Currency
|
||||
from services.stats_service import BlackJackStats
|
||||
|
||||
resources = JsonCache.read_json("resources")
|
||||
logs = logging.getLogger('Lumi.Core')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from config.parser import JsonCache
|
||||
from services.stats_service import BlackJackStats, SlotsStats
|
||||
from services.currency_service import Currency
|
||||
from services.stats_service import BlackJackStats, SlotsStats
|
||||
|
||||
strings = JsonCache.read_json("strings")
|
||||
resources = JsonCache.read_json("resources")
|
||||
|
|
|
@ -14,7 +14,7 @@ class Help(commands.Cog):
|
|||
)
|
||||
async def help_command(self, ctx):
|
||||
prefix = lib.formatter.get_prefix(ctx)
|
||||
return await ctx.respond(content=f"Please use Lumi's prefix to get help. Type `{prefix}help`", ephemeral=True)
|
||||
return await ctx.respond(content=f'Please use Lumi\'s prefix to get help. Type `{prefix}help`', ephemeral=True)
|
||||
|
||||
|
||||
def setup(client):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import datetime
|
||||
|
||||
from discord.ext import commands, bridge, tasks
|
||||
from discord.commands import SlashCommandGroup
|
||||
from discord.ext import commands, bridge, tasks
|
||||
|
||||
from lib import checks
|
||||
from lib.embeds.info import MiscInfo
|
||||
|
|
|
@ -15,17 +15,17 @@ mariadb_user = os.environ.get("MARIADB_USER")
|
|||
mariadb_password = os.environ.get("MARIADB_PASSWORD")
|
||||
|
||||
if instance.lower() == "main":
|
||||
dbx = dropbox.Dropbox(
|
||||
_dbx = dropbox.Dropbox(
|
||||
app_key=app_key,
|
||||
app_secret=app_secret,
|
||||
oauth2_refresh_token=oauth2_refresh_token
|
||||
)
|
||||
else:
|
||||
# can be ignored
|
||||
dbx = None
|
||||
_dbx = None
|
||||
|
||||
|
||||
async def create_db_backup(dbx, path="db/rcu.db"):
|
||||
async def create_db_backup():
|
||||
backup_name = datetime.today().strftime('%Y-%m-%d_%H%M')
|
||||
backup_name += f"_lumi.sql"
|
||||
|
||||
|
@ -35,24 +35,24 @@ async def create_db_backup(dbx, path="db/rcu.db"):
|
|||
subprocess.check_output(command, shell=True)
|
||||
|
||||
with open("./db/migrations/100-dump.sql", "rb") as f:
|
||||
dbx.files_upload(f.read(), f"/{backup_name}")
|
||||
_dbx.files_upload(f.read(), f"/{backup_name}")
|
||||
|
||||
|
||||
async def backup_cleanup(dbx):
|
||||
async def backup_cleanup():
|
||||
all_backup_files = []
|
||||
|
||||
for entry in dbx.files_list_folder('').entries:
|
||||
for entry in _dbx.files_list_folder('').entries:
|
||||
all_backup_files.append(entry.name)
|
||||
|
||||
for file in sorted(all_backup_files[:-48]):
|
||||
dbx.files_delete_v2('/' + file)
|
||||
_dbx.files_delete_v2('/' + file)
|
||||
|
||||
|
||||
async def backup(self):
|
||||
if instance.lower() == "main":
|
||||
try:
|
||||
await create_db_backup(dbx)
|
||||
await backup_cleanup(dbx)
|
||||
await create_db_backup()
|
||||
await backup_cleanup()
|
||||
|
||||
logs.info("[BACKUP] database backup success.")
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import psutil
|
|||
|
||||
from config.parser import JsonCache
|
||||
from lib import metadata
|
||||
from services.stats_service import BlackJackStats
|
||||
from services.currency_service import Currency
|
||||
from services.stats_service import BlackJackStats
|
||||
|
||||
_logs = logging.getLogger('Lumi.Core')
|
||||
_art = JsonCache.read_json("art")
|
||||
|
@ -30,7 +30,7 @@ async def cmd(command, ctx, unix_timestamp):
|
|||
icon_url=_art["logo"]["transparent"])
|
||||
embed.set_thumbnail(url=_art["logo"]["opaque"])
|
||||
|
||||
#embed.add_field(name="Author", value=f"{metadata.__author__}", inline=False)
|
||||
# embed.add_field(name="Author", value=f"{metadata.__author__}", inline=False)
|
||||
embed.add_field(name="Uptime", value=f"<t:{unix_timestamp}:R>")
|
||||
embed.add_field(name="Latency", value=f"{round(1000 * command.client.latency)}ms")
|
||||
embed.add_field(name="Memory", value=f"{memory_usage_in_mb:.2f} MB")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from discord.ext import commands
|
||||
from services import xkcd_service
|
||||
|
||||
from lib.embeds.info import MiscInfo
|
||||
from services import xkcd_service
|
||||
|
||||
_xkcd = xkcd_service.Client()
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ import pytz
|
|||
|
||||
|
||||
class LumiFormatter(logging.Formatter):
|
||||
def __init__(self, fmt=None, datefmt=None):
|
||||
super().__init__(fmt, datefmt)
|
||||
def __init__(self, fmt=None, dateformat=None):
|
||||
super().__init__(fmt, dateformat)
|
||||
self.timezone = pytz.timezone('US/Eastern')
|
||||
|
||||
def format(self, record):
|
||||
|
@ -21,10 +21,10 @@ class LumiFormatter(logging.Formatter):
|
|||
record.msg = message
|
||||
return super().format(record)
|
||||
|
||||
def formatTime(self, record, datefmt=None):
|
||||
def formatTime(self, record, dateformat=None):
|
||||
timestamp = self.timezone.localize(datetime.fromtimestamp(record.created))
|
||||
if datefmt:
|
||||
return timestamp.strftime(datefmt)
|
||||
if dateformat:
|
||||
return timestamp.strftime(dateformat)
|
||||
else:
|
||||
return str(timestamp)
|
||||
|
||||
|
@ -36,7 +36,7 @@ def setup_logger():
|
|||
|
||||
debug_log_file = os.path.join(logs_folder, 'debug.log')
|
||||
|
||||
with open(debug_log_file, 'w') as f:
|
||||
with open(debug_log_file, 'w'):
|
||||
pass
|
||||
|
||||
# Initialize the logger
|
||||
|
@ -51,8 +51,7 @@ def setup_logger():
|
|||
# CONSOLE HANDLER
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
console_formatter = LumiFormatter('[%(asctime)s] [%(name)s] %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S')
|
||||
console_formatter = LumiFormatter('[%(asctime)s] [%(name)s] %(message)s')
|
||||
|
||||
console_handler.setFormatter(console_formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
@ -61,8 +60,7 @@ def setup_logger():
|
|||
max_log_size_bytes = 10 * 1024 * 1024 # max. 10 MB
|
||||
debug_file_handler = RotatingFileHandler(debug_log_file, maxBytes=max_log_size_bytes, backupCount=5)
|
||||
debug_file_handler.setLevel(logging.DEBUG)
|
||||
debug_file_formatter = LumiFormatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S')
|
||||
debug_file_formatter = LumiFormatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s')
|
||||
debug_file_handler.setFormatter(debug_file_formatter)
|
||||
logger.addHandler(debug_file_handler)
|
||||
|
||||
|
|
|
@ -112,4 +112,3 @@ class SlotsStats:
|
|||
"games_won_three_diamonds": games_won_three_diamonds,
|
||||
"games_won_jackpot": games_won_jackpot
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ class HttpError(Exception):
|
|||
|
||||
class Comic:
|
||||
"""
|
||||
A class representing an xkcd comic.
|
||||
A class representing a xkcd comic.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
|
@ -47,19 +47,15 @@ class Comic:
|
|||
self.comic_url: str | None = comic_url
|
||||
self.explanation_url: str | None = explanation_url
|
||||
|
||||
def _determine_date(self, xkcd_dict: dict[str, Any]) -> datetime.date | None:
|
||||
@staticmethod
|
||||
def _determine_date(xkcd_dict: dict[str, Any]) -> datetime.date | None:
|
||||
"""
|
||||
Determine the date of the comic.
|
||||
Args:
|
||||
xkcd_dict:
|
||||
|
||||
Parameters
|
||||
----------
|
||||
xkcd_dict : dict[str, Any]
|
||||
The dictionary containing the comic data.
|
||||
Returns:
|
||||
|
||||
Returns
|
||||
-------
|
||||
datetime.date | None
|
||||
The date of the comic.
|
||||
"""
|
||||
try:
|
||||
return datetime.date(
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
users:
|
||||
# "admin" here is username
|
||||
admin:
|
||||
name: "Admin"
|
||||
# Just sha-256 which can be computed with "echo -n password | shasum -a 256"
|
||||
password: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"
|
||||
# use email to generate avatars using Gravatar. It is optional.
|
||||
email: me@email.net
|
Loading…
Reference in a new issue