You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Babushka/addons/languagetool/scripts/languagte_tool_api_wrapper.gd

212 lines
7.0 KiB

@tool
class_name LanguageToolApiWrapper
extends Node
const BASE_URL := "https://api.languagetoolplus.com/v2"
func _make_request(endpoint: String, method: HTTPClient.Method = HTTPClient.METHOD_GET, data: Dictionary = {}, headers: Dictionary = {}):
var url = BASE_URL + endpoint
var scheme_split = url.split("://")
var scheme = scheme_split[0]
var rest = scheme_split[1]
var host_and_path = rest.split("/", false, 1)
var host = host_and_path[0]
var path = "/" + host_and_path[1] if host_and_path.size() > 1 else "/"
var port = 443 if scheme == "https" else 80
var client = HTTPClient.new()
var tlsOptions: TLSOptions = (TLSOptions.client() if scheme == "https" else null)
var err = client.connect_to_host(host, port, tlsOptions)
if err != OK:
push_error("Failed to connect to host: " + str(err))
return null
while client.get_status() in [HTTPClient.STATUS_CONNECTING, HTTPClient.STATUS_RESOLVING]:
client.poll()
OS.delay_msec(10)
var header_array = []
for k in headers.keys():
header_array.append(str(k) + ": " + str(headers[k]))
var body = ""
if method == HTTPClient.METHOD_POST:
body = ""
if data.size() > 0:
body = client.query_string_from_dict(data)
header_array.append("Content-Type: application/x-www-form-urlencoded")
header_array.append("Content-Length: " + str(body.length()))
client.request(HTTPClient.METHOD_POST, path, header_array, body)
else:
if data.size() > 0:
path += "?" + client.query_string_from_dict(data)
client.request(HTTPClient.METHOD_GET, path, header_array)
while client.get_status() == HTTPClient.STATUS_REQUESTING:
client.poll()
OS.delay_msec(10)
var response = ""
while client.get_status() == HTTPClient.STATUS_BODY or client.has_response():
client.poll()
var chunk = client.read_response_body_chunk()
if chunk.size() == 0:
break
response += chunk.get_string_from_utf8()
OS.delay_msec(10)
var resp_code = client.get_response_code()
if resp_code != 200:
push_error("HTTP error: " + str(resp_code) + "\\n" + response)
return null
var json = JSON.new()
var json_err = json.parse(response)
if json_err != OK:
push_error("JSON parse error: " + str(json_err) + "\\n" + response)
return null
return json.get_data()
func check(text: String, language: String = "auto", opts: Dictionary = {}) -> LanguageToolCheckResponse:
var data = {
"text": text,
"language": language
}
for k in opts.keys():
data[k] = opts[k]
print("Checking text: "+text)
return LanguageToolCheckResponse.new(_make_request("/check", HTTPClient.METHOD_POST, data))
func get_languages():
return _make_request("/languages", HTTPClient.METHOD_GET)
func list_words(username: String, apiKey: String, offset: int = 0, limit: int = 10, dicts: String = ""):
var data = {
"username": username,
"apiKey": apiKey,
"offset": offset,
"limit": limit
}
if dicts != "":
data["dicts"] = dicts
return _make_request("/words", HTTPClient.METHOD_GET, data)
func add_word(word: String, username: String, apiKey: String, dict: String = ""):
var data = {
"word": word,
"username": username,
"apiKey": apiKey
}
if dict != "":
data["dict"] = dict
return _make_request("/words/add", HTTPClient.METHOD_POST, data)
func delete_word(word: String, username: String, apiKey: String, dict: String = ""):
var data = {
"word": word,
"username": username,
"apiKey": apiKey
}
if dict != "":
data["dict"] = dict
return _make_request("/words/delete", HTTPClient.METHOD_POST, data)
static func percent_encode(text: String) -> String:
return text.uri_encode()
class LanguageToolCheckResponse:
# Software info
var software_name: String
var software_version: String
var software_build_date: String
var software_api_version: int
var software_status: String = ""
var software_premium: bool = false
# Language info
var language_name: String
var language_code: String
var detected_language_name: String
var detected_language_code: String
# Match structure
class Match:
var message: String
var short_message: String = ""
var offset: int
var length: int
var replacements: Array[String] = []
var context_text: String
var context_offset: int
var context_length: int
var sentence: String
class Rule:
var id: String
var sub_id: String = ""
var description: String
var urls: Array[String] = []
var issue_type: String = ""
class Category:
var id: String
var name: String
var category: Category
var rule: Rule
var matches: Array[Match] = []
func _init(response: Variant) -> void:
# Parse software
var sw = response.software if response.has("software") else {}
software_name = sw.name if sw.has("name") else ""
software_version = sw.version if sw.has("version") else ""
software_build_date = sw.buildDate if sw.has("buildDate") else ""
software_api_version = sw.apiVersion if sw.has("apiVersion") else 0
software_status = sw.status if sw.has("status") else ""
software_premium = sw.premium if sw.has("premium") else false
# Parse language
var lang = response.language if response.has("language") else {}
language_name = lang.name if lang.has("name") else ""
language_code = lang.code if lang.has("code") else ""
var det_lang = lang.detectedLanguage if lang.has("detectedLanguage") else {}
detected_language_name = det_lang.name if det_lang.has("name") else ""
detected_language_code = det_lang.code if det_lang.has("code") else ""
# Parse matches
matches = []
var matches_arr = response.matches if response.has("matches") else []
for m in matches_arr:
var _match = Match.new()
_match.message = m.message if m.has("message") else ""
_match.short_message = m.shortMessage if m.has("shortMessage") else ""
_match.offset = m.offset if m.has("offset") else 0
_match.length = m.length if m.has("length") else 0
#_match.replacements = []
var replacements_arr = m.replacements if m.has("replacements") else []
for r in replacements_arr:
_match.replacements.append(r.value if r.has("value") else "")
var ctx = m.context if m.has("context") else {}
_match.context_text = ctx.text if ctx.has("text") else ""
_match.context_offset = ctx.offset if ctx.has("offset") else 0
_match.context_length = ctx.length if ctx.has("length") else 0
_match.sentence = m.sentence if m.has("sentence") else ""
var rule_dict = m.rule if m.has("rule") else {}
var rule = Match.Rule.new()
rule.id = rule_dict.id if rule_dict.has("id") else ""
rule.sub_id = rule_dict.subId if rule_dict.has("subId") else ""
rule.description = rule_dict.description if rule_dict.has("description") else ""
#rule.urls = []
var urls_arr = rule_dict.urls if rule_dict.has("urls") else []
for u in urls_arr:
rule.urls.append(u.value if u.has("value") else "")
rule.issue_type = rule_dict.issueType if rule_dict.has("issueType") else ""
var cat = rule_dict.category if rule_dict.has("category") else {}
var category = Match.Rule.Category.new()
category.id = cat.id if cat.has("id") else ""
category.name = cat.name if cat.has("name") else ""
rule.category = category
_match.rule = rule
matches.append(_match)