extends Node signal cache_done var _req_headers var _consts = preload("res://data/consts.gd") func _init() -> void: _req_headers = PackedStringArray(["User-Agent: " + _consts.APP_NAME + "/" + _consts.APP_VERSION, "Accept: */*"]) func _cache_error(err: String) -> String: return "CACHE::ERROR::" + err + "\n" func _get_dict_from_file(filepath: String) -> Dictionary: var file = FileAccess.open(filepath, FileAccess.READ) var data = JSON.parse_string(file.get_as_text()) return data ## get_card_data_from_name ## ## _name: String [br] ## A wrapper for searching for a card by name. Use **get_card_data_from_id** where possible, as it avoids an expensive search for the new card, if the card has been cached already. func get_card_data_from_name(_name: String) -> Dictionary: return _get_card_data_from_bulk("name", _name) ## get_card_data_from_id ## ## id: String [br] ## This is the preferred wrapper to use when fetching card data, it checks the cache for preexisting data and uses that if it's available. Otherwise, it will search the bulk json for the data. func get_card_data_from_id(id: String) -> Dictionary: if FileAccess.file_exists("user://card_cache/" + id + "/card.json"): return _get_dict_from_file("user://card_cache/" + id + "/card.json") return _get_card_data_from_bulk("id", id) func _get_card_data_from_bulk(field: String, search_query: String) -> Dictionary: var file = FileAccess.open("user://card_cache/bulk.json", FileAccess.READ) var bulk_json = JSON.parse_string(file.get_as_text()) var selected_entry = null for entry in bulk_json: if entry[field] == search_query: selected_entry = entry break continue file = null if selected_entry == null: return {} if selected_entry["image_status"] != "missing": _fetch_card_img(selected_entry) var dir = DirAccess.open("user://") dir.make_dir_recursive("user://card_cache/" + selected_entry["id"] + "/") dir = null file = FileAccess.open("user://card_cache/" + selected_entry["id"] + "/card.json", FileAccess.WRITE) file.store_line(JSON.stringify(selected_entry, "\t")) file = null return selected_entry func _fetch_card_img(data: Dictionary) -> Error: if FileAccess.file_exists("user://card_cache/" + data["id"] + "card.png"): return OK var httpr = HTTPRequest.new() add_child(httpr) var err = httpr.request((data["image_uris"])["png"], _req_headers) if err != OK: push_error(_cache_error("GET_REQUEST") + "An error occured in the Scryfall request.") return FAILED var resp = await httpr.request_completed var img = Image.new() err = img.load_png_from_buffer(resp[3]) if err != OK: push_error(_cache_error("IMG_LOADING") + "Couldn't load the image.") return FAILED var dir = DirAccess.open("user://") dir.make_dir_recursive("user://card_cache/" + data["id"] + "/") dir = null img.save_png("user://card_cache/" + data["id"] + "/card.png") img = null return OK func get_bulk_data(force: bool) -> Error: if FileAccess.file_exists("user://card_cache/bulk.json"): if force: DirAccess.remove_absolute("user://card_cahce/bulk.json") else: return OK var httpr = HTTPRequest.new() add_child(httpr) var error = httpr.request("https://api.scryfall.com/bulk-data/unique-artwork", _req_headers) if error != OK: push_error(_cache_error("GET_REQUEST") + "An error occurred in the Scryfall request.") return FAILED var response = await httpr.request_completed if response[0] != HTTPRequest.RESULT_SUCCESS: push_error(_cache_error("GET_REQUEST") + "Failed to fetch card data from Scryfall") return FAILED var unprocessed_body = response[3].get_string_from_utf8() var card_content = JSON.parse_string(unprocessed_body) if card_content == null: push_error(_cache_error("PARSING") + "Failed to parse the Scryfall card results.") return FAILED error = httpr.request(card_content["download_uri"], _req_headers) if error != OK: push_error(_cache_error("GET_REQUEST") + "An error occurred in the Scryfall request.") return FAILED response = await httpr.request_completed if response[0] != HTTPRequest.RESULT_SUCCESS: push_error(_cache_error("GET_REQUEST") + "Failed to fetch card data from Scryfall") return FAILED unprocessed_body = response[3].get_string_from_utf8() card_content = JSON.parse_string(unprocessed_body) if card_content == null: push_error(_cache_error("PARSING") + "Failed to parse the Scryfall card results.") return FAILED var dir = DirAccess.open("user://") dir.make_dir_recursive("user://card_cache/") # lets ensure the path is there dir = null var data_cache = FileAccess.open("user://card_cache/bulk.json", FileAccess.WRITE) data_cache.store_string(unprocessed_body) data_cache = null cache_done.emit() return OK