diff --git a/resolvers/editor.py b/resolvers/editor.py index 0f8c1fc6..0330a9f6 100644 --- a/resolvers/editor.py +++ b/resolvers/editor.py @@ -263,28 +263,9 @@ async def create_shout(_, info, inp): def patch_main_topic(session, main_topic_slug, shout): - """Update the main topic for a shout. - - Args: - session: SQLAlchemy session - main_topic_slug (str): Slug of the topic to set as main - shout (Shout): The shout to update - - Side Effects: - - Updates ShoutTopic.main flags in database - - Only one topic can be main at a time - - Example: - >>> def test_patch_main_topic(): - ... with local_session() as session: - ... shout = session.query(Shout).first() - ... patch_main_topic(session, 'tech', shout) - ... main_topic = session.query(ShoutTopic).filter_by( - ... shout=shout.id, main=True).first() - ... assert main_topic.topic.slug == 'tech' - ... return main_topic - """ + """Update the main topic for a shout.""" logger.info(f"Starting patch_main_topic for shout#{shout.id} with slug '{main_topic_slug}'") + logger.debug(f"Current shout topics: {[(t.topic.slug, t.main) for t in shout.topics]}") with session.begin(): # Получаем текущий главный топик @@ -292,7 +273,9 @@ def patch_main_topic(session, main_topic_slug, shout): session.query(ShoutTopic).filter(and_(ShoutTopic.shout == shout.id, ShoutTopic.main.is_(True))).first() ) if old_main: - logger.info(f"Found current main topic: {old_main.topic}") + logger.info(f"Found current main topic: {old_main.topic.slug}") + else: + logger.info("No current main topic found") # Находим новый главный топик main_topic = session.query(Topic).filter(Topic.slug == main_topic_slug).first() @@ -300,7 +283,7 @@ def patch_main_topic(session, main_topic_slug, shout): logger.error(f"Main topic with slug '{main_topic_slug}' not found") return - logger.info(f"Found new main topic: {main_topic.id}") + logger.info(f"Found new main topic: {main_topic.slug} (id={main_topic.id})") # Находим связь с новым главным топиком new_main = ( @@ -308,9 +291,10 @@ def patch_main_topic(session, main_topic_slug, shout): .filter(and_(ShoutTopic.shout == shout.id, ShoutTopic.topic == main_topic.id)) .first() ) + logger.debug(f"Found new main topic relation: {new_main is not None}") if old_main and new_main and old_main is not new_main: - logger.info("Updating main topic flags") + logger.info(f"Updating main topic flags: {old_main.topic.slug} -> {new_main.topic.slug}") old_main.main = False session.add(old_main) @@ -319,6 +303,8 @@ def patch_main_topic(session, main_topic_slug, shout): session.flush() logger.info(f"Main topic updated for shout#{shout.id}") + else: + logger.warning(f"No changes needed for main topic (old={old_main is not None}, new={new_main is not None})") def patch_topics(session, shout, topics_input): @@ -648,21 +634,12 @@ async def delete_shout(_, info, shout_id: int): def get_main_topic(topics): - """Get the main topic from a list of ShoutTopic objects. - - Args: - topics: List of ShoutTopic objects - - Returns: - dict: Main topic data with id, slug, title and is_main fields - - Example: - >>> topics = [ShoutTopic(main=True, topic=Topic(id=1, slug='test', title='Test'))] - >>> result = get_main_topic(topics) - >>> assert result['id'] == 1 - >>> assert result['is_main'] == True - """ + """Get the main topic from a list of ShoutTopic objects.""" + logger.info(f"Starting get_main_topic with {len(topics) if topics else 0} topics") + logger.debug(f"Topics data: {[(t.topic.slug if t.topic else 'no-topic', t.main) for t in topics] if topics else []}") + if not topics: + logger.warning("No topics provided to get_main_topic") return { "id": 0, "title": "no topic", @@ -672,24 +649,30 @@ def get_main_topic(topics): # Find first main topic in original order main_topic_rel = next((st for st in topics if st.main), None) + logger.debug(f"Found main topic relation: {main_topic_rel.topic.slug if main_topic_rel and main_topic_rel.topic else None}") if main_topic_rel and main_topic_rel.topic: - return { + result = { "slug": main_topic_rel.topic.slug, "title": main_topic_rel.topic.title, "id": main_topic_rel.topic.id, "is_main": True } + logger.info(f"Returning main topic: {result}") + return result # If no main found but topics exist, return first if topics and topics[0].topic: - return { + logger.info(f"No main topic found, using first topic: {topics[0].topic.slug}") + result = { "slug": topics[0].topic.slug, "title": topics[0].topic.title, "id": topics[0].topic.id, "is_main": True } + return result + logger.warning("No valid topics found, returning default") return { "slug": "notopic", "title": "no topic", diff --git a/resolvers/reader.py b/resolvers/reader.py index 1625d1e5..b82a7c1e 100644 --- a/resolvers/reader.py +++ b/resolvers/reader.py @@ -188,12 +188,15 @@ def get_shouts_with_links(info, q, limit=20, offset=0): """ shouts = [] try: + logger.info(f"Starting get_shouts_with_links with limit={limit}, offset={offset}") q = q.limit(limit).offset(offset) with local_session() as session: shouts_result = session.execute(q).all() + logger.info(f"Got {len(shouts_result) if shouts_result else 0} shouts from query") if not shouts_result: + logger.warning("No shouts found in query result") return [] for idx, row in enumerate(shouts_result): @@ -201,6 +204,7 @@ def get_shouts_with_links(info, q, limit=20, offset=0): shout = None if hasattr(row, "Shout"): shout = row.Shout + logger.debug(f"Processing shout#{shout.id} at index {idx}") if shout: shout_id = int(f"{shout.id}") shout_dict = shout.dict() @@ -228,37 +232,34 @@ def get_shouts_with_links(info, q, limit=20, offset=0): topics = None if has_field(info, "topics") and hasattr(row, "topics"): topics = json.loads(row.topics) if isinstance(row.topics, str) else row.topics + logger.debug(f"Shout#{shout_id} topics: {topics}") shout_dict["topics"] = topics if has_field(info, "main_topic"): main_topic = None if hasattr(row, "main_topic"): + logger.debug(f"Raw main_topic for shout#{shout_id}: {row.main_topic}") main_topic = json.loads(row.main_topic) if isinstance(row.main_topic, str) else row.main_topic - - # Если main_topic не определен, ищем топик с main=True или берем первый - if not main_topic and topics: - # Сначала ищем топик с main=True - main_topic = next((t for t in topics if t.get("is_main")), None) - - # Если не нашли main=True, берем первый топик - if not main_topic and len(topics) > 0: - main_topic = { - "id": topics[0]["id"], - "title": topics[0]["title"], - "slug": topics[0]["slug"], - "is_main": True - } - - # Если все еще нет main_topic, используем заглушку - if not main_topic: + logger.debug(f"Parsed main_topic for shout#{shout_id}: {main_topic}") + + if not main_topic and topics and len(topics) > 0: + logger.info(f"No main_topic found for shout#{shout_id}, using first topic from list") + main_topic = { + "id": topics[0]["id"], + "title": topics[0]["title"], + "slug": topics[0]["slug"], + "is_main": True + } + elif not main_topic: + logger.warning(f"No main_topic and no topics found for shout#{shout_id}") main_topic = { "id": 0, "title": "no topic", "slug": "notopic", "is_main": True } - shout_dict["main_topic"] = main_topic + logger.debug(f"Final main_topic for shout#{shout_id}: {main_topic}") if has_field(info, "authors") and hasattr(row, "authors"): shout_dict["authors"] = ( @@ -278,12 +279,14 @@ def get_shouts_with_links(info, q, limit=20, offset=0): shouts.append(shout_dict) except Exception as row_error: - logger.error(f"Ошибка при обработке строки {idx}: {row_error}", exc_info=True) + logger.error(f"Error processing row {idx}: {row_error}", exc_info=True) continue + except Exception as e: - logger.error(f"Фатальная ошибка в get_shouts_with_links: {e}", exc_info=True) + logger.error(f"Fatal error in get_shouts_with_links: {e}", exc_info=True) raise finally: + logger.info(f"Returning {len(shouts)} shouts from get_shouts_with_links") return shouts