Source code for rewardsbot.services.user

"""User service for handling user-related operations.

This module provides the UserService class for fetching and formatting
user contribution summaries and statistics.

:var logger: User service logger instance
:type logger: :class:`logging.Logger`
"""

import logging
from datetime import datetime

from rewardsbot.models.contribution import Contribution

logger = logging.getLogger("discord.user")


[docs] class UserService: """Service class for user-related operations. This class handles user contribution data fetching and formatting user summaries for display in Discord messages. """
[docs] @staticmethod async def user_summary(api_service, username): """Generate a summary of user contributions and statistics. :param api_service: API service instance for data fetching :type api_service: :class:`APIService` :param username: Username to generate summary for :type username: str :return: Formatted user summary or error message :rtype: str """ try: contributions = await api_service.fetch_user_contributions(username) if not contributions: return f"No contributions for {username}." # Get first contribution cycle dates first_contribution_cycle = await api_service.fetch_cycle_by_id_plain( contributions[0]["cycle_id"] ) first_contribution_date = first_contribution_cycle.get("end") if first_contribution_date: end_date = datetime.fromisoformat( first_contribution_date.replace("Z", "+00:00") ) first_contribution_formatted = f"{end_date.year}/{end_date.month:02d}" else: first_contribution_formatted = "Unknown" total_contributions = len(contributions) total_rewards = sum( contribution.get("reward", 0) for contribution in contributions ) last_five_contributions = sorted( contributions, key=lambda x: x.get("id", 0), reverse=True )[:5] contributions_text = "\n".join( Contribution(contribution).formatted_contributions(True) for contribution in last_five_contributions ) return ( f"**{username}**\n\n" f"First contribution cycle: {first_contribution_formatted}\n" f"Total contributions: {total_contributions}\n" f"Total rewards: {total_rewards:,}\n\n" f"Last contributions:\n\n{contributions_text}" ) except Exception as error: logger.error(f"❌ User Summary Error: {error}", exc_info=True) return f"❌ Failed to generate user summary for {username}."