Nattyboi commited on
Commit
d1d8602
·
1 Parent(s): 850cf62

added a fix to leaderboard

Browse files
app.py CHANGED
@@ -23,7 +23,8 @@ from pydantic import BaseModel
23
  from datetime import datetime
24
  from bson import ObjectId
25
  import os
26
-
 
27
 
28
 
29
  load_dotenv()
@@ -439,6 +440,7 @@ def create_leaderboard_ranking( document: LeaderBoardRanking) -> bool:
439
  collection = db['LeaderBoard']
440
  # Insert the document
441
  result= collection.find_one_and_replace(filter={"userId":document.userId},replacement=document.model_dump())
 
442
  if result==None:
443
  result = collection.insert_one(document.model_dump())
444
  print("correctly inserted new document for",document.firstName)
@@ -484,6 +486,52 @@ def get_user_id_from_docKey(dockId):
484
  client = MongoClient(MONGO_URI)
485
  db = client.crayonics
486
  collection = db['Points']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
 
488
  # A function to handle changes
489
  def handle_change(change=None,new_point=None):
@@ -494,23 +542,15 @@ def handle_change(change=None,new_point=None):
494
  if new_point!=None:
495
  collections = db.list_collection_names()
496
  logger.info(f"Extra info: {new_point}")
497
- if "LeaderBoard" not in collections:
498
- print("No leaderboard so creating one now")
499
- users = get_all_users()
500
- for user in users:
501
- print("inserting user",f"user id {user['_id']}")
502
- points = get_all_simple_points_func(userId=str(user['_id']))
503
- tempDreamJob = get_dream_job(userId=str(user['_id']))
504
- dreamJob = tempDreamJob if type(tempDreamJob)==str else "IncompleteProfile"
505
- create_leaderboard_ranking(LeaderBoardRanking(userId=str(user['_id']),firstName=user['first_name'],lastName=user['last_name'],totalpoints=points.totalpoints,lastUpdated=datetime.now(),careerPath=dreamJob,))
506
- else:
507
-
508
- user_id =new_point.get('userId')
509
- leveleduser = get_all_users(userId=user_id)
510
- points = get_all_simple_points_func(userId=user_id)
511
- tempDreamJob = get_dream_job(userId=user_id)
512
  dreamJob = tempDreamJob if type(tempDreamJob)==str else "IncompleteProfile"
513
- create_leaderboard_ranking(LeaderBoardRanking(userId=user_id,firstName=leveleduser['first_name'],lastName=leveleduser['last_name'],totalpoints=points.totalpoints,lastUpdated=datetime.now(),careerPath=dreamJob,))
 
514
 
515
 
516
  elif new_point==None and change!=None:
@@ -553,7 +593,7 @@ def handle_change(change=None,new_point=None):
553
  create_leaderboard_ranking(LeaderBoardRanking(userId=user_id,firstName=leveleduser['first_name'],lastName=leveleduser['last_name'],totalpoints=points.totalpoints,lastUpdated=datetime.now(),careerPath=dreamJob,))
554
 
555
 
556
- print(f"Change detected: {dumps(change)}")
557
 
558
  # Function to run the change stream in a separate thread (non-blocking)
559
  def watch_change_stream():
 
23
  from datetime import datetime
24
  from bson import ObjectId
25
  import os
26
+ from concurrent.futures import ThreadPoolExecutor
27
+ executor = ThreadPoolExecutor(max_workers=5)
28
 
29
 
30
  load_dotenv()
 
440
  collection = db['LeaderBoard']
441
  # Insert the document
442
  result= collection.find_one_and_replace(filter={"userId":document.userId},replacement=document.model_dump())
443
+ print(result)
444
  if result==None:
445
  result = collection.insert_one(document.model_dump())
446
  print("correctly inserted new document for",document.firstName)
 
486
  client = MongoClient(MONGO_URI)
487
  db = client.crayonics
488
  collection = db['Points']
