1
+ import datetime
1
2
import os
2
3
import re
3
4
import shutil
7
8
import discord
8
9
from discord .ext import commands
9
10
11
+ import util
10
12
from bot import COOL_CRAB , PENDING_FIXES_CHANNEL , FLASH_GAMES_CHANNEL , OTHER_GAMES_CHANNEL , ANIMATIONS_CHANNEL , \
11
13
is_bot_guy
12
14
from curation_validator import get_launch_commands_bluebot
@@ -72,13 +74,13 @@ async def approve(self, ctx: discord.ext.commands.Context, jump_url: str):
72
74
await message .remove_reaction (reaction .emoji , self .bot .user )
73
75
await message .add_reaction ("🤖" )
74
76
75
- @commands .command (name = "get-fixes" , hidden = True )
76
- @commands .has_role ("Administrator " )
77
+ @commands .command (name = "get-fixes" )
78
+ @commands .has_role ("Moderator " )
77
79
@commands .max_concurrency (1 , per = commands .BucketType .default , wait = False )
78
80
async def automatic_get_jsons (self , ctx : discord .ext .commands .Context , last_message_url : Optional [str ]):
79
81
l .debug (
80
82
f"pending fixes command invoked from { ctx .author .id } in channel { ctx .channel .id } - { ctx .message .jump_url } " )
81
- temp_folder = tempfile . mkdtemp ( prefix = 'pending_fixes' )
83
+
82
84
if last_message_url is not None :
83
85
await ctx .send (
84
86
f"Getting all jsons in #pending-fixes not marked with a ⚠️ before <{ last_message_url } > and after the pin. "
@@ -96,19 +98,14 @@ async def automatic_get_jsons(self, ctx: discord.ext.commands.Context, last_mess
96
98
l .debug (f"fetching message { message_id } " )
97
99
channel = self .bot .get_channel (channel_id )
98
100
message = await channel .fetch_message (message_id )
99
- all_json_messages = await get_raw_json_messages_in_pending_fixes (message )
101
+ final_folder , start_date , end_date = await self . get_raw_json_messages_in_pending_fixes (message )
100
102
else :
101
- await ctx .send (f"Getting all jsons in #pending-fixes not marked with a ⚠️since the pin. "
103
+ await ctx .send (f"Getting all jsons in #pending-fixes not marked with a ⚠ ️since the pin. "
102
104
f"Sit back and relax, this will take a while { COOL_CRAB } ." )
103
- all_json_messages = await get_raw_json_messages_in_pending_fixes (None )
104
- for msg in all_json_messages :
105
- l .debug (f"Downloading json { msg .attachments [0 ].filename } from message { msg .id } " )
106
- await msg .attachments [0 ].save (temp_folder + '/' + msg .attachments [0 ].filename )
107
- last_date = all_json_messages [0 ].created_at .date ().strftime ('%Y-%m-%d' )
108
- first_date = all_json_messages [- 1 ].created_at .date ().strftime ('%Y-%m-%d' )
109
- archive = shutil .make_archive (f'pending_fixes { first_date } to { last_date } ' , 'zip' , temp_folder )
105
+ final_folder , start_date , end_date = await self .get_raw_json_messages_in_pending_fixes (None )
106
+ archive = shutil .make_archive (f'pending_fixes { start_date } to { end_date } ' , 'zip' , final_folder )
110
107
await ctx .send (file = discord .File (archive ))
111
- shutil .rmtree (temp_folder , True )
108
+ shutil .rmtree (final_folder , True )
112
109
os .remove (archive )
113
110
114
111
@commands .command (name = "hell" , hidden = True )
@@ -129,7 +126,7 @@ async def hell(self, ctx: discord.ext.commands.Context, channel_alias: str):
129
126
await ctx .channel .send (f"Measuring the length of Blue's curation journey through hell. "
130
127
f"Sit back and relax, this will take a while { COOL_CRAB } ." )
131
128
132
- messages = await hell_counter (channel_id )
129
+ messages = await self . hell_counter (channel_id )
133
130
if len (messages ) > 0 :
134
131
await ctx .channel .send (
135
132
f"Blue's curation journey in `{ channel_alias } ` channel is `{ len (messages )} ` messages long.\n "
@@ -195,27 +192,33 @@ async def hell_counter(self, channel_id: int) -> list[discord.Message]:
195
192
if user .id == BLUE_ID :
196
193
return messages [:message_counter ]
197
194
198
- async def get_raw_json_messages_in_pending_fixes (self , oldest_message : Optional [discord .Message ]) -> list [
199
- discord .Message ]:
195
+ async def get_raw_json_messages_in_pending_fixes (self , newest_message : Optional [discord .Message ]) -> Optional [tuple [str , str , str ]]:
200
196
message_counter = 0
201
197
batch_size = 1000
202
198
all_messages : list [discord .Message ] = []
203
- messages_with_valid_json : list [discord .Message ] = []
199
+ downloaded_attachments : list [str ] = []
200
+ temp_folder = tempfile .mkdtemp (prefix = 'pending_fixes' )
204
201
205
202
channel : discord .TextChannel = self .bot .get_channel (PENDING_FIXES_CHANNEL )
206
- pins = await channel .pins ()
203
+ pins : list [discord .Message ] = await channel .pins ()
204
+ start_date = max ([pin .created_at for pin in pins ]).date ().strftime ('%Y-%m-%d' )
205
+ if newest_message is None :
206
+ end_date = datetime .date .today ().strftime ('%Y-%m-%d' )
207
+ else :
208
+ end_date = newest_message .created_at .date ().strftime ('%Y-%m-%d' )
209
+ uuid_regex = re .compile (r"^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}" )
207
210
while True :
208
- if oldest_message is None :
211
+ if newest_message is None :
209
212
l .debug (f"getting { batch_size } messages..." )
210
213
message_batch : list [discord .Message ] = await channel .history (limit = batch_size ).flatten ()
211
214
else :
212
- l .debug (f"getting { batch_size } messages from { oldest_message .jump_url } ..." )
215
+ l .debug (f"getting { batch_size } messages from { newest_message .jump_url } ..." )
213
216
message_batch : list [discord .Message ] = await channel .history (limit = batch_size ,
214
- before = oldest_message ).flatten ()
217
+ before = newest_message ).flatten ()
215
218
if len (message_batch ) == 0 :
216
219
l .warn (f"no messages found, weird." )
217
- return all_messages
218
- oldest_message = message_batch [- 1 ]
220
+ return None
221
+ newest_message = message_batch [- 1 ]
219
222
all_messages .extend (message_batch )
220
223
221
224
l .debug ("processing messages..." )
@@ -224,25 +227,36 @@ async def get_raw_json_messages_in_pending_fixes(self, oldest_message: Optional[
224
227
message_counter += 1
225
228
if len (msg .attachments ) != 1 :
226
229
continue
227
- is_json = False
228
- if msg .attachments [0 ].filename .endswith ('.json' ):
229
- is_json = True
230
230
reactions = msg .reactions
231
231
if len (reactions ) > 0 :
232
232
l .debug (f"analyzing reactions for msg { msg .id } - message { message_counter } ..." )
233
233
should_be_manual = False
234
- found_pin = False
235
234
for reaction in reactions :
236
235
if reaction .emoji == "⚠️" :
237
236
should_be_manual = True
238
- if msg in pins :
239
- found_pin = True
240
- if not should_be_manual and is_json :
241
- messages_with_valid_json .append (msg )
237
+ attachment_filename = msg .attachments [0 ].filename
238
+ if attachment_filename .endswith ('.json' ) and not should_be_manual :
239
+ l .debug (f"Downloading json { attachment_filename } from message { msg .id } " )
240
+ num_duplicates = downloaded_attachments .count (attachment_filename )
241
+ downloaded_attachments .append (attachment_filename )
242
+ if num_duplicates == 0 :
243
+ await msg .attachments [0 ].save (temp_folder + '/' + attachment_filename )
244
+ else :
245
+ await msg .attachments [0 ].save (temp_folder + '/dupe' + str (num_duplicates ) + "-" + attachment_filename )
246
+ elif attachment_filename .endswith ('.zip' ) or attachment_filename .endswith ('.7z' ) and not should_be_manual :
247
+ l .debug (f"Downloading archive { attachment_filename } from message { msg .id } " )
248
+ num_duplicates = downloaded_attachments .count (attachment_filename )
249
+ downloaded_attachments .append (attachment_filename )
250
+ if num_duplicates == 0 :
251
+ save_location = temp_folder + '/' + attachment_filename
252
+ else :
253
+ save_location = temp_folder + '/dupe' + str (num_duplicates ) + "-" + attachment_filename
254
+ await msg .attachments [0 ].save (save_location )
255
+ if not [x for x in util .get_archive_filenames (save_location ) if uuid_regex .match (x )]:
256
+ os .remove (save_location )
257
+ found_pin = msg in pins
242
258
if found_pin :
243
- l .debug (f"message filter searched { len (all_messages )} messages "
244
- f"and found { len (messages_with_valid_json )} which were usable jsons." )
245
- return messages_with_valid_json
259
+ return temp_folder , start_date , end_date
246
260
247
261
248
262
def setup (bot : commands .Bot ):
0 commit comments