docs-restruct

This commit is contained in:
2025-10-02 01:16:14 +03:00
parent 31cf6b6961
commit 4038c5dbf5
3 changed files with 190 additions and 19 deletions

View File

@@ -143,27 +143,29 @@ def is_featured_author(session: Session, author_id: int) -> bool:
def check_to_feature(session: Session, approver_id: int, reaction: dict) -> bool:
"""
Make a shout featured if it receives more than 4 votes from authors.
Make a shout featured if it receives more than 4 votes from featured authors.
:param session: Database session.
:param approver_id: Approver author ID.
:param reaction: Reaction object.
:return: True if shout should be featured, else False.
"""
is_positive_kind = reaction.get("kind") == ReactionKind.LIKE.value
# 🔧 Проверяем любую положительную реакцию (LIKE, ACCEPT, PROOF), не только LIKE
is_positive_kind = reaction.get("kind") in POSITIVE_REACTIONS
if not reaction.get("reply_to") and is_positive_kind:
# Проверяем, не содержит ли пост более 20% дизлайков
# Если да, то не должен быть featured независимо от количества лайков
if check_to_unfeature(session, reaction):
return False
# Собираем всех авторов, поставивших лайк
# Собираем всех авторов, поставивших положительную реакцию
author_approvers = set()
reacted_readers = (
session.query(Reaction.created_by)
.where(
Reaction.shout == reaction.get("shout"),
Reaction.kind.in_(POSITIVE_REACTIONS),
Reaction.reply_to.is_(None), # не реакция на комментарий
# Рейтинги (LIKE, DISLIKE) физически удаляются, поэтому фильтр deleted_at не нужен
)
.distinct()
@@ -189,7 +191,7 @@ def check_to_feature(session: Session, approver_id: int, reaction: dict) -> bool
def check_to_unfeature(session: Session, reaction: dict) -> bool:
"""
Unfeature a shout if:
1. Less than 5 positive votes, OR
1. Less than 5 positive votes from featured authors, OR
2. 20% or more of reactions are negative.
:param session: Database session.
@@ -199,18 +201,8 @@ def check_to_unfeature(session: Session, reaction: dict) -> bool:
if not reaction.get("reply_to"):
shout_id = reaction.get("shout")
# Проверяем соотношение дизлайков, даже если текущая реакция не дизлайк
total_reactions = (
session.query(Reaction)
.where(
Reaction.shout == shout_id,
Reaction.reply_to.is_(None),
Reaction.kind.in_(RATING_REACTIONS),
# Рейтинги физически удаляются при удалении, поэтому фильтр deleted_at не нужен
)
.count()
)
# 🔧 Считаем все рейтинговые реакции (положительные + отрицательные)
# Используем POSITIVE_REACTIONS + NEGATIVE_REACTIONS вместо только RATING_REACTIONS
positive_reactions = (
session.query(Reaction)
.where(
@@ -233,9 +225,13 @@ def check_to_unfeature(session: Session, reaction: dict) -> bool:
.count()
)
total_reactions = positive_reactions + negative_reactions
# Условие 1: Меньше 5 голосов "за"
if positive_reactions < 5:
logger.debug(f"Публикация {shout_id}: {positive_reactions} лайков (меньше 5) - должна быть unfeatured")
logger.debug(
f"Публикация {shout_id}: {positive_reactions} положительных реакций (меньше 5) - должна быть unfeatured"
)
return True
# Условие 2: Проверяем, составляют ли отрицательные реакции 20% или более от всех реакций
@@ -256,6 +252,8 @@ async def set_featured(session: Session, shout_id: int) -> None:
:param session: Database session.
:param shout_id: Shout ID.
"""
from cache.revalidator import revalidation_manager
s = session.query(Shout).where(Shout.id == shout_id).first()
if s:
current_time = int(time.time())
@@ -267,6 +265,17 @@ async def set_featured(session: Session, shout_id: int) -> None:
session.add(s)
session.commit()
# 🔧 Ревалидация кеша публикации и связанных сущностей
revalidation_manager.mark_for_revalidation(shout_id, "shouts")
# Ревалидируем авторов публикации
for author in s.authors:
revalidation_manager.mark_for_revalidation(author.id, "authors")
# Ревалидируем темы публикации
for topic in s.topics:
revalidation_manager.mark_for_revalidation(topic.id, "topics")
logger.info(f"Публикация {shout_id} получила статус featured, кеш помечен для ревалидации")
def set_unfeatured(session: Session, shout_id: int) -> None:
"""
@@ -275,9 +284,27 @@ def set_unfeatured(session: Session, shout_id: int) -> None:
:param session: Database session.
:param shout_id: Shout ID.
"""
from cache.revalidator import revalidation_manager
# Получаем публикацию для доступа к авторам и темам
shout = session.query(Shout).where(Shout.id == shout_id).first()
if not shout:
return
session.query(Shout).where(Shout.id == shout_id).update({"featured_at": None})
session.commit()
# 🔧 Ревалидация кеша публикации и связанных сущностей
revalidation_manager.mark_for_revalidation(shout_id, "shouts")
# Ревалидируем авторов публикации
for author in shout.authors:
revalidation_manager.mark_for_revalidation(author.id, "authors")
# Ревалидируем темы публикации
for topic in shout.topics:
revalidation_manager.mark_for_revalidation(topic.id, "topics")
logger.info(f"Публикация {shout_id} потеряла статус featured, кеш помечен для ревалидации")
async def _create_reaction(session: Session, shout_id: int, is_author: bool, author_id: int, reaction: dict) -> dict:
"""