bot_v4 / database /users.py
qqqsfasdf's picture
Upload 70 files
036b534 verified
# ============================================
# database/users.py โ€” ุงู„ู…ุณุชุฎุฏู…ูˆู† ูˆุงู„ู…ุดุชุฑูƒูˆู†
# ============================================
import logging
from database.connection import get_connection
logger = logging.getLogger(__name__)
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
# ุงู„ู…ุณุชุฎุฏู…ูˆู†
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
def upsert_user(user_id: int, username: str, first_name: str) -> None:
"""
ุชุณุฌูŠู„ ู…ุณุชุฎุฏู… ุฌุฏูŠุฏ ุฃูˆ ุชุญุฏูŠุซ ุจูŠุงู†ุงุชู‡ ุฅุฐุง ูƒุงู† ู…ูˆุฌูˆุฏุงู‹.
ูŠูุณุชุฏุนู‰ ููŠ ูƒู„ ุชูุงุนู„ ุฌุฏูŠุฏ ู…ุน ุงู„ุจูˆุช.
"""
conn = get_connection()
try:
conn.execute("""
INSERT INTO users (user_id, username, first_name)
VALUES (?, ?, ?)
ON CONFLICT(user_id) DO UPDATE SET
username = excluded.username,
first_name = excluded.first_name
""", (user_id, username or "", first_name or ""))
conn.commit()
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ upsert_user uid={user_id}: {e}", exc_info=True)
finally:
conn.close()
def get_user(user_id: int) -> dict | None:
"""ุฌู„ุจ ุจูŠุงู†ุงุช ู…ุณุชุฎุฏู…"""
conn = get_connection()
try:
c = conn.cursor()
c.execute("SELECT * FROM users WHERE user_id = ?", (user_id,))
row = c.fetchone()
return dict(row) if row else None
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ get_user uid={user_id}: {e}", exc_info=True)
return None
finally:
conn.close()
def is_user_banned(user_id: int) -> bool:
"""ุงู„ุชุญู‚ู‚ ู…ู† ุญุธุฑ ุงู„ู…ุณุชุฎุฏู…"""
conn = get_connection()
try:
c = conn.cursor()
c.execute(
"SELECT is_banned FROM users WHERE user_id = ?",
(user_id,)
)
row = c.fetchone()
return bool(row["is_banned"]) if row else False
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ is_user_banned uid={user_id}: {e}", exc_info=True)
return False
finally:
conn.close()
def ban_user(user_id: int) -> bool:
"""ุญุธุฑ ู…ุณุชุฎุฏู…"""
conn = get_connection()
try:
conn.execute(
"UPDATE users SET is_banned = 1 WHERE user_id = ?",
(user_id,)
)
conn.commit()
affected = conn.execute(
"SELECT changes() AS c"
).fetchone()["c"]
return affected > 0
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ ban_user uid={user_id}: {e}", exc_info=True)
return False
finally:
conn.close()
def unban_user(user_id: int) -> bool:
"""ุฑูุน ุงู„ุญุธุฑ ุนู† ู…ุณุชุฎุฏู…"""
conn = get_connection()
try:
conn.execute(
"UPDATE users SET is_banned = 0 WHERE user_id = ?",
(user_id,)
)
conn.commit()
affected = conn.execute(
"SELECT changes() AS c"
).fetchone()["c"]
return affected > 0
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ unban_user uid={user_id}: {e}", exc_info=True)
return False
finally:
conn.close()
def get_total_users() -> int:
"""ุฅุฌู…ุงู„ูŠ ุงู„ู…ุณุชุฎุฏู…ูŠู† ุงู„ู…ุณุฌู„ูŠู†"""
conn = get_connection()
try:
c = conn.cursor()
c.execute("SELECT COUNT(*) AS cnt FROM users WHERE is_banned = 0")
return c.fetchone()["cnt"]
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ get_total_users: {e}", exc_info=True)
return 0
finally:
conn.close()
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
# ุงู„ู…ุดุชุฑูƒูˆู† ููŠ ุงู„ุชู†ุจูŠู‡ุงุช
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
def subscribe_user(user_id: int, platform: str = "all") -> bool:
"""
ุงุดุชุฑุงูƒ ู…ุณุชุฎุฏู… ููŠ ุงู„ุชู†ุจูŠู‡ุงุช.
ูŠูุฑุฌุน True ุฅุฐุง ุชู… ุงู„ุงุดุชุฑุงูƒ (ู„ู… ูŠูƒู† ู…ุดุชุฑูƒุงู‹)ุŒ
False ุฅุฐุง ูƒุงู† ู…ุดุชุฑูƒุงู‹ ู…ุณุจู‚ุงู‹.
"""
conn = get_connection()
try:
c = conn.cursor()
c.execute("""
INSERT OR IGNORE INTO notification_subscribers (user_id, platform)
VALUES (?, ?)
""", (user_id, platform))
conn.commit()
return c.rowcount > 0
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ subscribe_user uid={user_id}: {e}", exc_info=True)
return False
finally:
conn.close()
def unsubscribe_user(user_id: int) -> bool:
"""
ุฅู„ุบุงุก ุงุดุชุฑุงูƒ ู…ุณุชุฎุฏู… ู…ู† ุงู„ุชู†ุจูŠู‡ุงุช.
ูŠูุฑุฌุน True ุฅุฐุง ุชู… ุงู„ุฅู„ุบุงุก.
"""
conn = get_connection()
try:
c = conn.cursor()
c.execute(
"DELETE FROM notification_subscribers WHERE user_id = ?",
(user_id,)
)
conn.commit()
return c.rowcount > 0
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ unsubscribe_user uid={user_id}: {e}", exc_info=True)
return False
finally:
conn.close()
def is_subscribed(user_id: int) -> bool:
"""ุงู„ุชุญู‚ู‚ ู…ู† ุงุดุชุฑุงูƒ ู…ุณุชุฎุฏู… ููŠ ุงู„ุชู†ุจูŠู‡ุงุช"""
conn = get_connection()
try:
c = conn.cursor()
c.execute(
"SELECT user_id FROM notification_subscribers WHERE user_id = ?",
(user_id,)
)
return c.fetchone() is not None
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ is_subscribed uid={user_id}: {e}", exc_info=True)
return False
finally:
conn.close()
def get_all_subscriber_ids() -> list[int]:
"""
ุฌู„ุจ ูƒู„ IDs ุงู„ู…ุดุชุฑูƒูŠู† ููŠ ุงู„ุชู†ุจูŠู‡ุงุช (ุบูŠุฑ ุงู„ู…ุญุธูˆุฑูŠู†).
ูŠูุณุชุฎุฏู… ู…ู† broadcaster.py ู„ุฅุฑุณุงู„ ุงู„ุฅุฐุงุนุงุช.
"""
conn = get_connection()
try:
c = conn.cursor()
c.execute("""
SELECT ns.user_id
FROM notification_subscribers ns
JOIN users u ON ns.user_id = u.user_id
WHERE u.is_banned = 0
ORDER BY ns.subscribed_at ASC
""")
return [row["user_id"] for row in c.fetchall()]
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ get_all_subscriber_ids: {e}", exc_info=True)
return []
finally:
conn.close()
def get_subscriber_count() -> int:
"""ุนุฏุฏ ุงู„ู…ุดุชุฑูƒูŠู† ุงู„ู†ุดุทูŠู† ููŠ ุงู„ุชู†ุจูŠู‡ุงุช"""
conn = get_connection()
try:
c = conn.cursor()
c.execute("""
SELECT COUNT(*) AS cnt
FROM notification_subscribers ns
JOIN users u ON ns.user_id = u.user_id
WHERE u.is_banned = 0
""")
return c.fetchone()["cnt"]
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ get_subscriber_count: {e}", exc_info=True)
return 0
finally:
conn.close()
def remove_subscriber(user_id: int) -> None:
"""
ุญุฐู ู…ุดุชุฑูƒ ู…ู† ุงู„ุชู†ุจูŠู‡ุงุช (ูŠูุณุชุฎุฏู… ู…ู† broadcaster ุนู†ุฏ ุฎุทุฃ ุฏุงุฆู…).
ู…ุซุงู„: ุงู„ู…ุณุชุฎุฏู… ุญุธุฑ ุงู„ุจูˆุช ุฃูˆ ุญุฐู ุญุณุงุจู‡.
"""
conn = get_connection()
try:
conn.execute(
"DELETE FROM notification_subscribers WHERE user_id = ?",
(user_id,)
)
conn.commit()
logger.info(f"ุชู… ุฅุฒุงู„ุฉ ุงู„ู…ุดุชุฑูƒ {user_id} ู…ู† ุงู„ุชู†ุจูŠู‡ุงุช (ุญุธุฑ ุฃูˆ ุญุณุงุจ ู…ุญุฐูˆู)")
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ remove_subscriber uid={user_id}: {e}", exc_info=True)
finally:
conn.close()
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
# ุณุฌู„ ุงู„ุฅุฐุงุนุงุช
# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
def log_broadcast(
admin_id: int,
message_text: str,
broadcast_type: str,
game_title: str,
game_link: str,
sent_count: int,
failed_count: int,
blocked_count: int
) -> int:
"""ุชุณุฌูŠู„ ู†ุชูŠุฌุฉ ุฅุฐุงุนุฉ ููŠ ู‚ุงุนุฏุฉ ุงู„ุจูŠุงู†ุงุช. ูŠูุฑุฌุน ID ุงู„ุณุฌู„."""
conn = get_connection()
try:
c = conn.cursor()
c.execute("""
INSERT INTO broadcasts
(admin_id, message_text, broadcast_type, game_title, game_link,
sent_count, failed_count, blocked_count)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", (
admin_id, message_text, broadcast_type, game_title, game_link,
sent_count, failed_count, blocked_count
))
conn.commit()
return c.lastrowid
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ log_broadcast: {e}", exc_info=True)
return 0
finally:
conn.close()
def get_broadcast_history(limit: int = 10) -> list[dict]:
"""ุขุฎุฑ N ุฅุฐุงุนุฉ (ู„ู„ู…ุดุฑู)"""
conn = get_connection()
try:
c = conn.cursor()
c.execute("""
SELECT id, broadcast_type, game_title, sent_count,
failed_count, blocked_count, sent_at
FROM broadcasts
ORDER BY id DESC
LIMIT ?
""", (limit,))
return [dict(r) for r in c.fetchall()]
except Exception as e:
logger.error(f"ุฎุทุฃ ููŠ get_broadcast_history: {e}", exc_info=True)
return []
finally:
conn.close()