1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# 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
)