6
6
import requests
7
7
import aiohttp
8
8
import webbrowser
9
+ import time
9
10
10
11
import ModuleUpdate
11
12
@@ -211,7 +212,7 @@ def get_played_ids(self):
211
212
song_index = item .item - 727000000
212
213
location_id = (song_index * 2 )+ 727000000
213
214
if location_id < 727000000 : continue
214
- if location_id not in self .ctx .missing_locations and location_id + 1 not in self .ctx .missing_locations :
215
+ if ( location_id not in self .ctx .missing_locations and location_id + 1 not in self .ctx .missing_locations ) and song_index not in played_items :
215
216
played_items .append (song_index )
216
217
played_items .sort ()
217
218
return played_items
@@ -255,7 +256,40 @@ def check_location(self, score):
255
256
async def download_beatmapset (self , beatmapset ):
256
257
print (f'Downloading { beatmapset ["artist" ]} - { beatmapset ["title" ]} ({ beatmapset ["id" ]} )' )
257
258
async with aiohttp .request ("GET" , f"https://beatconnect.io/b/{ beatmapset ['id' ]} " ) as req :
258
- content = await req .read ()
259
+ content_length = req .headers .get ('Content-Length' )
260
+
261
+ # With beatconnect we always know the total size of the download, so this is always true
262
+ if content_length is not None :
263
+ total_bytes = int (content_length )
264
+ total_mb = total_bytes / (1024 ** 2 )
265
+ # Beatconnect is slow to respond, so this message will appear when the download starts unlike when you run the command
266
+ self .output (f"Starting download of beatmapset ({ total_mb :.2f} MB)" )
267
+
268
+ downloaded_content = []
269
+ downloaded_bytes = 0
270
+ last_print_time = time .time ()
271
+ async for chunk in req .content .iter_any ():
272
+ downloaded_content .append (chunk )
273
+ downloaded_bytes += len (chunk )
274
+ downloaded_mb = downloaded_bytes / (1024 ** 2 )
275
+
276
+ # If we know the total size, calculate the progress
277
+ if content_length is not None :
278
+ progress = min (100 , int (downloaded_bytes / total_bytes * 100 ))
279
+
280
+ # Check if at least half a second has passed since last print or if the download is done
281
+ # Filesizes are small enough that we can do half a second intervals instead of 1 second
282
+ current_time = time .time ()
283
+ if current_time - last_print_time >= 0.5 or downloaded_bytes == total_bytes :
284
+ self .output (f"Downloaded: { downloaded_mb :.2f} MB / { total_mb :.2f} MB ({ progress } %)" )
285
+ last_print_time = current_time
286
+
287
+ # If we don't know the total size, just print the downloaded amount
288
+ else :
289
+ self .output (f"Downloaded: { downloaded_mb :.2f} MB" )
290
+
291
+ # Combine all the chunks into one just like req.read() would do
292
+ content = b"" .join (downloaded_content )
259
293
if len (content ) < 400 :
260
294
self .output (f'Error Downloading { beatmapset ["id" ]} { beatmapset ["artist" ]} - { beatmapset ["title" ]} .osz' )
261
295
self .output ('Please Manually Add the Map or Try Again Later.' )
@@ -265,6 +299,7 @@ async def download_beatmapset(self, beatmapset):
265
299
path = self .ctx .game_communication_path + ' config'
266
300
with open (os .path .join (path , filename ), 'wb' ) as f :
267
301
f .write (content )
302
+ self .output (f'Opening { filename } ...' ) # More feedback to the user
268
303
webbrowser .open (os .path .join (path , filename ))
269
304
270
305
0 commit comments