# coding=utf-8 from __future__ import absolute_import from celery import shared_task from django.db import transaction from social.models import SocialInfo, Feed, BigVMailBox from social.types import in_feed_reason_convert_for_fan from gm_types.gaia import ( FEED_ITEM_TYPE, IN_FEED_REASON ) from social.utils import ts_now_as_score @shared_task @transaction.atomic def create_feed( uid, follow_uid, topic_id, feed_reason, action_item_id=None, score=None, push_to_fans=True, tag_id=None, item_type=FEED_ITEM_TYPE.TOPIC): """create a new feed. NOTE: if user is a big_v, we should set push_to_fans as False args: push_to_fans: if this feed should be pushed to fans """ push_to_fans_only = False if feed_reason in ( IN_FEED_REASON.MY_TOPIC_VOTE, IN_FEED_REASON.MY_TOPIC_REPLY, IN_FEED_REASON.MY_DIARY_VOTE, IN_FEED_REASON.MY_DIARY_REPLY ): # dont trigger post save if user vote or reply a topic # dont push these two types into user's own feed push_to_fans_only = True # return fast if this is true if push_to_fans_only and not push_to_fans: return if not score: score = ts_now_as_score() if not push_to_fans_only: f, created = Feed.get_or_create( uid=uid, item_id=topic_id, item_type=item_type, feed_reason=feed_reason, score=score, ) if created or ( feed_reason not in (IN_FEED_REASON.FOLLOW_TAG, IN_FEED_REASON.FOLLOW_TAG_DIARY, IN_FEED_REASON.RECOMMEND_TOPIC, IN_FEED_REASON.FOLLOW_TAG_COMMENT, ) and feed_reason == f.feed_reason): f.reason_count += 1 f.save() SocialInfo.push_to_feed(f, score, tag_id or action_item_id) # if user is a bigv dont add feeditems for fans # cache it in a mailbox, it's fans will pull from this mailbox # 5.9 add two more reason to feed if created and SocialInfo.is_big_v(uid) and feed_reason in ( IN_FEED_REASON.MY_TOPIC_VOTE, IN_FEED_REASON.MY_TOPIC_REPLY, IN_FEED_REASON.MY_TOPIC, IN_FEED_REASON.MY_DIARY_VOTE, IN_FEED_REASON.MY_DIARY_REPLY ): mailbox = BigVMailBox(uid) mailbox.push(f.id) push_to_fans = False if SocialInfo.is_big_v(uid): return # chcek if we should push feeds to fans' feed if not push_to_fans: return # only some of the in_feed_reason can be converted feed_reason_for_fan = in_feed_reason_convert_for_fan(feed_reason) if not feed_reason_for_fan: return add_feed_for_fans(uid, topic_id, feed_reason_for_fan, action_item_id, score, item_type) @shared_task def add_feed_for_fans(uid, topic_id, feed_reason, action_item_id=None, score=None, item_type=FEED_ITEM_TYPE.TOPIC): """add feeditem record, which wil call a async task to update fans' feeds.""" si = SocialInfo.social_info(uid) for fan_uid in si.get_fans_iterator(): create_feed( fan_uid, si.uid, topic_id, feed_reason, action_item_id, push_to_fans=False, # dont broadcast to fan's fans score=score, item_type=item_type )