diff --git a/resolvers/follower.py b/resolvers/follower.py index be5e4999..fc6e5fe7 100644 --- a/resolvers/follower.py +++ b/resolvers/follower.py @@ -19,101 +19,136 @@ from services.auth import login_required from services.db import local_session from services.notify import notify_follower from services.schema import mutation, query +from utils.logger import root_logger as logger @mutation.field("follow") @login_required async def follow(_, info, what, slug): + logger.debug("Начало выполнения функции 'follow'") user_id = info.context.get("user_id") follower_dict = info.context.get("author") + logger.debug(f"user_id: {user_id}, follower_dict: {follower_dict}") + if not user_id or not follower_dict: + logger.warning("Неавторизованный доступ при попытке следования") return {"error": "unauthorized"} + follower_id = follower_dict.get("id") + logger.debug(f"follower_id: {follower_id}") entity_classes = { "AUTHOR": (Author, AuthorFollower, get_cached_follower_authors, cache_author), "TOPIC": (Topic, TopicFollower, get_cached_follower_topics, cache_topic), - "COMMUNITY": (Community, CommunityFollower, None, None), # No cache methods provided for community - "SHOUT": (Shout, ShoutReactionsFollower, None, None), # No cache methods provided for shout + "COMMUNITY": (Community, CommunityFollower, None, None), # Нет методов кэша для сообщества + "SHOUT": (Shout, ShoutReactionsFollower, None, None), # Нет методов кэша для shout } if what not in entity_classes: + logger.error(f"Неверный тип для следования: {what}") return {"error": "invalid follow type"} entity_class, follower_class, get_cached_follows_method, cache_method = entity_classes[what] entity_type = what.lower() + logger.debug(f"entity_class: {entity_class}, follower_class: {follower_class}, entity_type: {entity_type}") + entity_id = None entity_dict = None try: - # Fetch entity id from the database + logger.debug("Попытка получить сущность из базы данных") with local_session() as session: entity_query = select(entity_class).filter(entity_class.slug == slug) - [entity] = get_with_stat(entity_query) + entities = get_with_stat(entity_query) + logger.debug(f"Полученные сущности: {entities}") + [entity] = entities if not entity: + logger.warning(f"{what.lower()} не найден по slug: {slug}") return {"error": f"{what.lower()} not found"} entity_id = entity.id entity_dict = entity.dict() + logger.debug(f"entity_id: {entity_id}, entity_dict: {entity_dict}") if entity_id: - # Update database + logger.debug("Попытка добавить запись в базу данных") with local_session() as session: sub = follower_class(follower=follower_id, **{entity_type: entity_id}) + logger.debug(f"Создан объект подписки: {sub}") session.add(sub) session.commit() + logger.info(f"Пользователь {follower_id} подписался на {what.lower()} с ID {entity_id}") follows = None - # Update cache + # Обновление кэша if cache_method: + logger.debug("Обновление кэша") await cache_method(entity_dict) if get_cached_follows_method: + logger.debug("Получение обновленных подписок из кэша") follows = await get_cached_follows_method(follower_id) + logger.debug(f"Текущие подписки: {follows}") - # Notify author (only for AUTHOR type) + # Уведомление автора (только для типа AUTHOR) if what == "AUTHOR": + logger.debug("Отправка уведомления автору о подписке") await notify_follower(follower=follower_dict, author=entity_id, action="follow") except Exception as exc: + logger.exception("Произошла ошибка в функции 'follow'") return {"error": str(exc)} + logger.debug(f"Функция 'follow' завершена успешно с результатом: {what.lower()}s={follows}") return {f"{what.lower()}s": follows} @mutation.field("unfollow") @login_required async def unfollow(_, info, what, slug): + logger.debug("Начало выполнения функции 'unfollow'") user_id = info.context.get("user_id") follower_dict = info.context.get("author") + logger.debug(f"user_id: {user_id}, follower_dict: {follower_dict}") + if not user_id or not follower_dict: + logger.warning("Неавторизованный доступ при попытке отписаться") return {"error": "unauthorized"} + follower_id = follower_dict.get("id") + logger.debug(f"follower_id: {follower_id}") entity_classes = { "AUTHOR": (Author, AuthorFollower, get_cached_follower_authors, cache_author), "TOPIC": (Topic, TopicFollower, get_cached_follower_topics, cache_topic), - "COMMUNITY": (Community, CommunityFollower, None, None), # No cache methods provided for community + "COMMUNITY": (Community, CommunityFollower, None, None), # Нет методов кэша для сообщества "SHOUT": ( Shout, ShoutReactionsFollower, None, - ), # No cache methods provided for shout + ), # Нет методов кэша для shout } if what not in entity_classes: + logger.error(f"Неверный тип для отписки: {what}") return {"error": "invalid unfollow type"} entity_class, follower_class, get_cached_follows_method, cache_method = entity_classes[what] entity_type = what.lower() + logger.debug(f"entity_class: {entity_class}, follower_class: {follower_class}, entity_type: {entity_type}") + entity_id = None follows = [] error = None try: + logger.debug("Попытка получить сущность из базы данных") with local_session() as session: entity = session.query(entity_class).filter(entity_class.slug == slug).first() + logger.debug(f"Полученная сущность: {entity}") if not entity: + logger.warning(f"{what.lower()} не найден по slug: {slug}") return {"error": f"{what.lower()} not found"} entity_id = entity.id + logger.debug(f"entity_id: {entity_id}") sub = ( session.query(follower_class) @@ -125,37 +160,60 @@ async def unfollow(_, info, what, slug): ) .first() ) + logger.debug(f"Найдена подписка для удаления: {sub}") if sub: session.delete(sub) session.commit() + logger.info(f"Пользователь {follower_id} отписался от {what.lower()} с ID {entity_id}") if cache_method: + logger.debug("Обновление кэша после отписки") await cache_method(entity.dict()) - if get_cached_follows_method: + logger.debug("Получение обновленных подписок из кэша") follows = await get_cached_follows_method(follower_id) + logger.debug(f"Текущие подписки: {follows}") if what == "AUTHOR": + logger.debug("Отправка уведомления автору об отписке") await notify_follower(follower=follower_dict, author=entity_id, action="unfollow") except Exception as exc: + logger.exception("Произошла ошибка в функции 'unfollow'") + import traceback + traceback.print_exc() return {"error": str(exc)} + logger.debug(f"Функция 'unfollow' завершена успешно с результатом: {entity_type}s={follows}, error={error}") return {f"{entity_type}s": follows, "error": error} @query.field("get_shout_followers") def get_shout_followers(_, _info, slug: str = "", shout_id: int | None = None) -> List[Author]: + logger.debug("Начало выполнения функции 'get_shout_followers'") followers = [] - with local_session() as session: - shout = None - if slug: - shout = session.query(Shout).filter(Shout.slug == slug).first() - elif shout_id: - shout = session.query(Shout).filter(Shout.id == shout_id).first() - if shout: - reactions = session.query(Reaction).filter(Reaction.shout == shout.id).all() - for r in reactions: - followers.append(r.created_by) + try: + with local_session() as session: + shout = None + if slug: + shout = session.query(Shout).filter(Shout.slug == slug).first() + logger.debug(f"Найден shout по slug: {slug} -> {shout}") + elif shout_id: + shout = session.query(Shout).filter(Shout.id == shout_id).first() + logger.debug(f"Найден shout по ID: {shout_id} -> {shout}") + if shout: + reactions = session.query(Reaction).filter(Reaction.shout == shout.id).all() + logger.debug(f"Полученные реакции для shout ID {shout.id}: {reactions}") + for r in reactions: + followers.append(r.created_by) + logger.debug(f"Добавлен follower: {r.created_by}") + + except Exception as _exc: + import traceback + traceback.print_exc() + logger.exception("Произошла ошибка в функции 'get_shout_followers'") + return [] + + logger.debug(f"Функция 'get_shout_followers' завершена с {len(followers)} подписчиками") return followers