Nattyboi commited on
Commit
a4cc435
·
1 Parent(s): da561bd

added most features

Browse files
app.py CHANGED
@@ -15,6 +15,16 @@ from google import genai
15
  from typing import Optional,List
16
  from pydantic import BaseModel
17
  import re
 
 
 
 
 
 
 
 
 
 
18
 
19
  load_dotenv()
20
 
@@ -410,3 +420,119 @@ def protected_route(authorization: str = Header(...)):
410
 
411
 
412
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  from typing import Optional,List
16
  from pydantic import BaseModel
17
  import re
18
+ from bson.json_util import dumps
19
+ import threading
20
+ import concurrent.futures
21
+ from gamification.pointLogic import get_all_simple_points_func,get_dream_job
22
+ from pydantic import BaseModel
23
+ from datetime import datetime
24
+ from bson import ObjectId
25
+ import os
26
+
27
+
28
 
29
  load_dotenv()
30
 
 
420
 
421
 
422
 
423
+
424
+ class LeaderBoardRanking(BaseModel):
425
+ userId:str
426
+ firstName:str
427
+ lastName:str
428
+ totalpoints:float
429
+ lastUpdated:datetime
430
+ careerPath:str
431
+ class Config:
432
+ json_encoder ={
433
+ ObjectId:str
434
+ }
435
+
436
+
437
+ def create_leaderboard_ranking( document: LeaderBoardRanking) -> bool:
438
+
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)
445
+ return True
446
+
447
+ return False
448
+
449
+
450
+
451
+ def get_all_users(user_id =None) -> List:
452
+
453
+ client = MongoClient(MONGO_URI)
454
+ db = client.crayonics
455
+ collection = db['users']
456
+ # Insert the document
457
+ if user_id==None:
458
+ results= collection.find()
459
+
460
+ if results:
461
+ result = [result for result in results]
462
+ return result
463
+
464
+ client.close()
465
+ else:
466
+ result = collection.find_one(filter={"_id":ObjectId(user_id)})
467
+ return result
468
+
469
+
470
+ def get_user_id_from_docKey(dockId):
471
+ client = MongoClient(MONGO_URI)
472
+ db = client.crayonics
473
+ collection = db['Points']
474
+ # Insert the document
475
+ result = collection.find_one(filter={"_id":ObjectId(dockId)})
476
+ client.close()
477
+ return result['userId']
478
+
479
+
480
+
481
+
482
+
483
+ # MongoDB connection setup
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):
490
+ # add everybodies points and add it to the leaderboard table
491
+ collections = db.list_collection_names()
492
+ if "LeaderBoard" not in collections:
493
+ print("Collection doesnt exists.")
494
+ # loop through points, get userId from points and total points from points table then we
495
+ # loop through userId and get the firstName and LastName of each userId lastly
496
+ # loop throguh the questionarier using the userId and get the careerPath of each user
497
+ users = get_all_users()
498
+ for user in users:
499
+ points = get_all_simple_points_func(userId=str(user['_id']))
500
+ tempDreamJob = get_dream_job(userId=str(user['_id']))
501
+ dreamJob = tempDreamJob if type(tempDreamJob)==str else "IncompleteProfile"
502
+ create_leaderboard_ranking(LeaderBoardRanking(userId=str(user['_id']),firstName=user['first_name'],lastName=user['last_name'],totalpoints=points.totalpoints,lastUpdated=datetime.now(),careerPath=dreamJob,))
503
+ else:
504
+ if change['operationType'] == 'insert':
505
+ # Extract the full document
506
+ full_document = change['fullDocument']
507
+
508
+ # Extract the userId and numOfPoints
509
+
510
+ user_id =full_document.get('userId')
511
+ leveleduser = get_all_users(userId=user_id)
512
+ points = get_all_simple_points_func(userId=user_id)
513
+ tempDreamJob = get_dream_job(userId=user_id)
514
+ dreamJob = tempDreamJob if type(tempDreamJob)==str else "IncompleteProfile"
515
+ create_leaderboard_ranking(LeaderBoardRanking(userId=user_id,firstName=leveleduser['first_name'],lastName=leveleduser['last_name'],totalpoints=points.totalpoints,lastUpdated=datetime.now(),careerPath=dreamJob,))
516
+ elif change['operationType'] == 'update':
517
+ dockey = str(change['documentKey']['_id'])
518
+ user_id = get_user_id_from_docKey(dockId=dockey)
519
+ leveleduser = get_all_users(user_id=user_id)
520
+ points = get_all_simple_points_func(userId=user_id)
521
+ tempDreamJob = get_dream_job(userId=user_id)
522
+ dreamJob = tempDreamJob if type(tempDreamJob)==str else "IncompleteProfile"
523
+ create_leaderboard_ranking(LeaderBoardRanking(userId=user_id,firstName=leveleduser['first_name'],lastName=leveleduser['last_name'],totalpoints=points.totalpoints,lastUpdated=datetime.now(),careerPath=dreamJob,))
524
+
525
+
526
+ print(f"Change detected: {dumps(change)}")
527
+
528
+ # Function to run the change stream in a separate thread (non-blocking)
529
+ def watch_change_stream():
530
+ with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor: # Limit to 10 threads, adjust as needed
531
+ with collection.watch() as stream:
532
+ for change in stream:
533
+ # Submit the handle_change task to the thread pool
534
+ executor.submit(handle_change, change)
535
+ # Start a background thread to watch the change stream
536
+ @app.on_event("startup")
537
+ def start_change_stream():
538
+ threading.Thread(target=watch_change_stream, daemon=True).start()
gamification/imports.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from bson import ObjectId
2
+ from pymongo import MongoClient
3
+ import os
4
+ from typing import List
5
+ from dotenv import load_dotenv
6
+ from datetime import datetime,timedelta
7
+ load_dotenv()
8
+ MONGO_URI = os.getenv("MONGO_URI")
gamification/levelLogic.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # levels
2
+ from gamification.imports import *
3
+
4
+ from gamification.objects import UserLevel
5
+
6
+
7
+ def create_level_func(document:UserLevel,)->bool:
8
+ """
9
+ Creates a UserLevel document in the MongoDB collection.
10
+
11
+ :param UserLevel: Actually accepts an Instance of UserLevel and deserializes it here
12
+ :param maxPoints: Maximum Amount of points for this level.
13
+ :param minPoints: Minimum Amount of points for this level.
14
+ :param levelNumber: Number for this level.
15
+ :param careerPath: Career Path Special for this level.
16
+ """
17
+ db_uri = MONGO_URI
18
+ db_name = "crayonics"
19
+ collection_name="Level"
20
+ client = MongoClient(db_uri)
21
+ db = client[db_name]
22
+ collection = db[collection_name]
23
+ should_proceed= (collection.find_one(document.model_dump()))
24
+ # Insert the document
25
+ if should_proceed==None:
26
+ if document!=None:
27
+ result = collection.insert_one(document.model_dump(exclude_none=True))
28
+ return True
29
+ else:
30
+ client.close()
31
+ return False
32
+ else:
33
+ # The exact document already exists so it can't be created again
34
+ return False
35
+
36
+
37
+
38
+
39
+ def get_all_levels_func() -> List[UserLevel]:
40
+ # MongoDB URI and configuration
41
+ db_uri = MONGO_URI
42
+ db_name = "crayonics"
43
+ collection_name="Level"
44
+ client = MongoClient(db_uri)
45
+ db = client[db_name]
46
+ collection = db[collection_name]
47
+
48
+ # Fetch all documents from the collection
49
+ levels_cursor = collection.find() # This returns a cursor to the documents
50
+
51
+ # Convert the cursor to a list of UserLevel objects
52
+ levels = [UserLevel(**level) for level in levels_cursor]
53
+
54
+ return levels
55
+
56
+
57
+
58
+ def delete_level_func(level_id,)->bool:
59
+ db_uri = MONGO_URI
60
+ db_name = "crayonics"
61
+ collection_name="Level"
62
+ client = MongoClient(db_uri)
63
+ db = client[db_name]
64
+ collection = db[collection_name]
65
+ if isinstance(level_id, str):
66
+ level_id = ObjectId(level_id)
67
+ result = collection.delete_one(filter={"_id":level_id})
68
+ if result.acknowledged==True:
69
+ if result.deleted_count ==0:
70
+ return False
71
+ else:
72
+ return True
73
+ else:
74
+ return False
75
+
76
+
77
+
78
+
79
+ def edit_level_func(level_id, **kwargs):
80
+ """
81
+ Edit a UserLevel document in the MongoDB collection.
82
+
83
+ :param level_id: The ObjectId or unique identifier of the UserLevel to edit.
84
+ :param maxPoints: Maximum Amount of points for this level.
85
+ :param minPoints: Minimum Amount of points for this level.
86
+ :param levelNumber: Number for this level.
87
+ :param careerPath: Career Path Special for this level.
88
+ """
89
+ db_uri = MONGO_URI
90
+ db_name = "crayonics"
91
+ collection_name="Level"
92
+ client = MongoClient(db_uri)
93
+ db = client[db_name]
94
+ collection = db[collection_name]
95
+
96
+
97
+ # Ensure that `level_id` is an ObjectId if using ObjectId as the identifier
98
+ if isinstance(level_id, str):
99
+ level_id = ObjectId(level_id)
100
+
101
+ # Prepare the update data
102
+ update_data = {key: value for key, value in kwargs.items() if value is not None}
103
+
104
+
105
+ # Perform the update operation in the collection
106
+ result = collection.update_one(
107
+ {"_id": level_id}, # Find the document by its unique identifier (ObjectId or other)
108
+ {"$set": update_data} # Update the document with the new values
109
+ )
110
+
111
+ return result.modified_count
gamification/logic.py CHANGED
@@ -1,12 +1,9 @@
1
 
