1
Fork 0
mirror of https://github.com/wlinator/luminara.git synced 2024-10-02 20:23:12 +00:00

docker & mariadb init

This commit is contained in:
wlinator 2023-10-23 14:49:46 +02:00
parent 0468abcf00
commit e38dd8abdb
18 changed files with 226 additions and 54 deletions

13
.env.template Normal file
View file

@ -0,0 +1,13 @@
TOKEN=
INSTANCE=BETA
OWNER_ID=784783517845946429
XP_GAIN=1,1,1,2
COOLDOWN=7,8,9,10
CASH_BALANCE_NAME=$
SPECIAL_BALANCE_NAME=majikoins
DBX_OAUTH2_REFRESH_TOKEN=
DBX_APP_KEY=
DBX_APP_SECRET=
MARIADB_USER=
MARIADB_PASSWORD=
MARIADB_ROOT_PASSWORD=

5
.gitignore vendored
View file

@ -4,4 +4,7 @@ __pycache__/
*.db *.db
.env .env
*.log *.log
db/data/
db/init/2-data.sql

19
Dockerfile Normal file
View file

@ -0,0 +1,19 @@
FROM python:3.11
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /usr/src/app
RUN apt-get update && \
apt-get install -y locales && \
sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
dpkg-reconfigure locales
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
CMD [ "python", "./main.py" ]

4
README.md Normal file
View file

@ -0,0 +1,4 @@
This branch uses Docker and MariaDB to run Racu. It has the exact same functionality within Discord.
There is an ".env.template" file, please copy it to `.env` and fill out the details if you want to host Racu yourself.
Beware that this branch is much more complicated than Racu when its ran locally with sqlite3, however it is more suitable if you plan to host Racu on a major scale with thousands or millions of Discord servers.

View file

@ -13,7 +13,7 @@ class Birthday:
query = """ query = """
INSERT OR REPLACE INTO birthdays INSERT OR REPLACE INTO birthdays
(user_id, birthday) (user_id, birthday)
VALUES (?, ?) VALUES (%s, %s)
""" """
database.execute_query(query, (self.user_id, birthday)) database.execute_query(query, (self.user_id, birthday))
@ -23,7 +23,7 @@ class Birthday:
query = """ query = """
SELECT user_id SELECT user_id
FROM birthdays FROM birthdays
WHERE strftime('%m-%d', birthday) = ? WHERE strftime('%m-%d', birthday) = %s
""" """
tz = pytz.timezone('US/Eastern') tz = pytz.timezone('US/Eastern')

View file

@ -15,7 +15,7 @@ class BlackJackStats:
def push(self): def push(self):
query = """ query = """
INSERT INTO stats_bj (user_id, is_won, bet, payout, hand_player, hand_dealer) INSERT INTO stats_bj (user_id, is_won, bet, payout, hand_player, hand_dealer)
VALUES (?, ?, ?, ?, ?, ?) VALUES (%s, %s, %s, %s, %s, %s)
""" """
values = (self.user_id, self.is_won, self.bet, self.payout, self.hand_player, self.hand_dealer) values = (self.user_id, self.is_won, self.bet, self.payout, self.hand_player, self.hand_dealer)
@ -32,7 +32,7 @@ class BlackJackStats:
SUM(CASE WHEN is_won = 1 THEN 1 ELSE 0 END) AS winning, SUM(CASE WHEN is_won = 1 THEN 1 ELSE 0 END) AS winning,
SUM(CASE WHEN is_won = 0 THEN 1 ELSE 0 END) AS losing SUM(CASE WHEN is_won = 0 THEN 1 ELSE 0 END) AS losing
FROM stats_bj FROM stats_bj
WHERE user_id = ?; WHERE user_id = %s;
""" """
(amount_of_games, total_bet, (amount_of_games, total_bet,
total_payout, winning_amount, losing_amount) = database.select_query(query, (user_id,))[0] total_payout, winning_amount, losing_amount) = database.select_query(query, (user_id,))[0]

