diff --git a/managers/mongodb_manager.py b/managers/mongodb_manager.py index ca1f568..f0f1863 100644 --- a/managers/mongodb_manager.py +++ b/managers/mongodb_manager.py @@ -95,20 +95,18 @@ class MongoDBArticleCache: expires_at = datetime.utcnow() + timedelta(days=NOTIFIED_ARTICLE_TTL_DAYS) now = datetime.utcnow() - # Obtener todos los artículos existentes de una vez para optimizar - article_ids = [(a.get_platform(), str(a.get_id())) for a in article_list] - existing_articles = { - (a['platform'], a['id']): a - for a in self._articles_collection.find({ - '$or': [{'platform': p, 'id': i} for p, i in article_ids] - }) - } - operations = [] for article in article_list: platform = article.get_platform() article_id = str(article.get_id()) - key = (platform, article_id) + + # Consultar MongoDB directamente para cada artículo + # Esto asegura que siempre encontremos el artículo si existe, + # independientemente de la lista pasada como parámetro + existing = self._articles_collection.find_one({ + 'platform': platform, + 'id': article_id + }) # Campos base del artículo (sin user_info, sin createdAt/updatedAt) base_fields = { @@ -123,13 +121,70 @@ class MongoDBArticleCache: 'url': article.get_url(), 'images': article.get_images(), 'modified_at': article.get_modified_at(), - #'expiresAt': expires_at, + 'expiresAt': expires_at, } - # Preparar user_info - existing = existing_articles.get(key) - if existing is None: + # Preparar user_info basándose en lo que existe realmente en MongoDB + if existing: + # Artículo existe, actualizar user_info + existing_user_info = existing.get('user_info', []) + # Buscar si ya existe user_info para este usuario + user_info_index = None + for i, ui in enumerate(existing_user_info): + if ui.get('username') == username: + user_info_index = i + break + + if user_info_index is not None: + # Actualizar user_info existente pero mantener notified_at original + existing_user_info_entry = existing_user_info[user_info_index] + existing_user_info[user_info_index] = { + 'username': existing_user_info_entry.get('username'), + 'worker_name': worker_name or existing_user_info_entry.get('worker_name'), + 'notified': True, + 'notified_at': existing_user_info_entry.get('notified_at'), # Preservar notified_at original + 'is_favorite': existing_user_info_entry.get('is_favorite', False), + } + else: + # Añadir nuevo user_info + existing_user_info.append({ + 'username': username, + 'worker_name': worker_name, + 'notified': True, + 'notified_at': now, + 'is_favorite': False, + }) + + # Solo actualizar precio si es diferente, no actualizar fechas de notificación + existing_price = existing.get('price') + new_price = article.get_price() + if existing_price == new_price: + # Si el precio es el mismo, solo actualizar user_info y eliminar notifiedAt a nivel de artículo + operations.append( + UpdateOne( + {'platform': platform, 'id': article_id}, + { + '$set': {'user_info': existing_user_info}, + '$unset': {'notifiedAt': '', 'notified_at': ''} + } + ) + ) + else: + # Precio diferente, actualizar campos del artículo + user_info + # Mantener createdAt/updatedAt originales (no se incluyen en el $set) + update_data = dict(base_fields) + update_data['user_info'] = existing_user_info + operations.append( + UpdateOne( + {'platform': platform, 'id': article_id}, + { + '$set': update_data, + '$unset': {'notifiedAt': '', 'notified_at': ''} + } + ) + ) + else: # Artículo nuevo new_article_data = dict(base_fields) new_article_data['user_info'] = [{ @@ -142,6 +197,7 @@ class MongoDBArticleCache: # Usar $setOnInsert para createdAt y updatedAt # Solo se establecerán si el documento es nuevo (insert), no si ya existe (update) + # Si el documento ya existe, $setOnInsert NO se ejecuta, por lo que updatedAt no se actualiza operations.append( UpdateOne( {'platform': platform, 'id': article_id},