2
- from gamification.objects import UserFeedback, UserLevel, UserPoints,CustomerInfo,Customer
3
- from bson import ObjectId
4
- from pymongo import MongoClient
5
- import os
6
- from typing import List
7
- from dotenv import load_dotenv
8
- from datetime import datetime,timedelta
9
- load_dotenv()
10
 
11
  # Normal Math
12
  def caculate_rate_change_func(c0,c1,days_ago):
@@ -15,13 +12,13 @@ def caculate_rate_change_func(c0,c1,days_ago):
15
  # If there are customers now, but no customers initially (c0 is 0),
16
  # we consider it as infinite growth or 100% growth
17
  print("here")
18
- return {"daysAgo":days_ago,"totalCustomers": c1, "GrowthRate": 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, "GrowthRateType": "positive"}
19
  elif c1 == 0:
20
  # If both c0 and c1 are zero, there is no change
21
  return {"daysAgo":days_ago,"totalCustomers": c1, "GrowthRate": 0.0, "GrowthRateType": "neutral"}
22
  else:
23
  # This case is for when c1 < 0, but it's unlikely in a customer count scenario.
24
- return {"daysAgo":days_ago,"totalCustomers": c1, "GrowthRate": -99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, "GrowthRateType": "negative"}
25
 
26
  elif c1 > c0:
27
  # Positive growth rate: c1 > c0
@@ -45,117 +42,7 @@ def caculate_rate_change_func(c0,c1,days_ago):
45
 
46
  MONGO_URI = os.getenv("MONGO_URI")
47
 
