8
8
from discord .ext import commands , tasks
9
9
from PIL import Image
10
10
from enum import Enum
11
- from typing import Dict , List , Tuple
11
+ from typing import Dict , List , Tuple , Optional , cast
12
12
from matplotlib import pyplot as plt
13
13
from pymongo .errors import ServerSelectionTimeoutError
14
14
@@ -126,7 +126,7 @@ async def cog_load(self):
126
126
127
127
@commands .Cog .listener ()
128
128
async def on_ready (self ):
129
- if not self .save_guilds .is_running ():
129
+ if not self .save_guilds .is_running () and not self . client . is_dev :
130
130
self .save_guilds .start ()
131
131
if not self .vote_reminders .is_running ():
132
132
self .vote_reminders .start ()
@@ -171,10 +171,13 @@ async def vote_reminders(self):
171
171
if (
172
172
self ._date_helper (data ["last_vote" ].hour )
173
173
== self ._date_helper (datetime .now ().hour )
174
- and data ["last_vote" ].minute == datetime .now ().minute
174
+ and cast (datetime , data ["last_vote" ]).minute
175
+ == datetime .now ().minute
175
176
and not (
176
177
int (int (datetime .now ().timestamp ()) / 60 )
177
- == int (int (data ["last_vote" ].timestamp ()) / 60 )
178
+ == int (
179
+ int (cast (datetime , data ["last_vote" ]).timestamp ()) / 60
180
+ )
178
181
)
179
182
): # If they are the same amounts of minutes away from the unix epoch
180
183
@@ -221,7 +224,30 @@ async def vote_reminders(self):
221
224
async def save_guilds (self ):
222
225
from killua .static .constants import daily_users
223
226
224
- if not self .client .is_dev and self .skipped_first :
227
+ # Arguably this is a much better way of doing this as otherwise
228
+ # if the bot restarts this will be ignored for a day.
229
+ # While that's true, this could lead to daily users being
230
+ # 0 if it just ran after 24hrs since it is only saved during
231
+ # runtime. I don't want this so I will keep it as it is.
232
+ #
233
+ # Check when the last stats were saved
234
+ # last = await DB.const.find_one({"_id": "growth"})
235
+ # if not last:
236
+ # return
237
+ # last = last["growth"][-1]["date"]
238
+
239
+ # If it has been more than 24 hours since the last save
240
+ if self .skipped_first :
241
+ logging .debug (PrintColors .OKBLUE + "Saving stats:" )
242
+ logging .debug (
243
+ "Guilds: {} | Users: {} | Registered Users: {} | Daily Users: {}{}" .format (
244
+ len (self .client .guilds ),
245
+ len (self .client .users ),
246
+ await DB .teams .count_documents ({}),
247
+ len (daily_users .users ),
248
+ PrintColors .ENDC ,
249
+ )
250
+ )
225
251
await DB .const .update_one (
226
252
{"_id" : "growth" },
227
253
{
@@ -238,12 +264,8 @@ async def save_guilds(self):
238
264
)
239
265
if self .client .run_in_docker :
240
266
DAILY_ACTIVE_USERS .set (len (daily_users .users ))
241
- daily_users .users = (
242
- []
243
- ) # Resetting the daily users list lgtm [py/unused-local-variable]
244
- elif (
245
- not self .skipped_first
246
- ): # We want to avoid saving data each time the bot restarts, start 24h after one
267
+ daily_users .users = [] # Resetting the daily users list
268
+ else : # We want to avoid saving data each time the bot restarts, start 24h after one
247
269
self .skipped_first = True
248
270
249
271
@commands .Cog .listener ()
@@ -269,7 +291,7 @@ async def on_member_join(self, member: discord.Member):
269
291
{
270
292
"title" : "Welcome to the Killua support server a.k.a. Kile's dev!" ,
271
293
"description" : "You joined. What now?\n \n **Where to go**\n "
272
- + "┗ <#1019657047568035841> to recieve help or report bugs\n "
294
+ + "┗ <#1019657047568035841> to receive help or report bugs\n "
273
295
+ "┗ <#787819439596896288> To get some ping roles\n "
274
296
+ "┗ <#886546434663538728> Good place to check before asking questions\n "
275
297
+ "┗ <#754063177553150002> To see newest announcements\n "
@@ -499,7 +521,7 @@ def _parse_votes_for(
499
521
],
500
522
(
501
523
[v for v in custom_id .split (":" )[2 ].split ("," ) if v != "" ]
502
- if not custom_id .split (":" )[ 2 ]. isdigit ()
524
+ if len ( custom_id .split (":" )) > 2
503
525
else []
504
526
),
505
527
)
@@ -543,7 +565,11 @@ async def _process_vote_with_compression(
543
565
action : str ,
544
566
poll : bool ,
545
567
opt_votes : str ,
546
- ) -> Dict [int , Tuple [List [int ], List [str ]]]:
568
+ ) -> Optional [Dict [int , Tuple [List [int ], List [str ]]]]:
569
+ """
570
+ If a None is returned, an error was sent and the execution should stop.
571
+ Else the votes are returned.
572
+ """
547
573
votes : Dict [int , Tuple [List [int ], List [str ]]] = {}
548
574
# This took me a bit to figure out when revisiting this
549
575
# code. What is actually being stored here for each option
@@ -583,11 +609,10 @@ async def _process_vote_with_compression(
583
609
or re .findall (rf";{ pos + 1 } ;[^;:]*{ encrypted } (.*?)[;:]" , old_close )
584
610
) and pos == option - 1 :
585
611
# Already voted for this option
586
- await interaction .response .send_message (
612
+ return await interaction .response .send_message (
587
613
f"You already { 'voted for' if poll else 'chose' } this option!" ,
588
614
ephemeral = True ,
589
615
)
590
- return
591
616
592
617
if interaction .user .id in votes [pos ][0 ]:
593
618
votes [pos ][0 ].remove (interaction .user .id )
@@ -626,9 +651,7 @@ async def _process_vote_with_compression(
626
651
# custom ID to update
627
652
votes [option - 1 ][1 ].append (encrypted )
628
653
interaction .message .components [0 ].children [option - 1 ].custom_id = (
629
- "poll"
630
- if poll
631
- else "wyr"
654
+ ("poll" if poll else "wyr" )
632
655
+ ":"
633
656
+ action
634
657
+ ":"
@@ -658,17 +681,16 @@ async def _process_vote_with_compression(
658
681
)
659
682
)
660
683
if poll :
661
- await interaction .response .send_message (
684
+ return await interaction .response .send_message (
662
685
f"The maximum votes on this { 'poll' if poll else 'wyr' } has been reached! Make this a premium server to allow more votes! Please that votes started before becomind a premium server will still not be able to recieve more votes." ,
663
686
ephemeral = True ,
664
687
view = view ,
665
688
)
666
689
else :
667
- await interaction .response .send_message (
690
+ return await interaction .response .send_message (
668
691
f"The maximum votes on this { 'poll' if poll else 'wyr' } has been reached!" ,
669
692
ephemeral = True ,
670
693
)
671
- return
672
694
return votes
673
695
674
696
async def _process_vote_with_db (
@@ -713,7 +735,7 @@ def _set_new_field_name_for_unsaved(
713
735
interaction : discord .Interaction ,
714
736
poll : bool ,
715
737
option : int ,
716
- ):
738
+ ) -> Tuple [ str , str ] :
717
739
close_votes = re .findall (
718
740
rf";{ pos + 1 } ;(.*?)[;:]" ,
719
741
interaction .message .components [0 ].children [- 1 ].custom_id ,
@@ -815,6 +837,9 @@ async def _process_vote(
815
837
else :
816
838
votes = await self ._process_vote_with_db (interaction , guild , option , poll )
817
839
840
+ if votes is None :
841
+ return
842
+
818
843
embed = interaction .message .embeds [0 ]
819
844
820
845
new_embed = discord .Embed (
@@ -859,7 +884,7 @@ async def _process_votable(self, interaction: discord.Interaction) -> None:
859
884
"""
860
885
if (
861
886
interaction .data ["custom_id" ].split (":" )[2 ].isdigit ()
862
- ): # Backwards compatability
887
+ ): # Backwards compatibility
863
888
split = interaction .data ["custom_id" ].split (":" )
864
889
_p = split [0 ]
865
890
action = split [1 ]
@@ -899,12 +924,15 @@ async def _process_votable(self, interaction: discord.Interaction) -> None:
899
924
900
925
@commands .Cog .listener ()
901
926
async def on_interaction (self , interaction : discord .Interaction ):
902
- if interaction .type == discord .InteractionType .component :
903
- if interaction .data ["custom_id" ] and (
927
+ if (
928
+ interaction .type == discord .InteractionType .component
929
+ and interaction .data ["custom_id" ]
930
+ and (
904
931
interaction .data ["custom_id" ].startswith ("poll:" )
905
932
or interaction .data ["custom_id" ].startswith ("wyr:" )
906
- ):
907
- await self ._process_votable (interaction )
933
+ )
934
+ ):
935
+ await self ._process_votable (interaction )
908
936
909
937
@commands .Cog .listener ()
910
938
async def on_command_error (self , ctx : commands .Context , error ):
0 commit comments