1818 UserBadge ,
1919 UserProfile ,
2020)
21+ from .utils import analyze_contribution
22+
23+ # Default BACON rewards for different contribution types
24+ DEFAULT_BACON_REWARDS = {
25+ "Issue" : 5 ,
26+ "Post" : 10 ,
27+ "Hunt" : 15 ,
28+ "IpReport" : 3 ,
29+ "Organization" : 10 ,
30+ "ForumPost" : 2 ,
31+ "Bid" : 2 ,
32+ }
33+
34+
35+ def get_default_bacon_reward (instance , action_type ):
36+ """Get the default BACON reward for a given instance type"""
37+ model_name = instance ._meta .model_name .capitalize ()
38+ base_reward = DEFAULT_BACON_REWARDS .get (model_name , 1 )
39+
40+ # Add bonus for security-related content if applicable
41+ if hasattr (instance , "is_security" ) and getattr (instance , "is_security" , False ):
42+ base_reward += 3
43+
44+ return base_reward
2145
2246
2347def get_default_user ():
@@ -62,37 +86,70 @@ def create_activity(instance, action_type):
6286 )
6387
6488
65- def giveBacon (user , amt = 1 ):
66- # Check if the user already has a token record
89+ def giveBacon (user , instance = None , action_type = None , amt = None ):
90+ """
91+ Award BACON tokens to a user based on their contribution.
92+ If amt is provided, use that amount directly.
93+ Otherwise, analyze the contribution using AI to determine the amount.
94+ Falls back to default rewards if AI analysis fails.
95+ """
6796 if user is None or user .is_authenticated is False :
6897 return
69- token_earning , created = BaconEarning .objects .get_or_create (user = user )
7098
71- if created :
72- token_earning .tokens_earned = amt # Reward 10 tokens for completing the action (adjust as needed)
73- else :
74- token_earning .tokens_earned += amt # Add 10 tokens if the user already exists in the system
99+ token_earning , created = BaconEarning .objects .get_or_create (user = user )
75100
76- token_earning .save () # Save the updated record
101+ try :
102+ # If amount is specified, use it
103+ if amt is not None :
104+ reward_amount = amt
105+ # Otherwise analyze the contribution if we have an instance
106+ elif instance is not None and action_type is not None :
107+ try :
108+ reward_amount = analyze_contribution (instance , action_type )
109+ except Exception as e :
110+ # Fallback to default reward system
111+ reward_amount = get_default_bacon_reward (instance , action_type )
112+ else :
113+ reward_amount = 1 # Default minimum reward
114+
115+ # Ensure reward amount is within valid range (1-50)
116+ reward_amount = max (1 , min (50 , int (reward_amount )))
117+
118+ if created :
119+ token_earning .tokens_earned = reward_amount
120+ else :
121+ token_earning .tokens_earned += reward_amount
122+
123+ token_earning .save ()
124+ return reward_amount
125+
126+ except Exception as e :
127+ # If anything fails, ensure at least minimum reward is given
128+ if created :
129+ token_earning .tokens_earned = 1
130+ else :
131+ token_earning .tokens_earned += 1
132+ token_earning .save ()
133+ return 1
77134
78135
79136@receiver (post_save )
80137def handle_post_save (sender , instance , created , ** kwargs ):
81138 """Generic handler for post_save signal."""
82139 if sender == IpReport and created : # Track first IP report
83140 assign_first_action_badge (instance .user , "First IP Reported" )
84- giveBacon (instance .user )
141+ giveBacon (instance .user , instance = instance , action_type = "created" )
85142 create_activity (instance , "created" )
86143
87144 elif sender == Post and created : # Track first blog post
88145 assign_first_action_badge (instance .author , "First Blog Posted" )
89146 create_activity (instance , "created" )
90- giveBacon (instance .author , 5 ) # Reward for posting a blog
147+ giveBacon (instance .author , instance = instance , action_type = "created" )
91148
92149 elif sender == Issue and created : # Track first bug report
93150 assign_first_action_badge (instance .user , "First Bug Reported" )
94151 create_activity (instance , "created" )
95- giveBacon (instance .user , 5 ) # Reward for reporting a bug
152+ giveBacon (instance .user , instance = instance , action_type = "created" )
96153
97154 elif sender == Hunt and created : # Track first bug bounty
98155 # Attempt to get the user from Domain managers or Organization
@@ -108,17 +165,17 @@ def handle_post_save(sender, instance, created, **kwargs):
108165 if user :
109166 assign_first_action_badge (user , "First Bug Bounty" )
110167 create_activity (instance , "created" )
111- giveBacon (user , 5 ) # Reward for creating a bug bounty
168+ giveBacon (user , instance = instance , action_type = "created" )
112169
113170 elif sender == ForumPost and created : # Track first forum post
114171 assign_first_action_badge (instance .user , "First Forum Post" )
115172 create_activity (instance , "created" )
116- giveBacon (instance .user , 2 ) # Reward for posting in forum
173+ giveBacon (instance .user , instance = instance , action_type = "created" )
117174
118175 elif sender == Bid and created : # Track first bid placed
119176 assign_first_action_badge (instance .user , "First Bid Placed" )
120177 create_activity (instance , "placed" )
121- giveBacon (instance .user , 2 ) # Reward for placing a bid
178+ giveBacon (instance .user , instance = instance , action_type = "placed" )
122179
123180 elif sender is User and created : # Handle user sign-up
124181 Activity .objects .create (
@@ -158,9 +215,9 @@ def update_user_streak(sender, instance, created, **kwargs):
158215def handle_organization_creation (sender , instance , created , ** kwargs ):
159216 """Give bacon to user when they create an organization"""
160217 if created and instance .admin :
161- # Give 10 bacon tokens for creating an organization
162- giveBacon (instance .admin , 10 )
163- # Create an activity for the organization creation
218+ # Create an activity first so it's included in the AI analysis
164219 create_activity (instance , "created" )
220+ # Give bacon tokens using AI analysis or fallback to default (10)
221+ giveBacon (instance .admin , instance = instance , action_type = "created" )
165222 # Give first organization badge
166223 assign_first_action_badge (instance .admin , "First Organization Created" )
0 commit comments