48
-
49
- # levels
50
- def create_level_func(document:UserLevel,)->bool:
51
- """
52
- Creates a UserLevel document in the MongoDB collection.
53
-
54
- :param UserLevel: Actually accepts an Instance of UserLevel and deserializes it here
55
- :param maxPoints: Maximum Amount of points for this level.
56
- :param minPoints: Minimum Amount of points for this level.
57
- :param levelNumber: Number for this level.
58
- :param careerPath: Career Path Special for this level.
59
- """
60
- db_uri = MONGO_URI
61
- db_name = "crayonics"
62
- collection_name="Level"
63
- client = MongoClient(db_uri)
64
- db = client[db_name]
65
- collection = db[collection_name]
66
- should_proceed= (collection.find_one(document.model_dump()))
67
- # Insert the document
68
- if should_proceed==None:
69
- if document!=None:
70
- result = collection.insert_one(document.model_dump())
71
- return True
72
- else:
73
- client.close()
74
- return False
75
- else:
76
- # The exact document already exists so it can't be created again
77
- return False
78
-
79
-
80
-
81
-
82
- def get_all_levels_func() -> List[UserLevel]:
83
- # MongoDB URI and configuration
84
- db_uri = MONGO_URI
85
- db_name = "crayonics"
86
- collection_name="Level"
87
- client = MongoClient(db_uri)
88
- db = client[db_name]
89
- collection = db[collection_name]
90
-
91
- # Fetch all documents from the collection
92
- levels_cursor = collection.find() # This returns a cursor to the documents
93
-
94
- # Convert the cursor to a list of UserLevel objects
95
- levels = [UserLevel(**level) for level in levels_cursor]
96
-
97
- return levels
98
-
99
-
100
-
101
- def delete_level_func(level_id,)->bool:
102
- db_uri = MONGO_URI
103
- db_name = "crayonics"
104
- collection_name="Level"
105
- client = MongoClient(db_uri)
106
- db = client[db_name]
107
- collection = db[collection_name]
108
- if isinstance(level_id, str):
109
- level_id = ObjectId(level_id)
110
- result = collection.delete_one(filter={"_id":level_id})
111
- if result.acknowledged==True:
112
- if result.deleted_count ==0:
113
- return False
114
- else:
115
- return True
116
- else:
117
- return False
118
-
119
-
120
-
121
-
122
- def edit_level_func(level_id, **kwargs):
123
- """
124
- Edit a UserLevel document in the MongoDB collection.
125
-
126
- :param level_id: The ObjectId or unique identifier of the UserLevel to edit.
127
- :param maxPoints: Maximum Amount of points for this level.
128
- :param minPoints: Minimum Amount of points for this level.
129
- :param levelNumber: Number for this level.
130
- :param careerPath: Career Path Special for this level.
131
- """
132
- db_uri = MONGO_URI
133
- db_name = "crayonics"
134
- collection_name="Level"
135
- client = MongoClient(db_uri)
136
- db = client[db_name]
137
- collection = db[collection_name]
138
-
139
-
140
- # Ensure that `level_id` is an ObjectId if using ObjectId as the identifier
141
- if isinstance(level_id, str):
142
- level_id = ObjectId(level_id)
143
-
144
- # Prepare the update data
145
- update_data = {key: value for key, value in kwargs.items() if value is not None}
146
-
147
-
148
- # Perform the update operation in the collection
149
- result = collection.update_one(
150
- {"_id": level_id}, # Find the document by its unique identifier (ObjectId or other)
151
- {"$set": update_data} # Update the document with the new values
152
- )
153
-
154
- return result.modified_count
155
-
156
-
157
-
158
-
159
 
160
 
161
 
@@ -163,51 +50,6 @@ def edit_level_func(level_id, **kwargs):
163
 
164
  # points
165
 
166
- def create_points_func(document:UserPoints)->bool:
167
-
168
- db_uri = MONGO_URI
169
- db_name = "crayonics"
170
- collection_name="Points"
171
- client = MongoClient(db_uri)
172
- db = client[db_name]
173
- collection = db[collection_name]
174
- # Insert the document
175
-
176
- if document!=None:
177
- result = collection.insert_one(document.model_dump())
178
- return True
179
- else:
180
- client.close()
181
- return False
182
-
183
-
184
-
185
- def get_all_points_func() -> List[UserFeedback]:
186
- # MongoDB URI and configuration
187
- db_uri = MONGO_URI
188
- db_name = "crayonics"
189
- collection_name="Points"
190
- client = MongoClient(db_uri)
191
- db = client[db_name]
192
- collection = db[collection_name]
193
-
194
- # Fetch all documents from the collection
195
- point_cursor = collection.find() # This returns a cursor to the documents
196
-
197
- # Convert the cursor to a list of UserLevel objects
198
- points = [UserFeedback(**point) for point in point_cursor]
199
-
200
- return points
201
-
202
-
203
-
204
-
205
-
206
-
207
-
208
-
209
-
210
-
211
 
212
  # feedback
213
  def create_feedback_func(document:UserFeedback)->bool:
@@ -219,6 +61,8 @@ def create_feedback_func(document:UserFeedback)->bool:
219
  collection = db[collection_name]
220
  # Insert the document
221
  if document!=None:
 
 
222
  result = collection.insert_one(document.model_dump())
223
  return True
224
  else:
@@ -248,7 +92,6 @@ def get_all_feedback_func() -> List[UserFeedback]:
248
 
249
  def get_all_customer_info()->List[CustomerInfo]:
250
  db_uri=MONGO_URI
251
- # db_uri = "mongodb+srv://groupcresearchseminar:[email protected]/?retryWrites=true&w=majority&appName=Cluster0"
252
  db_name = "crayonics"
253
  collection_name = "users"
254
  client = MongoClient(db_uri)
@@ -283,3 +126,23 @@ def get_all_customer_info()->List[CustomerInfo]:
283
  for rate in list_of_rates:
284
  customer_info.append(CustomerInfo(**rate))
285
  return customer_info
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
+ from gamification.objects import PlatformEngagement, UserFeedback, UserLevel, UserPoints,CustomerInfo,Customer,IndividualUserLevel,Points,SimpleIndividualUserLevel
3
+ from gamification.levelLogic import create_level_func,get_all_levels_func,edit_level_func,delete_level_func
4
+ from gamification.imports import *
5
+ from gamification.pointLogic import create_points_func,get_all_simple_points_func,get_all_points_func
6
+
 
 
 
7
 
8
  # Normal Math
9
  def caculate_rate_change_func(c0,c1,days_ago):
 
12
  # If there are customers now, but no customers initially (c0 is 0),
13
  # we consider it as infinite growth or 100% growth
14
  print("here")
15
+ return {"daysAgo":days_ago,"totalCustomers": c1, "GrowthRate": 9999999999999999999999999999999999999999999999999999999, "GrowthRateType": "positive"}
16
  elif c1 == 0:
17
  # If both c0 and c1 are zero, there is no change
