Advertisement
Guest User

Untitled

a guest
Jan 25th, 2018
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.15 KB | None | 0 0
  1. # osu! ranked/loved map checker by G3T v1.1
  2.  
  3. import time
  4. import datetime
  5. import urllib.request
  6. import json
  7. import os
  8. import hashlib
  9. import collections
  10.  
  11. start_date_stamp = '2007-10-07'
  12. date_format = '%Y-%m-%d'
  13. page_date = datetime.datetime.strptime(start_date_stamp, date_format)
  14. api_key = ''
  15. db = {}
  16.  
  17. def get_next_date(ordered_dict):
  18.     bm_key = next(reversed(ordered_dict))
  19.     bm = ordered_dict[bm_key]
  20.     date_str = (bm['approved_date'].split(' '))[0]
  21.     return datetime.datetime.strptime(date_str, date_format)
  22.  
  23. def get_page(key, date):
  24.     url_base = 'https://osu.ppy.sh/api/get_beatmaps?'
  25.     url = url_base + 'k=' + key + '&since=' + date.strftime(date_format) + '&m=0'
  26.     page = urllib.request.urlopen(url)
  27.     return page.read()
  28.  
  29. def get_api_key():
  30.     print('The api key can be found at https://osu.ppy.sh/p/api')
  31.     api_key = input('Key: ')
  32.     try:
  33.         test = get_page(api_key, page_date)
  34.     except urllib.error.HTTPError:
  35.         print('That key is invalid, try again.')
  36.         return get_api_key()
  37.     return api_key
  38.  
  39. def md5(fname):
  40.     hash_md5 = hashlib.md5()
  41.     with open(fname, "rb") as f:
  42.         for chunk in iter(lambda: f.read(4096), b""):
  43.             hash_md5.update(chunk)
  44.     return hash_md5.hexdigest()
  45.  
  46. # Get API key
  47. if os.access('api_key', os.F_OK):
  48.     with open('api_key', 'r') as key_file:
  49.         api_key = key_file.readline().strip()
  50. else:
  51.     api_key = get_api_key()
  52.     with open('api_key', 'w') as key_file:
  53.         key_file.write(api_key)
  54.  
  55. # Get md5/mtime db
  56. if os.access('md5_mtime_db', os.F_OK):
  57.     with open('md5_mtime_db', 'r') as mmdb:
  58.         db = json.loads(mmdb.read())
  59.        
  60. # Get a list of all beatmap md5s in songs folder
  61. walk = next(os.walk('.\\Songs'))
  62. dirs = walk[1]
  63. path = walk[0]
  64. md5s = {}
  65. for i, d in enumerate(dirs):
  66.     print('Scanning songs folder... [maps: {:d} ({:.2f}%)]'.format(len(md5s), (i/len(dirs)) * 100), end='\r')
  67.     dir_path = os.path.join(path, d)
  68.     files = next(os.walk(dir_path))[2]
  69.     for f in files:
  70.         if f[-3:] == 'osu':
  71.             rel_path = os.path.join(d, f)
  72.             abs_path = os.path.join(dir_path, f)
  73.             f_mtime = os.path.getmtime(abs_path)
  74.             if (rel_path in db) and (db[rel_path][0] == f_mtime):
  75.                 md5s[db[rel_path][1]] = None
  76.             else:
  77.                 f_md5 = md5(abs_path)
  78.                 md5s[f_md5] = None
  79.                 db[rel_path] = (f_mtime, f_md5)
  80.  
  81. with open('md5_mtime_db', 'w') as mmdb:
  82.     mmdb.write(json.dumps(db))
  83.            
  84. print('Scanning songs folder... [maps: {:d} (100%)]  '.format(len(md5s)))
  85.  
  86. # Get a dictionary of all ranked standard maps
  87. if os.access('ranked_maps.json', os.F_OK):
  88.     with open('ranked_maps.json', 'r') as rmj:
  89.         maps = collections.OrderedDict(json.loads(rmj.read()))
  90.         page_date = get_next_date(maps)
  91. else:
  92.     maps = collections.OrderedDict([])
  93.  
  94. num_maps = -1
  95.  
  96. while (num_maps != len(maps)):
  97.     num_maps = len(maps)
  98.     print('Downloading ranked/loved map list... [maps: {:d}]'.format(num_maps), end='\r')
  99.    
  100.     page = get_page(api_key, page_date)
  101.     parsed_page = json.loads(page)
  102.  
  103.     for bm in parsed_page:
  104.         if bm['approved'] != '3':
  105.             maps[bm['file_md5']] = bm
  106.    
  107.     page_date = get_next_date(maps)
  108.  
  109.     time.sleep(1.1)
  110.  
  111. print('Downloading ranked/loved map list... [maps: {:d}]'.format(num_maps))
  112.  
  113. with open('ranked_maps.json', 'w') as rmj:
  114.     rmj.write(json.dumps(maps))
  115.  
  116. # Generate a set of all mapsets that are not present
  117. missing = {}
  118. ranked = 0
  119. loved = 0
  120. errors = 0
  121.  
  122. for key in maps:
  123.     if maps[key]['approved'] == '4':
  124.         loved += 1
  125.     elif maps[key]['approved'] in ('1', '2'):
  126.         ranked += 1
  127.     else:
  128.         errors += 1
  129.     if key not in md5s:
  130.         missing[maps[key]['beatmapset_id']] = None
  131.  
  132. print('Map composition:')
  133. print('    Ranked:  ' + str(ranked))
  134. print('    Loved:   ' + str(loved))
  135. print('    Unknown: ' + str(errors))
  136.  
  137. if len(missing.keys()) == 0:
  138.     print('All ranked/loved maps accounted for.')
  139. else:
  140.     print('Missing maps by song id:')
  141.     for key in missing.keys():
  142.         print(key)
  143.  
  144. input('Press any key to exit...')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement