modified: bot.py
This commit is contained in:
103
bot.py
103
bot.py
@@ -92,22 +92,28 @@ client = commands.Bot(command_prefix='-', intents=intents, owner_id = OWNER_ID)
|
||||
askmultus_queue = asyncio.Queue()
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
# Verbindung zur MySQL-Datenbank herstellen
|
||||
db_connection = mysql.connector.connect(
|
||||
host=DB_HOST,
|
||||
port=DB_PORT,
|
||||
user=DB_USER,
|
||||
password=DB_PASSWORD,
|
||||
database=DB_DATABASE
|
||||
)
|
||||
# Verbindung zur MySQL-Datenbank herstellen (OLD - now using connection pool)
|
||||
# db_connection = mysql.connector.connect(
|
||||
# host=DB_HOST,
|
||||
# port=DB_PORT,
|
||||
# user=DB_USER,
|
||||
# password=DB_PASSWORD,
|
||||
# database=DB_DATABASE
|
||||
# )
|
||||
|
||||
# Cursor erstellen
|
||||
db_cursor = db_connection.cursor()
|
||||
# Cursor erstellen (OLD - now using connection pool)
|
||||
# db_cursor = db_connection.cursor()
|
||||
|
||||
def close_database_connection(connection):
|
||||
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):
|
||||
"""Fügt neue Benutzerdaten in die Datenbank ein mit Connection Pool"""
|
||||
connection = None
|
||||
cursor = None
|
||||
try:
|
||||
connection = connect_to_database()
|
||||
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)
|
||||
@@ -115,44 +121,50 @@ def insert_user_data(user_id, guild_id, permission, points, ban, askmultus, filt
|
||||
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:
|
||||
retry_query(execute_insert)
|
||||
print("User data inserted successfully.")
|
||||
connection.commit()
|
||||
logger.info("User data inserted successfully.")
|
||||
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):
|
||||
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:
|
||||
connection = connect_to_database()
|
||||
cursor = connection.cursor()
|
||||
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
|
||||
if field == 'chat_history':
|
||||
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:
|
||||
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:
|
||||
logger.error(f"Database error: {err}")
|
||||
if db_connection.is_connected():
|
||||
db_cursor.close()
|
||||
db_connection.close()
|
||||
|
||||
# Verbindung neu aufbauen
|
||||
db_connection = connect_to_database()
|
||||
db_cursor = db_connection.cursor()
|
||||
|
||||
# Wiederhole die Abfrage nach dem erneuten Verbinden
|
||||
update_user_data(user_id, guild_id, field, value)
|
||||
if connection:
|
||||
connection.rollback()
|
||||
raise err
|
||||
finally:
|
||||
if cursor:
|
||||
cursor.close()
|
||||
if connection:
|
||||
close_database_connection(connection)
|
||||
|
||||
|
||||
def connect_to_database():
|
||||
@@ -175,10 +187,7 @@ def retry_query(func, *args, retries=3, delay=5):
|
||||
time.sleep(delay)
|
||||
raise RuntimeError("Max retries exceeded")
|
||||
|
||||
def get_database_cursor():
|
||||
if not db_connection.is_connected():
|
||||
db_connection.reconnect(attempts=3, delay=5)
|
||||
return db_connection.cursor()
|
||||
# Removed get_database_cursor() - now using connection pool directly
|
||||
|
||||
pool = mysql.connector.pooling.MySQLConnectionPool(
|
||||
pool_name="mypool",
|
||||
@@ -960,11 +969,15 @@ async def add_xp_to_user(user_id, guild_id, xp_gained, member=None):
|
||||
# Aktualisiere Nickname
|
||||
new_nickname = member.display_name
|
||||
if user_data.get("nickname") != new_nickname:
|
||||
try:
|
||||
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
|
||||
if member.display_avatar:
|
||||
try:
|
||||
discord_avatar_url = str(member.display_avatar.url)
|
||||
# Download und speichere das Profilbild lokal
|
||||
local_profile_path = await download_and_save_profile_image(user_id, discord_avatar_url)
|
||||
@@ -973,19 +986,27 @@ async def add_xp_to_user(user_id, guild_id, xp_gained, member=None):
|
||||
if user_data.get("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:
|
||||
# Kein Profilbild vorhanden, nutze Default
|
||||
try:
|
||||
default_path = "/static/default_profile.png"
|
||||
if user_data.get("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
|
||||
if member.joined_at:
|
||||
try:
|
||||
join_date = member.joined_at.date()
|
||||
# Aktualisiere Join-Datum auch wenn es bereits existiert (für den Fall, dass es falsch war)
|
||||
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'}")
|
||||
|
||||
@@ -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}")
|
||||
|
||||
# Speichere die aktualisierten XP und Level in der Datenbank
|
||||
try:
|
||||
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
|
||||
|
||||
@@ -1594,7 +1618,12 @@ async def download_and_save_profile_image(user_id, discord_url):
|
||||
|
||||
# Download das Bild
|
||||
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:
|
||||
# Speichere das Bild
|
||||
|
||||
Reference in New Issue
Block a user