18
  return {"daysAgo":days_ago,"totalCustomers": c1, "GrowthRate": 0.0, "GrowthRateType": "neutral"}
19
  else:
20
  # This case is for when c1 < 0, but it's unlikely in a customer count scenario.
21
+ return {"daysAgo":days_ago,"totalCustomers": c1, "GrowthRate": -999999999999999999999999999999999999999999999999999999, "GrowthRateType": "negative"}
22
 
23
  elif c1 > c0:
24
  # Positive growth rate: c1 > c0
 
42
 
43
  MONGO_URI = os.getenv("MONGO_URI")
44
 
45
+ # Levels
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
 
48
 
 
50
 
51
  # points
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  # feedback
55
  def create_feedback_func(document:UserFeedback)->bool:
 
61
  collection = db[collection_name]
62
  # Insert the document
63
  if document!=None:
64
+ feedbackPoints= Points(userId=document.userId,platformEngagement=PlatformEngagement(providing_feedback=15))
65
+ create_points_func(document=feedbackPoints)
66
  result = collection.insert_one(document.model_dump())
67
  return True
68
  else:
 
92
 
93
  def get_all_customer_info()->List[CustomerInfo]:
94
  db_uri=MONGO_URI
 
95
  db_name = "crayonics"
96
  collection_name = "users"
97
  client = MongoClient(db_uri)
 
126
  for rate in list_of_rates:
127
  customer_info.append(CustomerInfo(**rate))
128
  return customer_info
129
+
130
+
131
+
132
+
133
+
134
+ # Leaderboard Logic
135
+ def get_top_30():
136
+ db_uri=MONGO_URI
137
+ db_name = "crayonics"
138
+ collection_name = "LeaderBoard"
139
+ client = MongoClient(db_uri)
140
+ db = client[db_name]
141
+ collection = db[collection_name]
142
+ sorted_documents = collection.find().sort([("totalpoints", -1), ("lastName", 1)]).limit(30)
143
+ rankers = [
144
+ {**r, 'rank': i + 1} # Add 'rank' to the document with i+1 (1-based index)
145
+ for i, r in enumerate(sorted_documents)
146
+ ]
147
+
148
+ return rankers
gamification/objects.py CHANGED
@@ -1,35 +1,217 @@
1
  from datetime import datetime
2
- from pydantic import BaseModel
 
3
  from bson import ObjectId
 
4
  class UserLevel(BaseModel):
5
- maxPoints:int
6
- minPoints:int
7
- levelName:str
8
- careerPath:str
9
- levelNumber:int
10
- # To convert MongoDB ObjectId to string, if needed
 
 
 
11
  class Config:
12
  json_encoders = {
13
  ObjectId: str
14
  }
15
 
 
 
 
 
 
 
 
 
 
16
  class UserPoints(BaseModel):
17
- points:int
18
- reason:str
19
  userId:str
20
  class Config:
21
  json_encoders = {
22
  ObjectId: str
23
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  class UserFeedback(BaseModel):
25
  userId:str
26
  feedback:str
27
  rating:int
 
28
 
29
  class Config:
30
  json_encoders = {
31
  ObjectId: str
32
  }
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  class Customer(BaseModel):
35
  email:str
@@ -40,6 +222,7 @@ class Customer(BaseModel):
40
  json_encoders = {
41
  ObjectId: str
42
  }
 
43
 
44
 
45
 
@@ -54,12 +237,61 @@ class CustomerInfo(BaseModel):
54
  }
55
 
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  class IndividualUserLevel(BaseModel):
58
  totalpoints:int
59
- userId:str
60
- levelId:str
 
 
 
61
  class Config:
62
  json_encoders = {
63
  ObjectId: str
64
  }
65
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from datetime import datetime
2
+ from pydantic import model_validator, BaseModel
3
+ from typing import List, Optional, Union
4
  from bson import ObjectId
5
+
6
  class UserLevel(BaseModel):
7
+ _id: Optional[ObjectId]=None # Make sure _id can be Optional
8
+ id:Optional[str]=None
9
+ maxPoints: int
10
+ minPoints: int
11
+ levelName: str
12
+ careerPath: str
13
+ levelNumber: int
14
+
15
+ # To convert MongoDB ObjectId to string
16
  class Config:
17
  json_encoders = {
18
  ObjectId: str
19
  }
20
 
21
+ # Custom validator to handle the ObjectId conversion if needed
22
+ @model_validator(mode='before')
23
+ def handle_objectid(cls, values):
24
+ if '_id' in values and isinstance(values['_id'], ObjectId):
25
+ values['id'] = str(values['_id']) # Convert ObjectId to string
26
+ return values
27
+
28
+
29
+
30
  class UserPoints(BaseModel):
31
+ pointsId:str
 
32
  userId:str
33
  class Config:
34
  json_encoders = {
35
  ObjectId: str
36
  }
37
+
38
+
39
+ class LearningProgress(BaseModel):
40
+ course_completion: Optional[int] = None # Points for course completion
41
+ module_completion: Optional[int] = None # Points for module completion
42
+ daily_learning_streak: Optional[int] = None # Points for daily learning streak
43
+ quiz_assessment_completion: Optional[int] = None# Points for quiz/assessment completion
44
+ passing_score: Optional[int] = None # Points for passing assessments
45
+ class Config:
46
+ json_encoders = {
47
+ ObjectId: str
48
+ }
49
+ class SkillDevelopment(BaseModel):
50
+ skill_milestone_achievements: Optional[int] = None # Points for achieving milestones
51
+ cross_discipline_learning: Optional[int] = None # Points for completing courses in different tech categories
52
+ practical_project_submission: Optional[int] = None # Points for submitting a practical project
53
+ project_peer_review: Optional[int] = None # Points for reviewing a project
54
+ class Config:
55
+ json_encoders = {
56
+ ObjectId: str
57
+ }
58
+ class PlatformEngagement(BaseModel):
59
+ profile_completion: Optional[int] = None # Points for completing profile
60
+ connecting_learning_accounts: Optional[int] = None # Points for connecting learning accounts
61
+ daily_check_in: Optional[int] = None # Points for daily check-in
62
+ community_participation: Optional[int] = None # Points for community participation
63
+ providing_feedback: Optional[int] = None # Points for providing feedback
64
+ class Config:
65
+ json_encoders = {
66
+ ObjectId: str
67
+ }
68
+
69
+
70
+ class PointMultipliersWeekendWarrior(BaseModel):
71
+ weekendWarrior: float = 1.5
72
+ class Config:
73
+ json_encoders = {
74
+ ObjectId: str
75
+ }
76
+
77
+ class PointMultipliersFocusMode(BaseModel):
78
+ focusMode: float = 2
79
+ class Config:
80
+ json_encoders = {
81
+ ObjectId: str
82
+ }
83
+
84
+ class PointMultipliersSkillGapTargeting(BaseModel):
85
+ skillGapTargeting: float = 2
86
+ class Config:
87
+ json_encoders = {
88
+ ObjectId: str
89
+ }
90
+
91
+ class PointMultipliersTrendingTech(BaseModel):
92
+ trendingTech: float = 1.5
93
+
94
+ class Config:
95
+ json_encoders = {
96
+ ObjectId: str
97
+ }
98
+
99
+
100
+
101
+
102
+ class Points(BaseModel):
103
+ userId: str
104
+ numOfPoints: Optional[float] = None # Initially set to None
105
+ learningProgress: Optional[LearningProgress] = None
106
+ skillDevelopment: Optional[SkillDevelopment] = None
107
+ platformEngagement: Optional[PlatformEngagement] = None
108
+ weekendWarrior: Optional[PointMultipliersWeekendWarrior] = None
109
+ trendingTech: Optional[PointMultipliersTrendingTech]=None
110
+ skillGapTargeting:Optional[PointMultipliersSkillGapTargeting]=None
111
+ focusMode:Optional[PointMultipliersFocusMode]=None
112
+ earnedAt:Optional[datetime]=datetime.now()
113
+
114
+ @model_validator(mode='before')
115
+ def calculate_num_of_points(cls, values):
116
+ total_points = 0
117
+
118
+ # Add points from LearningProgress
119
+ learning_progress = values.get('learningProgress')
120
+
121
+ if learning_progress:
122
+ total_points += sum(filter(None, [
123
+ learning_progress.course_completion,
124
+ learning_progress.module_completion,
125
+ learning_progress.daily_learning_streak,
126
+ learning_progress.quiz_assessment_completion,
127
+ learning_progress.passing_score
128
+ ]))
129
+
130
+ # Add points from SkillDevelopment
131
+ skill_development = values.get('skillDevelopment')
132
+ if skill_development:
133
+ total_points += sum(filter(None, [
134
+ skill_development.skill_milestone_achievements,
135
+ skill_development.cross_discipline_learning,
136
+ skill_development.practical_project_submission,
137
+ skill_development.project_peer_review
138
+ ]))
139
+
140
+ # Add points from PlatformEngagement
141
+ platform_engagement = values.get('platformEngagement')
142
+ if platform_engagement:
143
+ total_points += sum(filter(None, [
144
+ platform_engagement.profile_completion,
145
+ platform_engagement.connecting_learning_accounts,
146
+ platform_engagement.daily_check_in,
147
+ platform_engagement.community_participation,
148
+ platform_engagement.providing_feedback
149
+ ]))
150
+
151
+ # Apply multipliers if present
152
+ PointMultipliersWeekendWarrior = values.get('weekendWarrior')
153
+ if PointMultipliersWeekendWarrior:
154
+ total_points *= sum([
155
+ PointMultipliersWeekendWarrior.weekendWarrior
156
+
157
+ ])
158
+
159
+ PointMultipliersTrendingTech = values.get('trendingTech')
160
+ if PointMultipliersTrendingTech:
161
+ total_points *= sum([
162
+ PointMultipliersTrendingTech.trendingTech
163
+ ])
164
+
165
+
166
+ PointMultipliersSkillGapTargeting = values.get('skillGapTargeting')
167
+ if PointMultipliersSkillGapTargeting:
168
+ total_points *= sum([
169
+ PointMultipliersSkillGapTargeting.skillGapTargeting
170
+ ])
171
+
172
+
173
+
174
+ PointMultipliersFocusMode = values.get('focusMode')
175
+ if PointMultipliersFocusMode:
176
+ total_points *= sum([
177
+ PointMultipliersFocusMode.focusMode,
178
+ ])
179
+
180
+
181
+ values['numOfPoints'] = total_points # Store calculated points
182
+
183
+ return values
184
+
185
+ class Config:
186
+ json_encoders = {
187
+ ObjectId: str
188
+ }
189
+
190
+
191
+
192
+
193
  class UserFeedback(BaseModel):
194
  userId:str
195
  feedback:str
196
  rating:int
197
+ respondedAt:datetime
198
 
199
  class Config:
200
  json_encoders = {
201
  ObjectId: str
202
  }
203
+
204
+
205
+
206
+ class Feedback(BaseModel):
207
+ feedback:str
208
+ rating:int
209
+
210
+ class Config:
211
+ json_encoders = {
212
+ ObjectId: str
213
+ }
214
+
215
 
216
  class Customer(BaseModel):
217
  email:str
 
222
  json_encoders = {
223
  ObjectId: str
224
  }
225
+
226
 
227
 
228
 
 
237
  }
238
 
239
 
240
+ class individualPoints(BaseModel):
241
+ numOfPoints:int
242
+ earnedAt:datetime
243
+ platformEngagement:Optional[dict]=None
244
+ learningProgress:Optional[dict]=None
245
+ skillDevelopment:Optional[dict]=None
246
+ weekendWarrior:Optional[dict]=None
247
+ trendingTech:Optional[dict]=None
248
+ skillGapTargeting:Optional[dict]=None
249
+ focusMode:Optional[dict]=None
250
+ class Config:
251
+ json_encoders={
252
+ ObjectId:str
253
+ }
254
+
255
+
256
  class IndividualUserLevel(BaseModel):
257
  totalpoints:int
258
+ levelName:str
259
+ maxPoints:float
260
+ minPoints:float
261
+ individualPoints:List[individualPoints]
262
+
263
  class Config:
264
  json_encoders = {
265
  ObjectId: str
266
  }
267
+
268
+
269
+ class SimpleIndividualUserLevel(BaseModel):
270
+ totalpoints:int
271
+ levelName:str
272
+ maxPoints:float
273
+ minPoints:float
274
+
275
+ class Config:
276
+ json_encoders = {
277
+ ObjectId: str
278
+ }
279
+
280
+
281
+ class Ranker(BaseModel):
282
+ firstName:str
283
+ lastName:str
284
+ rank:int
285
+
286
+ totalPoints:Optional[float]=None
287
+ dreamJob:Optional[str]=None
288
+ class Config:
289
+ json_encoders = {
290
+ ObjectId:str
291
+ }
292
+ @model_validator(mode='before')
293
+ def changeValueNames(cls,values):
294
+ values['totalPoints']= values.get("totalpoints")
295
+ values['dreamJob']=values.get("careerPath")
296
+ return values
297
+
gamification/pointLogic.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from gamification.objects import UserPoints ,SimpleIndividualUserLevel,IndividualUserLevel,UserLevel
3
+ from gamification.imports import *
4
+ from gamification.levelLogic import get_all_levels_func
5
+
6
+ # utils
7
+ def get_particular_level(totalPoints,dreamJob)->UserLevel:
8
+ # query db and get the results of all the level probably re use a function
9
+ levels = get_all_levels_func()
10
+ particularLevel= [level for level in levels if (level.maxPoints >= totalPoints) and (level.minPoints<=totalPoints)and (level.careerPath==dreamJob)]
11
+ defaulLevel= [level for level in levels if level.levelName=="default" ]
12
+ if len(particularLevel)>0:
13
+ return particularLevel
14
+ return defaulLevel
15
+
16
+
17
+ def get_dream_job(userId):
18
+ db_uri=MONGO_URI
19
+ db_name = "crayonics"
20
+ collection_name = "Questionaire"
21
+ client = MongoClient(db_uri)
22
+ db = client[db_name]
23
+ collection = db[collection_name]
24
+ questionaire_doc = collection.find_one({"userId": userId})
25
+ if questionaire_doc:
26
+ return questionaire_doc['dreamRole']
27
+ else: return False
28
+
29
+
30
+ def create_points_func(document:UserPoints)->bool:
31
+
32
+ db_uri = MONGO_URI
33
+ db_name = "crayonics"
34
+ collection_name="Points"
35
+ client = MongoClient(db_uri)
36
+ db = client[db_name]
37
+ collection = db[collection_name]
38
+ # Insert the document
39
+
40
+ if document!=None:
41
+ doc = document.model_dump()
42
+ doc['earnedAt']=datetime.now()
43
+ result = collection.insert_one(doc)
44
+ return True
45
+ else:
46
+ client.close()
47
+ return False
48
+
49
+
50
+
51
+ def get_all_points_func(userId) -> IndividualUserLevel:
52
+ # MongoDB URI and configuration
53
+ db_uri = MONGO_URI
54
+ db_name = "crayonics"
55
+ collection_name = "Points"
56
+ client = MongoClient(db_uri)
57
+ db = client[db_name]
58
+ collection = db[collection_name]
59
+ dreamJob = get_dream_job(userId=userId)
60
+
61
+ # Fetch all documents from the collection
62
+ point_cursor = collection.find({"userId": userId}) # This returns a cursor to the documents
63
+
64
+ # Convert the cursor to a list so we can reuse it
65
+ points_list = list(point_cursor)
66
+
67
+ # Calculate the total points
68
+ totalPoints = sum([point['numOfPoints'] for point in points_list])
69
+ particularLevelInfo = get_particular_level(dreamJob=dreamJob,totalPoints=totalPoints)
70
+ # Create the individual points list
71
+ individualPoints = [indpoint for indpoint in points_list]
72
+
73
+ print([pointss for pointss in individualPoints if all(val is not None for val in pointss.values())])
74
+
75
+
76
+ # Create the IndividualUserLevel object with totalPoints and individualPoints
77
+ points = IndividualUserLevel(totalpoints=totalPoints,levelName=particularLevelInfo[0].levelName,minPoints=particularLevelInfo[0].minPoints,maxPoints=particularLevelInfo[0].maxPoints, individualPoints=individualPoints)
78
+
79
+ return points
80
+
81
+
82
+
83
+
84
+
85
+ def get_all_simple_points_func(userId) -> SimpleIndividualUserLevel:
86
+ # MongoDB URI and configuration
87
+ db_uri = MONGO_URI
88
+ db_name = "crayonics"
89
+ collection_name = "Points"
90
+ client = MongoClient(db_uri)
91
+ db = client[db_name]
92
+ collection = db[collection_name]
93
+ dreamJob = get_dream_job(userId=userId)
94
+
95
+ # Fetch all documents from the collection
96
+ point_cursor = collection.find({"userId": userId}) # This returns a cursor to the documents
97
+
98
+ # Convert the cursor to a list so we can reuse it
99
+ points_list = list(point_cursor)
100
+
101
+ # Calculate the total points
102
+ totalPoints = sum([point['numOfPoints'] for point in points_list])
103
+ particularLevelInfo = get_particular_level(dreamJob=dreamJob,totalPoints=totalPoints)
104
+ # Create the individual points list
105
+
106
+ # Create the IndividualUserLevel object with totalPoints and individualPoints
107
+ points = SimpleIndividualUserLevel(totalpoints=totalPoints,levelName=particularLevelInfo[0].levelName,minPoints=particularLevelInfo[0].minPoints,maxPoints=particularLevelInfo[0].maxPoints)
108
+
109
+ return points
110
+
111
+
112
+
gamification/routes.py CHANGED
@@ -1,9 +1,8 @@
1
- from fastapi import FastAPI,HTTPException
2
  from gamification.objects import *
3
  from gamification.logic import *
4
- from pydantic import BaseModel
5
- from typing import Optional
6
- from bson import ObjectId
7
 
8
  class EditableUserLevel(BaseModel):
9
  levelId : str