View file

@ -29,8 +29,8 @@ class Currency:
def push(self): def push(self):
query = """ query = """
UPDATE currency UPDATE currency
SET cash_balance = ?, special_balance = ? SET cash_balance = %s, special_balance = %s
WHERE user_id = ? WHERE user_id = %s
""" """
database.execute_query(query, (round(self.cash), round(self.special), self.user_id)) database.execute_query(query, (round(self.cash), round(self.special), self.user_id))
@ -40,7 +40,7 @@ class Currency:
query = """ query = """
SELECT cash_balance, special_balance SELECT cash_balance, special_balance
FROM currency FROM currency
WHERE user_id = ? WHERE user_id = %s
""" """
try: try:
@ -54,7 +54,7 @@ class Currency:
if cash_balance is None or special_balance is None: if cash_balance is None or special_balance is None:
query = """ query = """
INSERT INTO currency (user_id, cash_balance, special_balance) INSERT INTO currency (user_id, cash_balance, special_balance)
VALUES (?, 50, 3) VALUES (%s, 50, 3)
""" """
database.execute_query(query, (user_id,)) database.execute_query(query, (user_id,))
return 50, 3 return 50, 3

View file

@ -34,7 +34,7 @@ class Dailies:
query = """ query = """
INSERT INTO dailies (user_id, amount, claimed_at, streak) INSERT INTO dailies (user_id, amount, claimed_at, streak)
VALUES (?, ?, ?, ?) VALUES (%s, %s, %s, %s)
""" """
values = (self.user_id, self.amount, self.claimed_at, self.streak) values = (self.user_id, self.amount, self.claimed_at, self.streak)
database.execute_query(query, values) database.execute_query(query, values)
@ -80,7 +80,7 @@ class Dailies:
WHERE id = ( WHERE id = (
SELECT MAX(id) SELECT MAX(id)
FROM dailies FROM dailies
WHERE user_id = ? WHERE user_id = %s
) )
""" """

View file

@ -21,7 +21,7 @@ class Inventory:
query = """ query = """
INSERT OR REPLACE INTO inventory (user_id, item_id, quantity) INSERT OR REPLACE INTO inventory (user_id, item_id, quantity)
VALUES (?, ?, COALESCE((SELECT quantity FROM inventory WHERE user_id = ? AND item_id = ?), 0) + ?) VALUES (%s, %s, COALESCE((SELECT quantity FROM inventory WHERE user_id = %s AND item_id = %s), 0) + %s)
""" """
database.execute_query(query, (self.user_id, item.id, self.user_id, item.id, abs(quantity))) database.execute_query(query, (self.user_id, item.id, self.user_id, item.id, abs(quantity)))
@ -29,13 +29,13 @@ class Inventory:
def take_item(self, item: Item.Item, quantity=1): def take_item(self, item: Item.Item, quantity=1):
query = """ query = """
INSERT OR REPLACE INTO inventory (user_id, item_id, quantity) INSERT OR REPLACE INTO inventory (user_id, item_id, quantity)
VALUES (?, ?, COALESCE((SELECT quantity FROM inventory WHERE user_id = ? AND item_id = ?) - ?, 0)) VALUES (%s, %s, COALESCE((SELECT quantity FROM inventory WHERE user_id = %s AND item_id = %s) - %s, 0))
""" """
database.execute_query(query, (self.user_id, item.id, self.user_id, item.id, abs(quantity))) database.execute_query(query, (self.user_id, item.id, self.user_id, item.id, abs(quantity)))
def get_inventory(self): def get_inventory(self):
query = "SELECT item_id, quantity FROM inventory WHERE user_id = ? AND quantity > 0" query = "SELECT item_id, quantity FROM inventory WHERE user_id = %s AND quantity > 0"
results = database.select_query(query, (self.user_id,)) results = database.select_query(query, (self.user_id,))
items_dict = {} items_dict = {}
@ -47,7 +47,7 @@ class Inventory:
return items_dict return items_dict
def get_item_quantity(self, item: Item.Item): def get_item_quantity(self, item: Item.Item):
query = "SELECT COALESCE(quantity, 0) FROM inventory WHERE user_id = ? AND item_id = ?" query = "SELECT COALESCE(quantity, 0) FROM inventory WHERE user_id = %s AND item_id = %s"
result = database.select_query_one(query, (self.user_id, item.id)) result = database.select_query_one(query, (self.user_id, item.id))
return result return result
@ -57,7 +57,7 @@ class Inventory:
FROM inventory FROM inventory
JOIN ShopItem ON inventory.item_id = ShopItem.item_id JOIN ShopItem ON inventory.item_id = ShopItem.item_id
JOIN item ON inventory.item_id = item.id JOIN item ON inventory.item_id = item.id
WHERE inventory.user_id = ? AND inventory.quantity > 0 AND ShopItem.worth > 0 WHERE inventory.user_id = %s AND inventory.quantity > 0 AND ShopItem.worth > 0
""" """
try: try:

View file

@ -25,7 +25,7 @@ class Item:
query = """ query = """
SELECT name, display_name, description, image_url, emote_id, quote, type SELECT name, display_name, description, image_url, emote_id, quote, type
FROM item FROM item
WHERE id = ? WHERE id = %s
""" """
data = database.select_query(query, (self.id,))[0] data = database.select_query(query, (self.id,))[0]
@ -33,7 +33,7 @@ class Item:
def get_quantity(self, author_id): def get_quantity(self, author_id):
query = """ query = """
SELECT COALESCE((SELECT quantity FROM inventory WHERE user_id = ? AND item_id = ?), 0) AS quantity SELECT COALESCE((SELECT quantity FROM inventory WHERE user_id = %s AND item_id = %s), 0) AS quantity
""" """
quantity = database.select_query_one(query, (author_id, self.id)) quantity = database.select_query_one(query, (author_id, self.id))
@ -44,7 +44,7 @@ class Item:
query = """ query = """
SELECT worth SELECT worth
FROM ShopItem FROM ShopItem
WHERE item_id = ? WHERE item_id = %s
""" """
return database.select_query_one(query, (self.id,)) return database.select_query_one(query, (self.id,))
@ -66,7 +66,7 @@ class Item:
query = """ query = """
INSERT OR REPLACE INTO item INSERT OR REPLACE INTO item
(id, name, display_name, description, image_url, emote_id, quote, type) (id, name, display_name, description, image_url, emote_id, quote, type)
VALUES (?, ?, ?, ?, ?, ?, ?, ?) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
""" """
database.execute_query(query, database.execute_query(query,
(index, name, display_name, description, image_url, emote_id, quote, item_type)) (index, name, display_name, description, image_url, emote_id, quote, item_type))
@ -92,12 +92,12 @@ class Item:
@staticmethod @staticmethod
def get_item_by_display_name(display_name): def get_item_by_display_name(display_name):
query = "SELECT id FROM item WHERE display_name = ?" query = "SELECT id FROM item WHERE display_name = %s"
item_id = database.select_query_one(query, (display_name,)) item_id = database.select_query_one(query, (display_name,))
return Item(item_id) return Item(item_id)
@staticmethod @staticmethod
def get_item_by_name(name): def get_item_by_name(name):
query = "SELECT id FROM item WHERE name = ?" query = "SELECT id FROM item WHERE name = %s"
item_id = database.select_query_one(query, (name,)) item_id = database.select_query_one(query, (name,))
return Item(item_id) return Item(item_id)

View file

