# -*- coding: utf-8 -*- # vim: set fileencoding=utf-8 : """ Downloads all Entries of a BotB Battle, both the Source and the render. Author: @kleeder Created: 2022-04-28 Modified version: emtries.com """ import json import re import requests import os cookies = { "user_id": "12345", "serial": "1a2b3c", "botbr_id": "54321" } battle_id = "10884" start_after_entry_id = None end_entry_id = None battle_dir = "." botb_url = "https://battleofthebits.com" botb_api = f"{botb_url}/api/v1/" url = f"{botb_api}battle/load/{battle_id}" json_data = requests.get(url, cookies=cookies).json() battle_name = json_data['title'] battle_path = f"{battle_dir}/{battle_name}" print(f"Starting donload for {battle_name}") data_file = f"{battle_path}/data.json" try: json_data = json.load(open(data_file, "r")) print(f"Using existing data file") except FileNotFoundError: print(f"Creating new directories and fetching data file") os.mkdir(battle_path) os.mkdir(f"{battle_path}/metadata") os.mkdir(f"{battle_path}/sourcefiles") os.mkdir(f"{battle_path}/renders") url = lambda p: f"{botb_api}entry/list/{p}/500/?filters=battle_id~{battle_id}" page = 0 json_data = [] current_data = requests.get(url(page), cookies=cookies).json() while len(current_data) != 0: print(f"Fetched page {page}") json_data.extend(current_data) page += 1 current_data = requests.get(url(page), cookies=cookies).json() print(f"Fetched {page} page{'' if page == 1 else 's'}") json.dump(json_data, open(data_file, "x")) for entry in json_data: if start_after_entry_id: if entry['id'] == start_after_entry_id: start_after_entry_id = None continue with open(f"{battle_path}/metadata/{entry['id']}.json", 'w') as outfile: json.dump(entry, outfile) json.dumps(entry) file_format = re.search("\.[^.]*$", entry['view_url']) file_format = file_format.string[file_format.regs[0][0]:file_format.regs[0][1]] response = requests.get(f"{botb_url}{entry['donload_url']}", cookies=cookies) entry['title'] = re.sub(r'[<>:"/\\|?*~]', '_', entry['title']) # Windows sanitization open(f"{battle_path}/sourcefiles/BotB {entry['id']} {entry['authors_display']} - {entry['title']}{file_format}", "wb").write(response.content) if entry.get('medium_visual', False): if not entry['view_url']: print(f"No render for Entry: {entry['id']}") else: response = requests.get(f"{botb_url}{entry['view_url']}", cookies=cookies) file_format = re.search("\.[^.]*$", entry['view_url']) file_format = file_format.string[file_format.regs[0][0]:file_format.regs[0][1]] if entry.get('medium_audio', False): if not entry['play_url']: print(f"No render for Entry: {entry['id']}") else: response = requests.get(f"{entry['play_url']}", cookies=cookies) file_format = ".mp3" try: open(f"{battle_path}/renders/BotB {entry['id']} {entry['authors_display']} - {entry['title']}{file_format}", "wb").write(response.content) except FileNotFoundError: print(f"Failed to get render for Entry: {entry['id']}") print(f"Saved Entry: {entry['id']}") if end_entry_id and entry['id'] == end_entry_id: break