21
21
USERNAMES = []
22
22
reported_problems = {}
23
23
24
+ from datetime import datetime , timedelta
25
+
26
+ def days_since_last_activity (username ):
27
+ submissions = getLatestAcceptedSubmits (username , limit = 1 )
28
+ if not submissions :
29
+ return None
30
+
31
+ # Ensure the timestamp is an integer
32
+ latest_submission_timestamp = submissions [0 ]['timestamp' ]
33
+ if isinstance (latest_submission_timestamp , str ):
34
+ latest_submission_timestamp = int (latest_submission_timestamp )
35
+ latest_submission_date = datetime .fromtimestamp (latest_submission_timestamp )
36
+
37
+ # Calculating the difference in days
38
+ difference = datetime .utcnow () - latest_submission_date
39
+ return difference .days
40
+
41
+
42
+
24
43
def isValidUsername (userId ):
25
44
return bool (re .match ("^[A-Za-z0-9_]*$" , userId ))
26
45
@@ -87,7 +106,7 @@ def getLatestAcceptedSubmits(userId, limit=10):
87
106
async def on_ready ():
88
107
print (f'Bot has logged in as { bot .user .name } ({ bot .user .id } )' )
89
108
check_leetcode_updates .start ()
90
-
109
+
91
110
@bot .event
92
111
async def on_command_error (ctx , error ):
93
112
if isinstance (error , commands .CommandInvokeError ):
@@ -102,6 +121,17 @@ async def CodegramBot(ctx):
102
121
if ctx .invoked_subcommand is None :
103
122
await ctx .send ('Please specify a valid subcommand. For example: track <username>.' )
104
123
124
+ @CodegramBot .command (name = "activity" )
125
+ async def user_activity (ctx , username : str ):
126
+ try :
127
+ days = days_since_last_activity (username )
128
+ if days is None :
129
+ await ctx .send (f"{ username } has no accepted submissions on LeetCode." )
130
+ else :
131
+ await ctx .send (f"{ username } has not solved a problem in { days } days." )
132
+ except Exception as e :
133
+ await ctx .send (f"An error occurred: { e } " )
134
+
105
135
@CodegramBot .command ()
106
136
async def track (ctx , username : str ):
107
137
if username not in USERNAMES :
@@ -120,6 +150,43 @@ async def who_is_better(ctx, username1: str, username2: str):
120
150
except Exception as e :
121
151
await ctx .send (f"An error occurred: { e } " )
122
152
153
+
154
+ @CodegramBot .command (name = "grindset" )
155
+ async def grindset (ctx , username : str ):
156
+ try :
157
+ average = calculate_average_solved_per_day (username )
158
+ if average is None :
159
+ await ctx .send (f"Couldn't fetch data for { username } . They might not have solved any problems on LeetCode." )
160
+ return
161
+ await ctx .send (f"{ username } solves an average of { average :.2f} problem(s) per day." )
162
+ except Exception as e :
163
+ await ctx .send (f"An error occurred: { e } " )
164
+
165
+
166
+ def calculate_average_solved_per_day (username ):
167
+ # Fetch the earliest submission
168
+ submissions = getLatestAcceptedSubmits (username , limit = 1000 ) # Assuming no one solves more than 1000 problems in a day
169
+ if not submissions :
170
+ return None
171
+
172
+ first_submission_timestamp = min ([submission ['timestamp' ] for submission in submissions ])
173
+ if isinstance (first_submission_timestamp , str ):
174
+ first_submission_timestamp = int (first_submission_timestamp )
175
+
176
+ first_submission_date = datetime .fromtimestamp (first_submission_timestamp )
177
+ difference = datetime .utcnow () - first_submission_date
178
+ days_difference = difference .days
179
+
180
+ # Get total problems solved
181
+ stats = getSubmitStats (username )
182
+ if not stats :
183
+ return None
184
+ total_solved = sum ([d ['count' ] for d in stats ['submitStats' ]['acSubmissionNum' ]])
185
+
186
+ # Calculate the average
187
+ average = total_solved / days_difference
188
+ return average
189
+
123
190
def compare_users_stats (username1 , username2 ):
124
191
stats1 = getSubmitStats (username1 )
125
192
stats2 = getSubmitStats (username2 )
@@ -139,6 +206,41 @@ def compare_users_stats(username1, username2):
139
206
return f"{ username2 } has solved more problems than { username1 } ({ solved2 } vs { solved1 } )."
140
207
else :
141
208
return f"{ username1 } and { username2 } have solved the same number of problems ({ solved1 } )."
209
+ def display_user_stats (username ):
210
+ stats = getSubmitStats (username )
211
+ if not stats :
212
+ return f"Username { username } is invalid or not found."
213
+
214
+ total_solved = sum ([d ['count' ] for d in stats ['submitStats' ]['acSubmissionNum' ]])
215
+
216
+ # Formatting the data for output
217
+ stats_str = f"Statistics for { username } :\n "
218
+ stats_str += f"Total Problems Solved: { total_solved } \n "
219
+
220
+ for difficulty_stat in stats ['submitStats' ]['acSubmissionNum' ]:
221
+ stats_str += f"{ difficulty_stat ['difficulty' ]} Problems Solved: { difficulty_stat ['count' ]} out of { difficulty_stat ['submissions' ]} submissions\n "
222
+
223
+ return stats_str
224
+
225
+ bot .remove_command ('help' )
226
+
227
+ @CodegramBot .command (name = 'help' )
228
+ async def custom_help (ctx ):
229
+ help_str = "List of available commands under `CodegramBot`:\n "
230
+
231
+ for command in CodegramBot .walk_commands ():
232
+ help_str += f"!CodegramBot { command .name } \n "
233
+
234
+ await ctx .send (help_str )
235
+
236
+
237
+ @CodegramBot .command (name = "stats" )
238
+ async def user_stats (ctx , username : str ):
239
+ try :
240
+ stats_message = display_user_stats (username )
241
+ await ctx .send (stats_message )
242
+ except Exception as e :
243
+ await ctx .send (f"An error occurred: { e } " )
142
244
143
245
async def check_for_updates (username , channel_id ):
144
246
submissions = getLatestAcceptedSubmits (username )
0 commit comments