@ -18,22 +18,22 @@ class ShopItem:
""" """
def set_price(self, price): def set_price(self, price):
query = "UPDATE ShopItem SET price = ? WHERE item_id = ?" query = "UPDATE ShopItem SET price = %s WHERE item_id = %s"
database.execute_query(query, (price, self.item.id)) database.execute_query(query, (price, self.item.id))
self.price = price self.price = price
def set_price_special(self, price_special): def set_price_special(self, price_special):
query = "UPDATE ShopItem SET price_special = ? WHERE item_id = ?" query = "UPDATE ShopItem SET price_special = %s WHERE item_id = %s"
database.execute_query(query, (price_special, self.item.id)) database.execute_query(query, (price_special, self.item.id))
self.price_special = price_special self.price_special = price_special
def set_worth(self, worth): def set_worth(self, worth):
query = "UPDATE ShopItem SET worth = ? WHERE item_id = ?" query = "UPDATE ShopItem SET worth = %s WHERE item_id = %s"
database.execute_query(query, (worth, self.item.id)) database.execute_query(query, (worth, self.item.id))
self.worth = worth self.worth = worth
def set_description(self, description): def set_description(self, description):
query = "UPDATE ShopItem SET description = ? WHERE item_id = ?" query = "UPDATE ShopItem SET description = %s WHERE item_id = %s"
database.execute_query(query, (description, self.item.id)) database.execute_query(query, (description, self.item.id))
self.description = description self.description = description
@ -41,7 +41,7 @@ class ShopItem:
query = """ query = """
SELECT price, price_special, worth, description SELECT price, price_special, worth, description
FROM ShopItem FROM ShopItem
WHERE item_id = ? WHERE item_id = %s
""" """
try: try:
@ -49,7 +49,7 @@ class ShopItem:
except (IndexError, TypeError): except (IndexError, TypeError):
query = """ query = """
INSERT INTO ShopItem (item_id, price, price_special, worth, description) INSERT INTO ShopItem (item_id, price, price_special, worth, description)
VALUES (?, 0, 0, 0, "placeholder_descr") VALUES (%s, 0, 0, 0, "placeholder_descr")
""" """
database.execute_query(query, (self.item.id,)) database.execute_query(query, (self.item.id,))
(price, price_special, worth, description) = 0, 0, 0, "placeholder_descr" (price, price_special, worth, description) = 0, 0, 0, "placeholder_descr"

View file