@@ -25,17 +24,64 @@ gamification = FastAPI()
25
 
26
 
27
  @gamification.post("/create-feedback",tags=["user"])
28
- def create_feedback(user_feedback:UserFeedback)->bool:
 
 
 
 
 
 
 
 
 
29
  try:
 
30
  result = create_feedback_func(user_feedback)
31
- return {"message":result}
32
  except Exception as e:
33
  raise HTTPException(status_code=500,detail=f"{e}")
34
 
 
35
  @gamification.post("/get-leaderboard",tags=["user"])
36
  def get_leaderboard_details():
37
  pass
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  @gamification.get("/get-customer-info",tags=["admin"])
40
  def get_customer_information():
41
  try:
@@ -55,7 +101,7 @@ def get_feedback()->List[UserFeedback]:
55
  @gamification.post("/create-level",tags=["admin"])
56
  def create_level(level_obj:UserLevel)->bool:
57
  result = create_level_func(document=level_obj)
58
- return {"message":result}
59
 
60
 
61
 
@@ -79,5 +125,17 @@ def delete_level(levelId)->bool:
79
  try:
80
  result = delete_level_func(level_id=levelId)
81
  return {"message":result}
 
 
 
 
 
 
 
 
 
 
 
 
82
  except Exception as e:
83
  raise HTTPException(status_code=500,detail=f"{e}")
 
1
+ from fastapi import FastAPI,HTTPException, Header
2
  from gamification.objects import *
3
  from gamification.logic import *
4
+ from jwtcoding import decode_jwt
5
+ from tokenManagement import verify_access_token
 
6
 
7
  class EditableUserLevel(BaseModel):
8
  levelId : str
 
24
 
25
 
26
  @gamification.post("/create-feedback",tags=["user"])
27
+ def create_feedback(feedback:Feedback,authorization: str = Header(...))->bool:
28
+
29
+ token = authorization.split("Bearer ")[-1]
30
+
31
+ # Here, you would validate the token (e.g., check with a JWT library)
32
+ decoded_user_id,decoded_access_token = decode_jwt(token)
33
+ is_valid = verify_access_token(db_uri=MONGO_URI, user_id=decoded_user_id, access_token=decoded_access_token)
34
+ if is_valid != True: # Example check
35
+ raise HTTPException(status_code=401, detail="Invalid token")
36
+
37
  try:
38
+ user_feedback = UserFeedback(userId=decoded_user_id,respondedAt=datetime.now(), feedback=feedback.feedback,rating=feedback.rating)
39
  result = create_feedback_func(user_feedback)
40
+ return result
41
  except Exception as e:
42
  raise HTTPException(status_code=500,detail=f"{e}")
43
 
44
+
45
  @gamification.post("/get-leaderboard",tags=["user"])
46
  def get_leaderboard_details():
47
  pass
48
 
49
+ @gamification.get("/get-advanced-user-points",tags=["user"])
50
+ def get_points(authorization: str = Header(...))->IndividualUserLevel:
51
+ # Extract the token from the Authorization header (Bearer token)
52
+ token = authorization.split("Bearer ")[-1]
53
+
54
+ # Here, you would validate the token (e.g., check with a JWT library)
55
+ decoded_user_id,decoded_access_token = decode_jwt(token)
56
+ is_valid = verify_access_token(db_uri=MONGO_URI, user_id=decoded_user_id, access_token=decoded_access_token)
57
+
58
+ if is_valid != True: # Example check
59
+ raise HTTPException(status_code=401, detail="Invalid token")
60
+
61
+ # do thing u want here
62
+ points = get_all_points_func(userId=decoded_user_id)
63
+ return points.model_dump(exclude_none=True)
64
+
65
+
66
+
67
+ @gamification.get("/get-simple-user-points",tags=["user"])
68
+ def get_points(authorization: str = Header(...))->SimpleIndividualUserLevel:
69
+ # Extract the token from the Authorization header (Bearer token)
70
+ token = authorization.split("Bearer ")[-1]
71
+
72
+ # Here, you would validate the token (e.g., check with a JWT library)
73
+ decoded_user_id,decoded_access_token = decode_jwt(token)
74
+ is_valid = verify_access_token(db_uri=MONGO_URI, user_id=decoded_user_id, access_token=decoded_access_token)
75
+
76
+ if is_valid != True: # Example check
77
+ raise HTTPException(status_code=401, detail="Invalid token")
78
+
79
+ # do thing u want here
80
+ points = get_all_simple_points_func(userId=decoded_user_id)
81
+ return points.model_dump(exclude_none=True)
82
+
83
+
84
+
85
  @gamification.get("/get-customer-info",tags=["admin"])
86
  def get_customer_information():
87
  try:
 
101
  @gamification.post("/create-level",tags=["admin"])
102
  def create_level(level_obj:UserLevel)->bool:
103
  result = create_level_func(document=level_obj)
104
+ return result
105
 
106
 
107
 
 
125
  try:
126
  result = delete_level_func(level_id=levelId)
127
  return {"message":result}
128
+ except Exception as e:
129
+ raise HTTPException(status_code=500,detail=f"{e}")
130
+
131
+
132
+ @gamification.get("/get-top-30",tags=["user","admin"])
133
+ def get_leaderboard()->List[Ranker]:
134
+ try:
135
+ list_of_rankers = []
136
+ result = get_top_30()
137
+ list_of_rankers = [Ranker(**ranker) for ranker in result]
138
+
139
+ return list_of_rankers
140
  except Exception as e:
141
  raise HTTPException(status_code=500,detail=f"{e}")
s.py ADDED
File without changes
streaksManagement.py CHANGED
@@ -1,6 +1,9 @@
1
  from pymongo import MongoClient
2
  from datetime import datetime, timedelta
3
  from typing import Dict, List, Union
 
 
 
4
 
5
  def get_current_date() -> str:
6
  # Get the current date and return it in YYYY-MM-DD format
@@ -37,12 +40,19 @@ def save_in_streaks_history(db_uri,document):
37
  print("added new streak reset record")
38
  document["streaks_records"] = [{"date_of_streak_reset":current_date,"streak_dates":document["streak_dates"]}]
39
  document.pop("streak_dates")
 
 
40
  collection.insert_one(document)
41
  return True
42
  else:
43
  print("added another streak reset record")
44
  current_record={"date_of_streaks_reset":current_date,"streak_dates":document["streak_dates"]}
45
-
 
 
 
 
 
46
  dates = found_user["streaks_records"] + [current_record]
47
  collection.update_one(
48
  {"user_id": document.get("user_id")},
@@ -57,8 +67,6 @@ def save_in_streaks_history(db_uri,document):
57
  # finally:
58
  # client.close()
59
 
60
-
61
-
62
  def streaks_manager(db_uri: str, document: Dict) -> Union[bool, str]:
63
  """
64
  Manage user streaks in MongoDB.
@@ -93,9 +101,17 @@ def streaks_manager(db_uri: str, document: Dict) -> Union[bool, str]:
93
  if is_a_streak:
94
  print("its a streak guys")
95
  # Extend existing streak
96
- if not (current_date== found_user["streak_dates"][-1]):
97
  dates = found_user["streak_dates"] + [current_date]
 
 
 
 
 
 
 
98
  else:
 
99
  dates=found_user["streak_dates"]
100
  collection.update_one(
101
  {"user_id": document.get("user_id")},
 
1
  from pymongo import MongoClient
2
  from datetime import datetime, timedelta
3
  from typing import Dict, List, Union
4
+ from gamification.objects import Points,PointMultipliersWeekendWarrior,PlatformEngagement
5
+ from gamification.logic import create_points_func
6
+
7
 
8
  def get_current_date() -> str:
9
  # Get the current date and return it in YYYY-MM-DD format
 
40
  print("added new streak reset record")
41
  document["streaks_records"] = [{"date_of_streak_reset":current_date,"streak_dates":document["streak_dates"]}]
42
  document.pop("streak_dates")
43
+ streakPoints= Points(userId=document['user_id'],platformEngagement=PlatformEngagement(daily_check_in=5))
44
+ create_points_func(document=streakPoints)
45
  collection.insert_one(document)
46
  return True
47
  else:
48
  print("added another streak reset record")
49
  current_record={"date_of_streaks_reset":current_date,"streak_dates":document["streak_dates"]}
50
+ today = datetime.date(datetime.now())
51
+ if (today.weekday()>=5):
52
+ streakPoints= Points(userId=document['user_id'],platformEngagement=PlatformEngagement(daily_check_in=5),weekendWarrior=PointMultipliersWeekendWarrior())
53
+ else:
54
+ streakPoints= Points(userId=document['user_id'],platformEngagement=PlatformEngagement(daily_check_in=5))
55
+ wasCreated= create_points_func(document=streakPoints)
56
  dates = found_user["streaks_records"] + [current_record]
57
  collection.update_one(
58
  {"user_id": document.get("user_id")},
 
67
  # finally:
68
  # client.close()
69
 
 
 
70
  def streaks_manager(db_uri: str, document: Dict) -> Union[bool, str]:
71
  """
72
  Manage user streaks in MongoDB.
 
101
  if is_a_streak:
102
  print("its a streak guys")
103
  # Extend existing streak
104
+ if not ((current_date)== (found_user["streak_dates"][-1])):
105
  dates = found_user["streak_dates"] + [current_date]
106
+ print("an actual streak")
107
+ today = datetime.date(datetime.now())
108
+ if (today.weekday()>=5):
109
+ streakPoints= Points(userId=document['user_id'],platformEngagement=PlatformEngagement(daily_check_in=5),weekendWarrior=PointMultipliersWeekendWarrior())
110
+ else:
111
+ streakPoints= Points(userId=document['user_id'],platformEngagement=PlatformEngagement(daily_check_in=5))
112
+ create_points_func(document=streakPoints)
113
  else:
114
+
115
  dates=found_user["streak_dates"]
116
  collection.update_one(
117
  {"user_id": document.get("user_id")},
testing.py ADDED
File without changes
utils.py CHANGED
@@ -1,8 +1,13 @@
1
  from bson import ObjectId
2
- import json
 
 
 
3
  from datetime import datetime
4
  import requests
5
  from pymongo import MongoClient
 
 
6
  from password import *
7
  from streaksManagement import streaks_manager
8
 
@@ -176,6 +181,9 @@ def create_questionaire(db_uri: str, db_name: str, collection_name: str, documen
176
  result= collection.find_one_and_replace(filter={"userId":document.get("userId")},replacement=document)
177
  print(result)
178
  if result==None:
 
 
 
179
  result = collection.insert_one(document)
180
  print(result)
181
  return str(result.inserted_id)
@@ -230,10 +238,6 @@ def login_user(db_uri: str, db_name: str, collection_name: str, document: dict)
230
 
231
 
232
 
233
- from pymongo import MongoClient
234
- from bson.objectid import ObjectId
235
- from typing import Dict, Optional
236
-
237
  def user_details_func(db_uri: str, document: Dict) -> Optional[Dict]:
238
  """
239
  Retrieve and process user details from MongoDB collections.
 
1
  from bson import ObjectId
2
+
3
+ from pymongo import MongoClient
4
+ from typing import Dict, Optional
5
+
6
  from datetime import datetime
7
  import requests
8
  from pymongo import MongoClient
9
+ from gamification.logic import create_points_func
10
+ from gamification.objects import PlatformEngagement, Points
11
  from password import *
12
  from streaksManagement import streaks_manager
13
 
 
181
  result= collection.find_one_and_replace(filter={"userId":document.get("userId")},replacement=document)
182
  print(result)
183
  if result==None:
184
+ # give points for the completness of a profile
185
+ completProfilePoints= Points(userId=document.get('userId'),platformEngagement=PlatformEngagement(profile_completion=50))
186
+ wasCreated= create_points_func(document=completProfilePoints)
187
  result = collection.insert_one(document)
188
  print(result)
189
  return str(result.inserted_id)
 
238
 
239
 
240
 
 
 
 
 
241
  def user_details_func(db_uri: str, document: Dict) -> Optional[Dict]:
242
  """
243
  Retrieve and process user details from MongoDB collections.