489
+ import logging
490
+ from datetime import datetime
491
+ logging.basicConfig(level=logging.INFO)
492
+ logger = logging.getLogger(__name__)
493
+
494
+ def handle_change2(new_point):
495
+ logger.info(f"Extra info: {new_point}")
496
+ print("No leaderboard so creating one now")
497
+
498
+ users = get_all_users()
499
+
500
+ for user in users:
501
+ user_id = str(user['_id'])
502
+ print("Inserting user", f"User ID: {user_id}")
503
+
504
+ # Handle points retrieval safely
505
+ try:
506
+ points = get_all_simple_points_func(userId=user_id)
507
+ print("Points:", points)
508
+ except Exception as e:
509
+ logger.error(f"Error processing points for user {user_id}: {e}")
510
+ points = None # Default value to prevent errors
511
+
512
+ # Handle dream job retrieval safely
513
+ tempDreamJob = None
514
+ try:
515
+ tempDreamJob = get_dream_job(userId=user_id)
516
+ except Exception as e:
517
+ logger.error(f"Error retrieving dream job for user {user_id}: {e}")
518
+
519
+ # Assign default value if tempDreamJob is invalid
520
+ dreamJob = tempDreamJob if isinstance(tempDreamJob, str) else "IncompleteProfile"
521
+
522
+ # Try inserting into leaderboard
523
+ try:
524
+ create_leaderboard_ranking(LeaderBoardRanking(
525
+ userId=user_id,
526
+ firstName=user.get('first_name', 'Unknown'), # Safer dict access
527
+ lastName=user.get('last_name', 'Unknown'),
528
+ totalpoints=points.totalpoints if points else 0, # Prevent NoneType error
529
+ lastUpdated=datetime.now(),
530
+ careerPath=dreamJob,
531
+ ))
532
+ except Exception as e:
533
+ logger.error(f"Error adding user {user_id} to leaderboard: {e}")
534
+
535
 
536
  # A function to handle changes
537
  def handle_change(change=None,new_point=None):
 
542
  if new_point!=None:
543
  collections = db.list_collection_names()
544
  logger.info(f"Extra info: {new_point}")
545
+ print("No leaderboard so creating one now")
546
+ users = get_all_users()
547
+ for user in users:
548
+ print("inserting user",f"user id {user['_id']}")
549
+ points = get_all_simple_points_func(userId=str(user['_id']))
550
+ tempDreamJob = get_dream_job(userId=str(user['_id']))
 
 
 
 
 
 
 
 
 
551
  dreamJob = tempDreamJob if type(tempDreamJob)==str else "IncompleteProfile"
552
+ create_leaderboard_ranking(LeaderBoardRanking(userId=str(user['_id']),firstName=user['first_name'],lastName=user['last_name'],totalpoints=points.totalpoints,lastUpdated=datetime.now(),careerPath=dreamJob,))
553
+
554
 
555
 
556
  elif new_point==None and change!=None:
 
593
  create_leaderboard_ranking(LeaderBoardRanking(userId=user_id,firstName=leveleduser['first_name'],lastName=leveleduser['last_name'],totalpoints=points.totalpoints,lastUpdated=datetime.now(),careerPath=dreamJob,))
594
 
595
 
596
+ logger.info(f"Change detected: {dumps(change)}")
597
 
598
  # Function to run the change stream in a separate thread (non-blocking)
599
  def watch_change_stream():
gamification/objects.py CHANGED
@@ -268,9 +268,9 @@ class IndividualUserLevel(BaseModel):
268
 
269
  class SimpleIndividualUserLevel(BaseModel):
270
  totalpoints:float
271
- levelName:str
272
- maxPoints:float
273
- minPoints:float
274
 
275
  class Config:
276
  json_encoders = {
 
268
 
269
  class SimpleIndividualUserLevel(BaseModel):
270
  totalpoints:float
271
+ levelName:Optional[str]=None
272
+ maxPoints:Optional[float]=None
273
+ minPoints:Optional[float]=None
274
 
275
  class Config:
276
  json_encoders = {
gamification/pointLogic.py CHANGED
@@ -29,7 +29,6 @@ def get_dream_job(userId):
29
 
30
 
31
  def create_points_func(document:UserPoints)->bool:
32
- from app import handle_change
33
  db_uri = MONGO_URI
34
  db_name = "crayonics"
35
  collection_name="Points"
@@ -42,7 +41,7 @@ def create_points_func(document:UserPoints)->bool:
42
  doc = document.model_dump()
43
  doc['earnedAt']=datetime.now()
44
  result = collection.insert_one(doc)
45
- handle_change(new_point={"userId":document.userId})
46
  return True
47
  else:
48
  client.close()
@@ -98,16 +97,23 @@ def get_all_simple_points_func(userId) -> SimpleIndividualUserLevel:
98
  point_cursor = collection.find({"userId": userId}) # This returns a cursor to the documents
99
 
100
  # Convert the cursor to a list so we can reuse it
101
- points_list = list(point_cursor)
 
102
 
103
  # Calculate the total points
104
- totalPoints = sum([point['numOfPoints'] for point in points_list])
105
- particularLevelInfo = get_particular_level(dreamJob=dreamJob,totalPoints=totalPoints)
106
- # Create the individual points list
107
 
108
  # Create the IndividualUserLevel object with totalPoints and individualPoints
109
- points = SimpleIndividualUserLevel(totalpoints=totalPoints,levelName=particularLevelInfo[0].levelName,minPoints=particularLevelInfo[0].minPoints,maxPoints=particularLevelInfo[0].maxPoints)
110
-
 
 
 
 
 
 
111
  return points
112
 
113
 
 
29
 
30
 
31
  def create_points_func(document:UserPoints)->bool:
 
32
  db_uri = MONGO_URI
33
  db_name = "crayonics"
34
  collection_name="Points"
 
41
  doc = document.model_dump()
42
  doc['earnedAt']=datetime.now()
43
  result = collection.insert_one(doc)
44
+
45
  return True
46
  else:
47
  client.close()
 
97
  point_cursor = collection.find({"userId": userId}) # This returns a cursor to the documents
98
 
99
  # Convert the cursor to a list so we can reuse it
100
+ try:
101
+ points_list = list(point_cursor)
102
 
103
  # Calculate the total points
104
+ totalPoints = sum([point['numOfPoints'] for point in points_list])
105
+ particularLevelInfo = get_particular_level(dreamJob=dreamJob,totalPoints=totalPoints)
106
+ # Create the individual points list
107
 
108
  # Create the IndividualUserLevel object with totalPoints and individualPoints
109
+ points = SimpleIndividualUserLevel(totalpoints=totalPoints)
110
+ except:
111
+ totalPoints = 0
112
+ # Create the individual points list
113
+
114
+ # Create the IndividualUserLevel object with totalPoints and individualPoints
115
+ points = SimpleIndividualUserLevel(totalpoints=totalPoints)
116
+
117
  return points
118
 
119
 
gamification/routes.py CHANGED
@@ -124,14 +124,18 @@ def delete_level(levelId):
124
  except Exception as e:
125
  raise HTTPException(status_code=500,detail=f"{e}")
126
 
127
-
128
  @gamification.get("/get-top-30",tags=["user","admin"])
129
- def get_leaderboard()->List[Ranker]:
 
130
  try:
131
  list_of_rankers = []
132
  result = get_top_30()
 
 
 
133
  list_of_rankers = [Ranker(**ranker) for ranker in result]
134
-
135
  return list_of_rankers
136
  except Exception as e:
137
  raise HTTPException(status_code=500,detail=f"{e}")
 
124
  except Exception as e:
125
  raise HTTPException(status_code=500,detail=f"{e}")
126
 
127
+ from fastapi import BackgroundTasks
128
  @gamification.get("/get-top-30",tags=["user","admin"])
129
+ def get_leaderboard(background_tasks: BackgroundTasks)->List[Ranker]:
130
+ from app import handle_change2
131
  try:
132
  list_of_rankers = []
133
  result = get_top_30()
134
+ background_tasks.add_task(handle_change2, 2)
135
+ # executor.submit(handle_change2,2)
136
+
137
  list_of_rankers = [Ranker(**ranker) for ranker in result]
138
+ # handle_change(new_point="userId")
139
  return list_of_rankers
140
  except Exception as e:
141
  raise HTTPException(status_code=500,detail=f"{e}")