Some updates for backend thingies
This commit is contained in:
1
src/consumers/__init__.py
Normal file
1
src/consumers/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""RabbitMQ Consumer implementations"""
|
||||
149
src/consumers/report_consumer.py
Normal file
149
src/consumers/report_consumer.py
Normal file
@@ -0,0 +1,149 @@
|
||||
"""Report RabbitMQ Consumer - Processes report events and saves to database"""
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
# Add src to path to import modules
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from infrastructure.adapters.rabbitmq.consumer import RabbitMQConsumer
|
||||
from infrastructure.adapters.rabbitmq.messages import ReportMessage, ReportEventType
|
||||
from infrastructure.adapters.persistence.report_repository_mongo import ReportRepositoryMongo
|
||||
from infrastructure.adapters.persistence.user_repository_sql import UserRepositorySQL
|
||||
from domain.reports import Report
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ReportConsumer:
|
||||
"""Consumer for report events from RabbitMQ"""
|
||||
|
||||
def __init__(self):
|
||||
self.repo = ReportRepositoryMongo()
|
||||
self.user_repo = UserRepositorySQL()
|
||||
self.consumer = RabbitMQConsumer(queue_name='reports_queue')
|
||||
self.consumer.set_callback(self.process_message)
|
||||
|
||||
def process_message(self, message_dict: dict):
|
||||
"""
|
||||
Processes a report event message from RabbitMQ
|
||||
|
||||
Args:
|
||||
message_dict: Dictionary containing the message data
|
||||
"""
|
||||
try:
|
||||
# Reconstruct the ReportMessage object
|
||||
message = ReportMessage.from_dict(message_dict)
|
||||
|
||||
if message.event_type == ReportEventType.CREATE:
|
||||
self._handle_create_report(message)
|
||||
elif message.event_type == ReportEventType.UPDATE_VISIBILITY:
|
||||
self._handle_update_visibility(message)
|
||||
elif message.event_type == ReportEventType.DELETE:
|
||||
self._handle_delete_report(message)
|
||||
else:
|
||||
logger.warning(f"Unknown event type: {message.event_type}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing report message: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def _handle_create_report(self, message: ReportMessage):
|
||||
"""Handle report create event"""
|
||||
try:
|
||||
logger.info(f"Creating report: {message.id_reporte} from user {message.id_usuario}")
|
||||
|
||||
# Parse datetime string
|
||||
fecha_creacion = datetime.fromisoformat(message.fecha_creacion)
|
||||
|
||||
# Create Report domain object
|
||||
report = Report(
|
||||
id_reporte=message.id_reporte,
|
||||
id_usuario=message.id_usuario,
|
||||
tipo_reporte=message.tipo_reporte,
|
||||
descripcion=message.descripcion,
|
||||
ubicacion=message.ubicacion,
|
||||
visibilidad=message.visibilidad,
|
||||
fecha_creacion=fecha_creacion
|
||||
)
|
||||
|
||||
# Save to repository
|
||||
saved_report = self.repo.save(report)
|
||||
logger.info(f"Report created successfully: {message.id_reporte}")
|
||||
|
||||
# Increment user's report counter
|
||||
self.user_repo.increment_reports(message.id_usuario)
|
||||
logger.info(f"Incremented report counter for user: {message.id_usuario}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating report: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def _handle_update_visibility(self, message: ReportMessage):
|
||||
"""Handle report visibility update event"""
|
||||
try:
|
||||
logger.info(f"Updating visibility for report: {message.id_reporte}")
|
||||
|
||||
# Find the report
|
||||
report = self.repo.find_by_id(message.id_reporte)
|
||||
if not report:
|
||||
logger.warning(f"Report not found: {message.id_reporte}")
|
||||
return
|
||||
|
||||
# Update visibility
|
||||
self.repo.update_visibility(message.id_reporte, message.visibilidad)
|
||||
logger.info(f"Report visibility updated: {message.id_reporte} -> {message.visibilidad}")
|
||||
|
||||
# Penalize author if visibility is very low (shadowban)
|
||||
if message.penalize_author and message.visibilidad < 20:
|
||||
try:
|
||||
user = self.user_repo.find_by_id(report.id_usuario)
|
||||
if user:
|
||||
# Reduce user's rating
|
||||
new_rating = max(0, user.calificacion - 5)
|
||||
self.user_repo.update_rating(report.id_usuario, new_rating)
|
||||
logger.info(f"Author penalized: user {report.id_usuario} rating reduced to {new_rating}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error penalizing author: {e}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating report visibility: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def _handle_delete_report(self, message: ReportMessage):
|
||||
"""Handle report delete event"""
|
||||
try:
|
||||
logger.info(f"Deleting report: {message.id_reporte}")
|
||||
|
||||
success = self.repo.delete(message.id_reporte)
|
||||
if success:
|
||||
logger.info(f"Report deleted successfully: {message.id_reporte}")
|
||||
else:
|
||||
logger.warning(f"Failed to delete report: {message.id_reporte}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error deleting report: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def start(self):
|
||||
"""Start consuming messages"""
|
||||
logger.info("Starting Report Consumer...")
|
||||
logger.info("[*] Waiting for report events. Ctrl+C to exit.")
|
||||
try:
|
||||
self.consumer.start_consuming()
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Report Consumer stopped by user")
|
||||
except Exception as e:
|
||||
logger.error(f"Consumer error: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
consumer = ReportConsumer()
|
||||
consumer.start()
|
||||
145
src/consumers/user_consumer.py
Normal file
145
src/consumers/user_consumer.py
Normal file
@@ -0,0 +1,145 @@
|
||||
"""User RabbitMQ Consumer - Processes user events and saves to database"""
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
# Add src to path to import modules
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from infrastructure.adapters.rabbitmq.consumer import RabbitMQConsumer
|
||||
from infrastructure.adapters.rabbitmq.messages import UserMessage, UserEventType
|
||||
from infrastructure.adapters.persistence.user_repository_sql import UserRepositorySQL
|
||||
from domain.users import User
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UserConsumer:
|
||||
"""Consumer for user events from RabbitMQ"""
|
||||
|
||||
def __init__(self):
|
||||
self.repo = UserRepositorySQL()
|
||||
self.consumer = RabbitMQConsumer(queue_name='users_queue')
|
||||
self.consumer.set_callback(self.process_message)
|
||||
|
||||
def process_message(self, message_dict: dict):
|
||||
"""
|
||||
Processes a user event message from RabbitMQ
|
||||
|
||||
Args:
|
||||
message_dict: Dictionary containing the message data
|
||||
"""
|
||||
try:
|
||||
# Reconstruct the UserMessage object
|
||||
message = UserMessage.from_dict(message_dict)
|
||||
|
||||
if message.event_type == UserEventType.CREATE:
|
||||
self._handle_create_user(message)
|
||||
elif message.event_type == UserEventType.UPDATE:
|
||||
self._handle_update_user(message)
|
||||
elif message.event_type == UserEventType.DELETE:
|
||||
self._handle_delete_user(message)
|
||||
else:
|
||||
logger.warning(f"Unknown event type: {message.event_type}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing user message: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def _handle_create_user(self, message: UserMessage):
|
||||
"""Handle user create event"""
|
||||
try:
|
||||
logger.info(f"Creating user: {message.email}")
|
||||
|
||||
# Parse datetime strings
|
||||
fecha_nacimiento = datetime.fromisoformat(message.fecha_nacimiento)
|
||||
fecha_creacion = datetime.fromisoformat(message.fecha_creacion)
|
||||
|
||||
# Create User domain object
|
||||
user = User(
|
||||
user_id=0, # Will be auto-generated by DB
|
||||
nombre=message.nombre,
|
||||
apellido=message.apellido,
|
||||
email=message.email,
|
||||
fecha_nacimiento=fecha_nacimiento,
|
||||
fecha_creacion=fecha_creacion,
|
||||
calificacion=message.calificacion,
|
||||
numero_reportes=message.numero_reportes,
|
||||
url_foto_perfil=message.url_foto_perfil,
|
||||
biografia=message.biografia
|
||||
)
|
||||
|
||||
# Save to repository
|
||||
saved_user = self.repo.save(user)
|
||||
logger.info(f"User created successfully: {saved_user.user_id} - {saved_user.email}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating user: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def _handle_update_user(self, message: UserMessage):
|
||||
"""Handle user update event"""
|
||||
try:
|
||||
logger.info(f"Updating user: {message.user_id}")
|
||||
|
||||
# Find the user
|
||||
user = self.repo.find_by_id(message.user_id)
|
||||
if not user:
|
||||
logger.warning(f"User not found: {message.user_id}")
|
||||
return
|
||||
|
||||
# Update fields if provided
|
||||
if message.nombre:
|
||||
user.nombre = message.nombre
|
||||
if message.apellido:
|
||||
user.apellido = message.apellido
|
||||
if message.url_foto_perfil is not None:
|
||||
user.url_foto_perfil = message.url_foto_perfil
|
||||
if message.biografia is not None:
|
||||
user.biografia = message.biografia
|
||||
|
||||
# Save to repository
|
||||
updated_user = self.repo.update(user)
|
||||
logger.info(f"User updated successfully: {message.user_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating user: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def _handle_delete_user(self, message: UserMessage):
|
||||
"""Handle user delete event"""
|
||||
try:
|
||||
logger.info(f"Deleting user: {message.user_id}")
|
||||
|
||||
success = self.repo.delete(message.user_id)
|
||||
if success:
|
||||
logger.info(f"User deleted successfully: {message.user_id}")
|
||||
else:
|
||||
logger.warning(f"Failed to delete user: {message.user_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error deleting user: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
def start(self):
|
||||
"""Start consuming messages"""
|
||||
logger.info("Starting User Consumer...")
|
||||
logger.info("[*] Waiting for user events. Ctrl+C to exit.")
|
||||
try:
|
||||
self.consumer.start_consuming()
|
||||
except KeyboardInterrupt:
|
||||
logger.info("User Consumer stopped by user")
|
||||
except Exception as e:
|
||||
logger.error(f"Consumer error: {e}", exc_info=True)
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
consumer = UserConsumer()
|
||||
consumer.start()
|
||||
Reference in New Issue
Block a user