@ -15,7 +15,7 @@ class SlotsStats:
def push(self): def push(self):
query = """ query = """
INSERT INTO stats_slots (user_id, is_won, bet, payout, spin_type, icons) INSERT INTO stats_slots (user_id, is_won, bet, payout, spin_type, icons)
VALUES (?, ?, ?, ?, ?, ?) VALUES (%s, %s, %s, %s, %s, %s)
""" """
values = (self.user_id, self.is_won, self.bet, self.payout, self.spin_type, self.icons) values = (self.user_id, self.is_won, self.bet, self.payout, self.spin_type, self.icons)
@ -34,7 +34,7 @@ class SlotsStats:
SUM(CASE WHEN spin_type = 'three_diamonds' AND is_won = 1 THEN 1 ELSE 0 END) AS games_won_three_diamonds, SUM(CASE WHEN spin_type = 'three_diamonds' AND is_won = 1 THEN 1 ELSE 0 END) AS games_won_three_diamonds,
SUM(CASE WHEN spin_type = 'jackpot' AND is_won = 1 THEN 1 ELSE 0 END) AS games_won_jackpot SUM(CASE WHEN spin_type = 'jackpot' AND is_won = 1 THEN 1 ELSE 0 END) AS games_won_jackpot
FROM stats_slots FROM stats_slots
WHERE user_id = ? WHERE user_id = %s
""" """
(amount_of_games, total_bet, (amount_of_games, total_bet,

View file

@ -24,13 +24,13 @@ class Xp:
def push(self): def push(self):
query = """ query = """
UPDATE xp UPDATE xp
SET user_xp = ?, user_level = ?, cooldown = ? SET user_xp = %s, user_level = %s, cooldown = %s
WHERE user_id = ? WHERE user_id = %s
""" """
database.execute_query(query, (self.xp, self.level, self.ctime, self.user_id)) database.execute_query(query, (self.xp, self.level, self.ctime, self.user_id))
def fetch_or_create_xp(self): def fetch_or_create_xp(self):
query = "SELECT user_xp, user_level, cooldown FROM xp WHERE user_id = ?" query = "SELECT user_xp, user_level, cooldown FROM xp WHERE user_id = %s"
try: try:
(user_xp, user_level, cooldown) = database.select_query(query, (self.user_id,))[0] (user_xp, user_level, cooldown) = database.select_query(query, (self.user_id,))[0]
@ -40,7 +40,7 @@ class Xp:
if any(var is None for var in [user_xp, user_level, cooldown]): if any(var is None for var in [user_xp, user_level, cooldown]):
query = """ query = """
INSERT INTO xp (user_id, user_xp, user_level, cooldown) INSERT INTO xp (user_id, user_xp, user_level, cooldown)
VALUES (?, 0, 0, ?) VALUES (%s, 0, 0, %s)
""" """
database.execute_query(query, (self.user_id, time.time())) database.execute_query(query, (self.user_id, time.time()))
(user_xp, user_level, cooldown) = (0, 0, time.time()) (user_xp, user_level, cooldown) = (0, 0, time.time())

View file

@ -1,22 +1,25 @@
import logging import logging
import sqlite3 import mysql.connector
from sqlite3 import Error from mysql.connector import Error
from dotenv import load_dotenv
import os
racu_logs = logging.getLogger('Racu.Core') racu_logs = logging.getLogger('Racu.Core')
load_dotenv('.env')
def create_connection(): cnxpool = mysql.connector.pooling.MySQLConnectionPool(
try: pool_name='core-pool',
conn = sqlite3.connect("db/rcu.db") pool_size=25,
except Error as e: host='db',
racu_logs.error("'create_connection()' Error occurred: {}".format(e)) user=os.getenv("MARIADB_USER"),
return password=os.getenv("MARIADB_PASSWORD"),
database='racudb'
return conn )
def execute_query(query, values=None): def execute_query(query, values=None):
conn = create_connection() conn = cnxpool.get_connection()
cursor = conn.cursor() cursor = conn.cursor()
if values: if values:
@ -25,32 +28,42 @@ def execute_query(query, values=None):
cursor.execute(query) cursor.execute(query)
conn.commit() conn.commit()
conn.close()
racu_logs.debug(f"database.execute_query: 'query': {query}, 'values': {values}") racu_logs.debug(f"database.execute_query: 'query': {query}, 'values': {values}")
return cursor return cursor
def select_query(query, values=None): def select_query(query, values=None):
conn = create_connection() conn = cnxpool.get_connection()
cursor = conn.cursor() cursor = conn.cursor()
racu_logs.debug(f"database.select_query: 'query': {query}, 'values': {values}") racu_logs.debug(f"database.select_query: 'query': {query}, 'values': {values}")
if values: if values:
return cursor.execute(query, values).fetchall() cursor.execute(query, values)
output = cursor.fetchall()
else: else:
return cursor.execute(query).fetchall() cursor.execute(query)
output = cursor.fetchall()
conn.close()
return output
def select_query_one(query, values=None): def select_query_one(query, values=None):
conn = create_connection() conn = cnxpool.get_connection()
cursor = conn.cursor() cursor = conn.cursor()
racu_logs.debug(f"database.select_query_one: 'query': {query}, 'values': {values}") racu_logs.debug(f"database.select_query_one: 'query': {query}, 'values': {values}")
if values: if values:
output = cursor.execute(query, values).fetchone() cursor.execute(query, values)
output = cursor.fetchone()
else: else:
output = cursor.execute(query).fetchone() cursor.execute(query)
output = cursor.fetchone()
conn.close()
if output: if output:
return output[0] return output[0]

82
db/init/1-tables.sql Normal file
View file

@ -0,0 +1,82 @@
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE xp (
user_id BIGINT PRIMARY KEY NOT NULL,
user_xp INT NOT NULL,
user_level INT NOT NULL,
cooldown FLOAT
);
CREATE TABLE currency (
user_id BIGINT PRIMARY KEY NOT NULL,
cash_balance BIGINT NOT NULL,
special_balance BIGINT
);
CREATE TABLE stats_bj (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT,
is_won BOOLEAN,
bet BIGINT,
payout BIGINT,
hand_player TEXT,
hand_dealer TEXT
);
CREATE TABLE stats_slots (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT,
is_won BOOLEAN,
bet BIGINT,
payout BIGINT,
spin_type TEXT,
icons TEXT
);
CREATE TABLE stats_duel (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT,
is_won BOOLEAN,
bet BIGINT
);
CREATE TABLE dailies (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT,
amount BIGINT,
claimed_at TINYTEXT,
streak INT
);
CREATE TABLE item (
id INT PRIMARY KEY AUTO_INCREMENT,
name TEXT,
display_name TEXT,
description TEXT,
image_url TEXT,
emote_id BIGINT,
quote TEXT,
type TEXT
);
CREATE TABLE inventory (
user_id BIGINT,
item_id INT,
quantity INT,
PRIMARY KEY (user_id, item_id),
FOREIGN KEY (item_id) REFERENCES item (id)
);
CREATE TABLE ShopItem (
item_id INT PRIMARY KEY,
price BIGINT,
price_special BIGINT,
worth BIGINT,
description TEXT
);
CREATE TABLE birthdays (
user_id BIGINT NOT NULL PRIMARY KEY,
birthday DATETIME DEFAULT NULL
);

34
docker-compose.yml Normal file
View file

@ -0,0 +1,34 @@
version: '3'
services:
core:
build: .
restart: always
depends_on:
db:
condition: service_healthy
db:
image: mariadb
restart: always
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
MARIADB_USER: ${MARIADB_USER}
MARIADB_PASSWORD: ${MARIADB_PASSWORD}
MARIADB_DATABASE: racudb
volumes:
- ./db/init:/docker-entrypoint-initdb.d/
- ./db/data:/var/lib/mysql
ports:
- 3306:3306
healthcheck:
test: [ "CMD", "mariadb", "-h", "localhost", "-u", "${MARIADB_USER}", "-p${MARIADB_PASSWORD}", "-e", "SELECT 1" ]
interval: 10s
timeout: 10s
retries: 5
adminer:
image: adminer
restart: always
ports:
- 8080:8080

View file

@ -9,6 +9,9 @@ SPECIAL_BALANCE_NAME=
DBX_OAUTH2_REFRESH_TOKEN= DBX_OAUTH2_REFRESH_TOKEN=
DBX_APP_KEY= DBX_APP_KEY=
DBX_APP_SECRET= DBX_APP_SECRET=
MARIADB_USER=
MARIADB_PASSWORD=
MARIADB_ROOT_PASSWORD=
""" """
import logging import logging
@ -280,8 +283,8 @@ if __name__ == '__main__':
load_dotenv('.env') load_dotenv('.env')
# load db # load db
db.tables.sync_database() # db.tables.sync_database()
Item.insert_items() # Item.insert_items()
load_cogs() load_cogs()
sbbot.run(os.getenv('TOKEN')) sbbot.run(os.getenv('TOKEN'))

View file

@ -2,4 +2,5 @@ py-cord==2.4.1
python-dotenv==1.0.0 python-dotenv==1.0.0
setuptools==67.8.0 setuptools==67.8.0
pytz==2023.3 pytz==2023.3
dropbox==11.36.2 dropbox==11.36.2
mysql-connector-python==8.1.0