modified: bot.py
This commit is contained in:
157
bot.py
157
bot.py
@@ -92,67 +92,79 @@ client = commands.Bot(command_prefix='-', intents=intents, owner_id = OWNER_ID)
|
|||||||
askmultus_queue = asyncio.Queue()
|
askmultus_queue = asyncio.Queue()
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
# Verbindung zur MySQL-Datenbank herstellen
|
# Verbindung zur MySQL-Datenbank herstellen (OLD - now using connection pool)
|
||||||
db_connection = mysql.connector.connect(
|
# db_connection = mysql.connector.connect(
|
||||||
host=DB_HOST,
|
# host=DB_HOST,
|
||||||
port=DB_PORT,
|
# port=DB_PORT,
|
||||||
user=DB_USER,
|
# user=DB_USER,
|
||||||
password=DB_PASSWORD,
|
# password=DB_PASSWORD,
|
||||||
database=DB_DATABASE
|
# database=DB_DATABASE
|
||||||
)
|
# )
|
||||||
|
|
||||||
# Cursor erstellen
|
# Cursor erstellen (OLD - now using connection pool)
|
||||||
db_cursor = db_connection.cursor()
|
# db_cursor = db_connection.cursor()
|
||||||
|
|
||||||
def close_database_connection(connection):
|
def close_database_connection(connection):
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
def insert_user_data(user_id, guild_id, permission, points, ban, askmultus, filter_value, chat_history, xp=0, level=1, nickname="", profile_picture="", join_date=None, leave_date=None):
|
def insert_user_data(user_id, guild_id, permission, points, ban, askmultus, filter_value, chat_history, xp=0, level=1, nickname="", profile_picture="", join_date=None, leave_date=None):
|
||||||
insert_query = """
|
"""Fügt neue Benutzerdaten in die Datenbank ein mit Connection Pool"""
|
||||||
INSERT INTO user_data (user_id, guild_id, permission, points, ban, askmultus, filter_value, rank, chat_history, xp, level, nickname, profile_picture, join_date, leave_date)
|
connection = None
|
||||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
cursor = None
|
||||||
"""
|
|
||||||
serialized_chat_history = json.dumps(chat_history)
|
|
||||||
data = (user_id, guild_id, permission, points, ban, askmultus, filter_value, 0, serialized_chat_history, xp, level, nickname, profile_picture, join_date, leave_date)
|
|
||||||
|
|
||||||
def execute_insert():
|
|
||||||
cursor = get_database_cursor()
|
|
||||||
cursor.execute(insert_query, data)
|
|
||||||
db_connection.commit()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
retry_query(execute_insert)
|
connection = connect_to_database()
|
||||||
print("User data inserted successfully.")
|
cursor = connection.cursor()
|
||||||
|
insert_query = """
|
||||||
|
INSERT INTO user_data (user_id, guild_id, permission, points, ban, askmultus, filter_value, rank, chat_history, xp, level, nickname, profile_picture, join_date, leave_date)
|
||||||
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||||
|
"""
|
||||||
|
serialized_chat_history = json.dumps(chat_history)
|
||||||
|
data = (user_id, guild_id, permission, points, ban, askmultus, filter_value, 0, serialized_chat_history, xp, level, nickname, profile_picture, join_date, leave_date)
|
||||||
|
|
||||||
|
cursor.execute(insert_query, data)
|
||||||
|
connection.commit()
|
||||||
|
logger.info("User data inserted successfully.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error inserting user data after retries: {e}")
|
logger.error(f"Error inserting user data: {e}")
|
||||||
|
if connection:
|
||||||
|
connection.rollback()
|
||||||
|
raise e
|
||||||
|
finally:
|
||||||
|
if cursor:
|
||||||
|
cursor.close()
|
||||||
|
if connection:
|
||||||
|
close_database_connection(connection)
|
||||||
|
|
||||||
|
|
||||||
def update_user_data(user_id, guild_id, field, value):
|
def update_user_data(user_id, guild_id, field, value):
|
||||||
global db_connection, db_cursor # global-Deklaration muss vor dem Zugriff erfolgen
|
"""Aktualisiert Benutzerdaten in der Datenbank mit Connection Pool"""
|
||||||
|
connection = None
|
||||||
|
cursor = None
|
||||||
try:
|
try:
|
||||||
|
connection = connect_to_database()
|
||||||
|
cursor = connection.cursor()
|
||||||
update_query = f"UPDATE user_data SET {field} = %s WHERE user_id = %s AND guild_id = %s"
|
update_query = f"UPDATE user_data SET {field} = %s WHERE user_id = %s AND guild_id = %s"
|
||||||
|
|
||||||
# Überprüfen, ob das Feld 'chat_history' aktualisiert wird
|
# Überprüfen, ob das Feld 'chat_history' aktualisiert wird
|
||||||
if field == 'chat_history':
|
if field == 'chat_history':
|
||||||
serialized_chat_history = json.dumps(value)
|
serialized_chat_history = json.dumps(value)
|
||||||
db_cursor.execute(update_query, (serialized_chat_history, user_id, guild_id))
|
cursor.execute(update_query, (serialized_chat_history, user_id, guild_id))
|
||||||
else:
|
else:
|
||||||
db_cursor.execute(update_query, (value, user_id, guild_id))
|
cursor.execute(update_query, (value, user_id, guild_id))
|
||||||
|
|
||||||
db_connection.commit()
|
connection.commit()
|
||||||
|
logger.debug(f"Successfully updated {field} for user {user_id} in guild {guild_id}")
|
||||||
|
|
||||||
except mysql.connector.Error as err:
|
except mysql.connector.Error as err:
|
||||||
logger.error(f"Database error: {err}")
|
logger.error(f"Database error: {err}")
|
||||||
if db_connection.is_connected():
|
if connection:
|
||||||
db_cursor.close()
|
connection.rollback()
|
||||||
db_connection.close()
|
raise err
|
||||||
|
finally:
|
||||||
# Verbindung neu aufbauen
|
if cursor:
|
||||||
db_connection = connect_to_database()
|
cursor.close()
|
||||||
db_cursor = db_connection.cursor()
|
if connection:
|
||||||
|
close_database_connection(connection)
|
||||||
# Wiederhole die Abfrage nach dem erneuten Verbinden
|
|
||||||
update_user_data(user_id, guild_id, field, value)
|
|
||||||
|
|
||||||
|
|
||||||
def connect_to_database():
|
def connect_to_database():
|
||||||
@@ -175,10 +187,7 @@ def retry_query(func, *args, retries=3, delay=5):
|
|||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
raise RuntimeError("Max retries exceeded")
|
raise RuntimeError("Max retries exceeded")
|
||||||
|
|
||||||
def get_database_cursor():
|
# Removed get_database_cursor() - now using connection pool directly
|
||||||
if not db_connection.is_connected():
|
|
||||||
db_connection.reconnect(attempts=3, delay=5)
|
|
||||||
return db_connection.cursor()
|
|
||||||
|
|
||||||
pool = mysql.connector.pooling.MySQLConnectionPool(
|
pool = mysql.connector.pooling.MySQLConnectionPool(
|
||||||
pool_name="mypool",
|
pool_name="mypool",
|
||||||
@@ -960,32 +969,44 @@ async def add_xp_to_user(user_id, guild_id, xp_gained, member=None):
|
|||||||
# Aktualisiere Nickname
|
# Aktualisiere Nickname
|
||||||
new_nickname = member.display_name
|
new_nickname = member.display_name
|
||||||
if user_data.get("nickname") != new_nickname:
|
if user_data.get("nickname") != new_nickname:
|
||||||
update_user_data(user_id, guild_id, "nickname", new_nickname)
|
try:
|
||||||
user_data["nickname"] = new_nickname
|
update_user_data(user_id, guild_id, "nickname", new_nickname)
|
||||||
|
user_data["nickname"] = new_nickname
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to update nickname for user {user_id}: {e}")
|
||||||
|
|
||||||
# Aktualisiere Profilbild - mit lokalem Download und Hash-Vergleich
|
# Aktualisiere Profilbild - mit lokalem Download und Hash-Vergleich
|
||||||
if member.display_avatar:
|
if member.display_avatar:
|
||||||
discord_avatar_url = str(member.display_avatar.url)
|
try:
|
||||||
# Download und speichere das Profilbild lokal
|
discord_avatar_url = str(member.display_avatar.url)
|
||||||
local_profile_path = await download_and_save_profile_image(user_id, discord_avatar_url)
|
# Download und speichere das Profilbild lokal
|
||||||
|
local_profile_path = await download_and_save_profile_image(user_id, discord_avatar_url)
|
||||||
# Speichere den lokalen Pfad in der Datenbank statt der Discord URL
|
|
||||||
if user_data.get("profile_picture") != local_profile_path:
|
# Speichere den lokalen Pfad in der Datenbank statt der Discord URL
|
||||||
update_user_data(user_id, guild_id, "profile_picture", local_profile_path)
|
if user_data.get("profile_picture") != local_profile_path:
|
||||||
user_data["profile_picture"] = local_profile_path
|
update_user_data(user_id, guild_id, "profile_picture", local_profile_path)
|
||||||
|
user_data["profile_picture"] = local_profile_path
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to update profile picture for user {user_id}: {e}")
|
||||||
else:
|
else:
|
||||||
# Kein Profilbild vorhanden, nutze Default
|
# Kein Profilbild vorhanden, nutze Default
|
||||||
default_path = "/static/default_profile.png"
|
try:
|
||||||
if user_data.get("profile_picture") != default_path:
|
default_path = "/static/default_profile.png"
|
||||||
update_user_data(user_id, guild_id, "profile_picture", default_path)
|
if user_data.get("profile_picture") != default_path:
|
||||||
user_data["profile_picture"] = default_path
|
update_user_data(user_id, guild_id, "profile_picture", default_path)
|
||||||
|
user_data["profile_picture"] = default_path
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to set default profile picture for user {user_id}: {e}")
|
||||||
|
|
||||||
# Aktualisiere Join-Datum - IMMER wenn member.joined_at verfügbar ist
|
# Aktualisiere Join-Datum - IMMER wenn member.joined_at verfügbar ist
|
||||||
if member.joined_at:
|
if member.joined_at:
|
||||||
join_date = member.joined_at.date()
|
try:
|
||||||
# Aktualisiere Join-Datum auch wenn es bereits existiert (für den Fall, dass es falsch war)
|
join_date = member.joined_at.date()
|
||||||
update_user_data(user_id, guild_id, "join_date", join_date)
|
# Aktualisiere Join-Datum auch wenn es bereits existiert (für den Fall, dass es falsch war)
|
||||||
user_data["join_date"] = join_date
|
update_user_data(user_id, guild_id, "join_date", join_date)
|
||||||
|
user_data["join_date"] = join_date
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to update join date for user {user_id}: {e}")
|
||||||
|
|
||||||
logger.info(f"Updated user data for {member.display_name} (ID: {user_id}) - Nickname: {new_nickname}, Join Date: {join_date if member.joined_at else 'N/A'}")
|
logger.info(f"Updated user data for {member.display_name} (ID: {user_id}) - Nickname: {new_nickname}, Join Date: {join_date if member.joined_at else 'N/A'}")
|
||||||
|
|
||||||
@@ -993,8 +1014,11 @@ async def add_xp_to_user(user_id, guild_id, xp_gained, member=None):
|
|||||||
logger.error(f"Error updating user data during XP gain: {e}")
|
logger.error(f"Error updating user data during XP gain: {e}")
|
||||||
|
|
||||||
# Speichere die aktualisierten XP und Level in der Datenbank
|
# Speichere die aktualisierten XP und Level in der Datenbank
|
||||||
update_user_data(user_id, guild_id, "xp", user_data["xp"])
|
try:
|
||||||
update_user_data(user_id, guild_id, "level", user_data["level"])
|
update_user_data(user_id, guild_id, "xp", user_data["xp"])
|
||||||
|
update_user_data(user_id, guild_id, "level", user_data["level"])
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to update XP/Level for user {user_id}: {e}")
|
||||||
|
|
||||||
return level_up # Gibt zurück, ob ein Level-Up stattgefunden hat
|
return level_up # Gibt zurück, ob ein Level-Up stattgefunden hat
|
||||||
|
|
||||||
@@ -1594,7 +1618,12 @@ async def download_and_save_profile_image(user_id, discord_url):
|
|||||||
|
|
||||||
# Download das Bild
|
# Download das Bild
|
||||||
logger.info(f"Downloading profile image for user {user_id} from {discord_url}")
|
logger.info(f"Downloading profile image for user {user_id} from {discord_url}")
|
||||||
response = requests.get(discord_url, timeout=10)
|
|
||||||
|
# Use a session with timeout for better connection handling
|
||||||
|
session = requests.Session()
|
||||||
|
session.timeout = (10, 15) # (connection timeout, read timeout)
|
||||||
|
|
||||||
|
response = session.get(discord_url, timeout=15)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
# Speichere das Bild
|
# Speichere das Bild
|
||||||
|
|||||||
Reference in New Issue
Block a user