import logging from django.dispatch import receiver from pingcap_sso.discourse import signals as discourse_signals from pingcap_sso.discourse.consts import QA_CATEGORIES, QA_FEEDBACK_CATEGORIES from pingcap_sso.discourse.models import DiscoursePost, DiscourseTopic from pingcap_sso.discourse.lib import is_topic_solved from pingcap_sso.models import UserAwardedPoint from pingcap_sso.lib.discourse import _get_sso_user from pingcap_sso.lib.points import ( AWARD_ASKTUG_NEW_POST, AWARD_ASKTUG_NEW_TOPIC, AWARD_ASKTUG_PINNED, AWARD_ASKTUG_WAS_LIKED, AWARD_ASKTUG_SOLVED, AWARD_ASKTUG_MARK_SOLVED, award_points_by_type, revoke_award_by_type_without_limits ) logger = logging.getLogger(__name__) @receiver( discourse_signals.post_created, dispatch_uid='_award_user_who_answer_questions_in_asktug' ) def _award_user_who_answer_questions_in_asktug(sender, post, **kwargs): post_id = post['id'] discourse_post = DiscoursePost.objects.select_related('topic').get(id=post_id) post_type = discourse_post.post_type action_code = discourse_post.action_code user = _get_sso_user(discourse_post.user) # It means topic_created, just skip if discourse_post.post_number == 1: return # It may be a robot if not user: return # regular post if post_type == 1 and discourse_post.topic.category_id in QA_CATEGORIES: if is_topic_solved(discourse_post.topic_id): logger.info( f'skip awarding points for post {discourse_post.id} ' f'because topic {discourse_post.topic_id} is solved' ) return award_points_by_type( user, AWARD_ASKTUG_NEW_POST, discourse_topic_id=discourse_post.topic_id, discourse_post_id=discourse_post.id) # action post which means topic was pinned elif post_type == 3 and action_code in ( 'pinned.enabled', 'pinned_globally.enabled', 'banner.enabled'): topic_author = _get_sso_user(discourse_post.topic.user) if topic_author: award_points_by_type( topic_author, AWARD_ASKTUG_PINNED, discourse_topic_id=discourse_post.topic_id, discourse_post_id=discourse_post.id) else: pass @receiver( discourse_signals.topic_created, dispatch_uid='_award_user_who_ask_questions_in_asktug' ) def _award_user_who_ask_questions_in_asktug(sender, topic, **kwargs): topic_id = topic['id'] discourse_topic = DiscourseTopic.objects.get(id=topic_id) user = _get_sso_user(discourse_topic.user) # It may be a robot if not user: return if discourse_topic.category_id in QA_CATEGORIES: award_points_by_type( user, AWARD_ASKTUG_NEW_TOPIC, discourse_topic_id=discourse_topic.id ) @receiver( discourse_signals.post_destroyed, dispatch_uid='_revoke_points_after_post_destroyed' ) def _revoke_points_after_post_destroyed(sender, post, **kwargs): post_id = post['id'] discourse_post = DiscoursePost.objects.select_related('topic').get(id=post_id) user = _get_sso_user(discourse_post.user) exists_awarded_qs = UserAwardedPoint.objects.filter( discourse_post_id=post_id, award_type=AWARD_ASKTUG_NEW_POST, revoked_by__isnull=True) if exists_awarded_qs.exists(): award_record = revoke_award_by_type_without_limits( user, AWARD_ASKTUG_NEW_POST, discourse_topic_id=discourse_post.topic_id, discourse_post_id=discourse_post.id) exists_awarded_qs.update(revoked_by=award_record) @receiver( discourse_signals.topic_destroyed, dispatch_uid='_revoke_points_after_topic_destroyed' ) def _revoke_points_after_topic_destroyed(sender, topic, **kwargs): topic_id = topic['id'] discourse_topic = DiscourseTopic.objects.get(id=topic_id) user = _get_sso_user(discourse_topic.user) exists_awarded_qs = UserAwardedPoint.objects.filter( discourse_topic_id=topic_id, award_type=AWARD_ASKTUG_NEW_TOPIC, revoked_by__isnull=True) if exists_awarded_qs.exists(): award_record = revoke_award_by_type_without_limits( user, AWARD_ASKTUG_NEW_TOPIC, discourse_topic_id=discourse_topic.id) exists_awarded_qs.update(revoked_by=award_record) @receiver( discourse_signals.post_was_liked, dispatch_uid='_award_user_when_post_was_liked' ) def _award_user_when_post_was_liked( sender, topic_id, post_id, topic_author, post_author, acting_user, user_action_id, **kwargs): if post_author != acting_user: if post_author: award_points_by_type( post_author, AWARD_ASKTUG_WAS_LIKED, discourse_topic_id=topic_id, discourse_post_id=post_id, discourse_user_action_id=user_action_id ) @receiver( discourse_signals.topic_solved, dispatch_uid='_award_user_when_topic_solved' ) def _award_user_when_topic_solved( sender, topic_id, post_id, topic_author, post_author, acting_user, user_action_id, **kwargs): discourse_topic = DiscourseTopic.objects.get(id=topic_id) if post_author and post_author != acting_user and discourse_topic.category_id in QA_CATEGORIES: award_points_by_type( post_author, AWARD_ASKTUG_SOLVED, discourse_topic_id=topic_id, discourse_post_id=post_id, discourse_user_action_id=user_action_id ) if topic_author and topic_author == acting_user and post_author != acting_user and\ discourse_topic.category_id in QA_FEEDBACK_CATEGORIES: award_points_by_type( topic_author, AWARD_ASKTUG_MARK_SOLVED, discourse_topic_id=topic_id, discourse_post_id=post_id, discourse_user_action_id=user_action_id )