@tool @icon("res://UI/assets/font_awesome/itch-io.svg") extends Node class_name ItchIOService static var _log: TwitchLogger = TwitchLogger.new(&"ItchIOService") #region RegEx HTML Scrapping static var _desc_re: RegEx = RegEx.create_from_string(r'(?s)
(.*?)<\/div>') static var _div_re: RegEx = RegEx.create_from_string(r'(?s)
(.*?)<\/div>') static var _ss_thumb_re: RegEx = RegEx.create_from_string(r']+src="([^"]+/\d+x\d+/[^"]+)"') static var _ss_full_re: RegEx = RegEx.create_from_string(r']+href=\"([^"]+\/original\/[^"]+)"') #endregion func get_itch_app_data(game_url: String) -> ItchIOAppData: var http_request = HTTPRequest.new() add_child(http_request) var base_url := game_url.strip_edges().rstrip("/") var json_url := base_url + "/data.json" var err := http_request.request(json_url) if err != OK: _log.e("Error requesting Itch data: %s" % error_string(err)) return null var json_result: Array = await http_request.request_completed var _result: int = json_result[0] var response_code: int = json_result[1] var body: PackedByteArray = json_result[3] if response_code != HTTPClient.RESPONSE_OK: _log.e("Failed to fetch Itch data.json. HTTP %s" % response_code) return null var json = JSON.parse_string(body.get_string_from_utf8()) if typeof(json) != TYPE_DICTIONARY: _log.e("Invalid JSON from Itch") return null err = http_request.request(base_url) if err != OK: _log.e("Error requesting Itch HTML: %s" % error_string(err)) return ItchIOAppData.from_json(json) var html_result: Array = await http_request.request_completed var html_code: int = html_result[1] var html_body: PackedByteArray = html_result[3] if html_code == HTTPClient.RESPONSE_OK: var html := html_body.get_string_from_utf8() var extra_info: Dictionary = scrape_html(html) json.merge(extra_info) else: _log.e("Could not retrieve HTML content. Skipping description/screenshot parsing.") http_request.queue_free() return ItchIOAppData.from_json(json) func scrape_html(html: String) -> Dictionary: var data := { "description": "", "screenshots_thumbnails": [], "screenshots_full": [], } var desc_match: RegExMatch = _desc_re.search(html) if desc_match: data["description"] = Util.convert_html_to_bbcode(desc_match.get_string(1)) var div_match := _div_re.search(html) if div_match: var screenshot_block: String = div_match.get_string(1) var ss_thumb_matches: Array[RegExMatch] = _ss_thumb_re.search_all(screenshot_block) for s_match: RegExMatch in ss_thumb_matches: data["screenshots_thumbnails"].append(s_match.get_string(1)) var ss_full_matches: Array[RegExMatch] = _ss_full_re.search_all(screenshot_block) for s_match: RegExMatch in ss_full_matches: data["screenshots_full"].append(s_match.get_string(1)) return data