import asyncio import logging logger = logging.getLogger("bcs.sentiment") def _aliases_csv(user_data) -> str | None: """Convert aliases list to comma-separated string for DB storage.""" return ",".join(user_data.aliases) if user_data.aliases else None def save_user_state(bot, dirty_users: set[int], user_id: int) -> None: """Fire-and-forget save of a user's current state to DB.""" user_data = bot.drama_tracker.get_user(user_id) asyncio.create_task(bot.db.save_user_state( user_id=user_id, offense_count=user_data.offense_count, immune=user_data.immune, off_topic_count=user_data.off_topic_count, baseline_coherence=user_data.baseline_coherence, user_notes=user_data.notes or None, warned=user_data.warned_since_reset, last_offense_at=user_data.last_offense_time or None, aliases=_aliases_csv(user_data), warning_expires_at=user_data.warning_expires_at or None, )) dirty_users.discard(user_id) async def flush_dirty_states(bot, dirty_users: set[int]) -> None: """Save all dirty user states to DB.""" if not dirty_users: return dirty = list(dirty_users) saved = 0 for user_id in dirty: user_data = bot.drama_tracker.get_user(user_id) try: await bot.db.save_user_state( user_id=user_id, offense_count=user_data.offense_count, immune=user_data.immune, off_topic_count=user_data.off_topic_count, baseline_coherence=user_data.baseline_coherence, user_notes=user_data.notes or None, warned=user_data.warned_since_reset, last_offense_at=user_data.last_offense_time or None, aliases=_aliases_csv(user_data), warning_expires_at=user_data.warning_expires_at or None, ) dirty_users.discard(user_id) saved += 1 except Exception: logger.exception("Failed to flush state for user %d", user_id) logger.info("Flushed %d/%d dirty user states to DB.", saved, len(dirty))