|
17 | 17 | def setup_periodic_tasks(sender, **kwargs): |
18 | 18 | sender.add_periodic_task(60, update_offline_users.s(), name="Update online users every minute") |
19 | 19 | sender.add_periodic_task(3600, update_heat_scores.s(), name="Update heat scores every hour") |
| 20 | + sender.add_periodic_task(60, update_user_recommendations.s(), name="Update user recommendations every minute") |
20 | 21 |
|
21 | 22 |
|
22 | 23 | @celery.task |
@@ -92,3 +93,60 @@ def update_offline_users(): |
92 | 93 | return "Updated online status for {} users. {} passed offline and {} passed or stayed online.".format( |
93 | 94 | count, offline_count, online_count |
94 | 95 | ) |
| 96 | + |
| 97 | + |
| 98 | +def default_date_converter(o): |
| 99 | + if isinstance(o, datetime.datetime): |
| 100 | + return o.__str__() |
| 101 | + |
| 102 | + |
| 103 | +@celery.task |
| 104 | +def update_user_recommendations(): |
| 105 | + today = datetime.datetime.utcnow() |
| 106 | + count = 0 |
| 107 | + for user_to_update in User.select_all(): |
| 108 | + count += 1 |
| 109 | + user_to_update_recommendations = [] |
| 110 | + |
| 111 | + user_to_update_age = ( |
| 112 | + today.year |
| 113 | + - user_to_update.birthdate.year |
| 114 | + - ((today.month, today.day) < (user_to_update.birthdate.month, user_to_update.birthdate.day)) |
| 115 | + ) |
| 116 | + user_to_update_tags = [t.name for t in user_to_update.get_tags()] |
| 117 | + |
| 118 | + inverted_gender = _get_inverted_gender(user_to_update.gender, user_to_update.orientation) |
| 119 | + |
| 120 | + for user in User.get_multis(orientation=user_to_update.orientation, gender=inverted_gender): |
| 121 | + if user.id == user_to_update.id: |
| 122 | + continue |
| 123 | + score = 0 |
| 124 | + |
| 125 | + distance = _get_distance(user_to_update.geohash, user.geohash) |
| 126 | + score -= distance |
| 127 | + |
| 128 | + user_age = ( |
| 129 | + today.year |
| 130 | + - user.birthdate.year |
| 131 | + - ((today.month, today.day) < (user.birthdate.month, user.birthdate.day)) |
| 132 | + ) |
| 133 | + age_diff = _get_age_diff(user_to_update_age, user_age) |
| 134 | + score -= age_diff |
| 135 | + |
| 136 | + user_tags = [t.name for t in user.get_tags()] |
| 137 | + common_tags = _get_common_tags(user_to_update_tags, user_tags) |
| 138 | + score += len(common_tags) * 2 |
| 139 | + |
| 140 | + score += user.heat_score |
| 141 | + |
| 142 | + d = {"score": score, "common_tags": common_tags, "distance": distance} |
| 143 | + d.update(user.to_dict()) |
| 144 | + user_to_update_recommendations.append(d) |
| 145 | + user_to_update_recommendations_sorted = sorted( |
| 146 | + user_to_update_recommendations, key=lambda x: x["score"], reverse=True |
| 147 | + ) |
| 148 | + redis.set( |
| 149 | + f"user_recommendations:{str(user_to_update.id)}", |
| 150 | + json.dumps(user_to_update_recommendations_sorted, default=default_date_converter), |
| 151 | + ) |
| 152 | + return f"Successfully updated recommendations for {count} users." |
0 commit comments