Skip to content

Commit 9ffd1d2

Browse files
committed
Updated recommendations
1 parent 2a7cf50 commit 9ffd1d2

File tree

3 files changed

+72
-63
lines changed

3 files changed

+72
-63
lines changed

backend/PyMatcha/routes/api/recommendations.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
from flask_jwt_extended import current_user
2323
from flask_jwt_extended import jwt_required
2424
from PyMatcha import redis
25-
from PyMatcha.utils.errors import NotFoundError
25+
from PyMatcha.utils.errors import BadRequestError
26+
from PyMatcha.utils.recommendations import create_user_recommendations
2627
from PyMatcha.utils.success import SuccessOutput
2728

2829
recommendations_bp = Blueprint("recommendations", __name__)
@@ -33,5 +34,8 @@
3334
def get_recommendations():
3435
recommendations = redis.get(f"user_recommendations:{str(current_user.id)}")
3536
if not recommendations:
36-
raise NotFoundError("Recommendations not calculated yet", "Please come back later")
37+
create_user_recommendations(current_user)
38+
recommendations = redis.get(f"user_recommendations:{str(current_user.id)}")
39+
if not recommendations:
40+
raise BadRequestError("User recommendations cannot be calculated")
3741
return SuccessOutput("recommendations", json.loads(recommendations))
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import datetime
2+
import json
3+
4+
from PyMatcha import redis
5+
from PyMatcha.utils.match_score import _get_age_diff
6+
from PyMatcha.utils.match_score import _get_common_tags
7+
from PyMatcha.utils.match_score import _get_distance
8+
from PyMatcha.utils.match_score import _get_gender_query
9+
10+
11+
def default_date_converter(o):
12+
if isinstance(o, datetime.datetime):
13+
return o.__str__()
14+
15+
16+
def create_user_recommendations(user_to_update):
17+
today = datetime.datetime.utcnow()
18+
user_to_update_recommendations = []
19+
if not user_to_update.birthdate:
20+
return
21+
if not user_to_update.geohash:
22+
return
23+
24+
user_to_update_age = (
25+
today.year
26+
- user_to_update.birthdate.year
27+
- ((today.month, today.day) < (user_to_update.birthdate.month, user_to_update.birthdate.day))
28+
)
29+
user_to_update_tags = [t.name for t in user_to_update.get_tags()]
30+
31+
query = _get_gender_query(user_to_update.orientation, user_to_update.gender)
32+
33+
for user in query:
34+
if user.id == user_to_update.id:
35+
continue
36+
score = 0
37+
38+
distance = _get_distance(user_to_update.geohash, user.geohash)
39+
if distance:
40+
score -= distance
41+
42+
user_age = (
43+
today.year - user.birthdate.year - ((today.month, today.day) < (user.birthdate.month, user.birthdate.day))
44+
)
45+
age_diff = _get_age_diff(user_to_update_age, user_age)
46+
score -= age_diff
47+
48+
user_tags = [t.name for t in user.get_tags()]
49+
common_tags = _get_common_tags(user_to_update_tags, user_tags)
50+
score += len(common_tags) * 2
51+
52+
score += user.heat_score
53+
54+
d = {"score": score, "common_tags": common_tags, "distance": distance}
55+
d.update(user.to_dict())
56+
user_to_update_recommendations.append(d)
57+
user_to_update_recommendations_sorted = sorted(
58+
user_to_update_recommendations, key=lambda x: x["score"], reverse=True
59+
)
60+
redis.set(
61+
f"user_recommendations:{str(user_to_update.id)}",
62+
json.dumps(user_to_update_recommendations_sorted, default=default_date_converter),
63+
)
64+
redis.expire(f"user_recommendations:{str(user_to_update.id)}", 3600)

backend/PyMatcha/utils/tasks.py

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
import datetime
2-
import json
32
import logging
43
from math import ceil
54

65
from PyMatcha import celery
76
from PyMatcha import redis
87
from PyMatcha.models.message import Message
98
from PyMatcha.models.user import User
10-
from PyMatcha.utils.match_score import _get_age_diff
11-
from PyMatcha.utils.match_score import _get_common_tags
12-
from PyMatcha.utils.match_score import _get_distance
13-
from PyMatcha.utils.match_score import _get_gender_query
9+
from PyMatcha.utils.recommendations import create_user_recommendations
1410

1511
BASE_HEAT_SCORE = 30
1612
LIKES_MULTIPLIER = 2
@@ -102,66 +98,11 @@ def update_offline_users():
10298
)
10399

104100

105-
def default_date_converter(o):
106-
if isinstance(o, datetime.datetime):
107-
return o.__str__()
108-
109-
110101
@celery.task
111102
def update_user_recommendations():
112-
today = datetime.datetime.utcnow()
113103
count = 0
114104
for user_to_update in User.select_all():
115-
count += 1
116-
user_to_update_recommendations = []
117-
if not user_to_update.birthdate:
118-
continue
119-
if not user_to_update.geohash:
120-
continue
121-
122-
user_to_update_age = (
123-
today.year
124-
- user_to_update.birthdate.year
125-
- ((today.month, today.day) < (user_to_update.birthdate.month, user_to_update.birthdate.day))
126-
)
127-
user_to_update_tags = [t.name for t in user_to_update.get_tags()]
128-
129-
query = _get_gender_query(user_to_update.orientation, user_to_update.gender)
130-
131-
for user in query:
132-
if user.id == user_to_update.id:
133-
continue
134-
score = 0
135-
136-
distance = _get_distance(user_to_update.geohash, user.geohash)
137-
if distance:
138-
score -= distance
139-
140-
user_age = (
141-
today.year
142-
- user.birthdate.year
143-
- ((today.month, today.day) < (user.birthdate.month, user.birthdate.day))
144-
)
145-
age_diff = _get_age_diff(user_to_update_age, user_age)
146-
score -= age_diff
147-
148-
user_tags = [t.name for t in user.get_tags()]
149-
common_tags = _get_common_tags(user_to_update_tags, user_tags)
150-
score += len(common_tags) * 2
151-
152-
score += user.heat_score
153-
154-
d = {"score": score, "common_tags": common_tags, "distance": distance}
155-
d.update(user.to_dict())
156-
user_to_update_recommendations.append(d)
157-
user_to_update_recommendations_sorted = sorted(
158-
user_to_update_recommendations, key=lambda x: x["score"], reverse=True
159-
)
160-
redis.set(
161-
f"user_recommendations:{str(user_to_update.id)}",
162-
json.dumps(user_to_update_recommendations_sorted, default=default_date_converter),
163-
)
164-
redis.expire(f"user_recommendations:{str(user_to_update.id)}", 3600)
105+
create_user_recommendations(user_to_update)
165106
return f"Successfully updated recommendations for {count} users."
166107

167108

0 commit comments

Comments
 (0)