Bugbot/Scripts/server_gitea_api.gd
Jamie Greunbaum 5c37903872 - Bugs are now filtered out by status before being passed out of the HTTPClient thread.
- Fixed an issue that caused bugs to be given the incorrect resolution tag.
2024-05-22 01:46:51 -04:00

203 lines
11 KiB
GDScript

class_name BugbotServerGiteaAPI
extends "res://addons/Bugbot/Scripts/server_api.gd"
#region Consts
const DEFAULT_SERVER : StringName = &"https://gitea.example.com"
const DEFAULT_BASE_URL : StringName = &"api/v1/"
const DEFAULT_OWNER_NAME : StringName = &"ProjectOwner"
const DEFAULT_REPO_NAME : StringName = &"ProjectName"
const DEFAULT_API_KEY : StringName = &"0123456789abcdef0123456789abcdef01234567"
const DEFAULT_BUG_LABEL : StringName = &"Kind/Bug"
const DEFAULT_STATUS_LABEL : StringName = &"Status/Need More Info"
const UNRESOLVED_TAG : StringName = &"Status/Unresolved"
const IN_PROGRESS_TAG : StringName = &"Status/In Progress"
const RESOLVED_TAG : StringName = &"Status/Resolved"
#endregion
func _return_list_of_bugs(callback:Callable) -> int:
return __start_thread_with_callback(__return_list_of_bugs_thread.bind(callback))
func _prepare_form(callback:Callable) -> int:
print(_current_server_api(), " has not yet implemented this functionality.")
return BugbotServerError.OK
func _send_form_data(callback:Callable) -> int:
return __start_thread_with_callback(__send_form_data_thread.bind(callback))
func __return_list_of_bugs_thread(callback:Callable) -> void:
var http_client : HTTPClient = HTTPClient.new()
var error : int = __connect_to_server(http_client, DEFAULT_SERVER)
assert(error == Error.OK)
while http_client.get_status() == HTTPClient.STATUS_CONNECTING or http_client.get_status() == HTTPClient.STATUS_RESOLVING:
http_client.poll()
assert(http_client.get_status() == HTTPClient.STATUS_CONNECTED)
var api_url : String = __build_url_string("issues")
api_url += "?state=all&labels=" + ProjectSettings.get_setting("bugbot/reporting/gitea/bug_label", DEFAULT_BUG_LABEL).uri_encode()
var header_data : Array = __create_header_data("application/json", ProjectSettings.get_setting("bugbot/reporting/gitea/API_key", DEFAULT_API_KEY))
error = http_client.request(HTTPClient.METHOD_GET, api_url, header_data)
assert(error == Error.OK)
while http_client.get_status() == HTTPClient.STATUS_REQUESTING:
http_client.poll()
assert(http_client.get_status() == HTTPClient.STATUS_BODY or http_client.get_status() == HTTPClient.STATUS_CONNECTED)
var response_string : String = __get_http_client_chunk_response(http_client)
var response_array : Array
var response_data := JSON.parse_string(response_string)
# If the response is an array, we can make the assumption that this is
# a list of returned bugs.
if response_data is Array:
var resolved_labels : Array = ProjectSettings.get_setting("bugbot/reporting/gitea/status_labels/resolved_statuses")
var in_progress_labels : Array = ProjectSettings.get_setting("bugbot/reporting/gitea/status_labels/in_progress_statuses")
var unresolved_labels : Array = ProjectSettings.get_setting("bugbot/reporting/gitea/status_labels/unresolved_statuses")
var show_resolved : bool = ProjectSettings.get_setting("bugbot/markers/resolved/show_resolved_bugs")
var show_in_progress : bool = ProjectSettings.get_setting("bugbot/markers/in_progress/show_in_progress_bugs")
var show_unresolved : bool = ProjectSettings.get_setting("bugbot/markers/unresolved/show_unresolved_bugs")
for bug_in:Dictionary in response_data:
var bug : BugbotBugData = BugbotBugData.new()
var bug_labels : Array = []
var resolved_tag_found : bool = false
var in_progress_tag_found : bool = false
var unresolved_tag_found : bool = false
# Find which resolution statuses apply to this bug.
bug.is_open = (bug_in["state"] == "open")
if not bug.is_open:
resolved_tag_found = true
else:
for labels:Dictionary in bug_in["labels"]:
bug_labels.append(labels["name"] as String)
for label:String in resolved_labels:
if bug_labels.has(label): resolved_tag_found = true
for label:String in in_progress_labels:
if bug_labels.has(label): in_progress_tag_found = true
for label:String in unresolved_labels:
if bug_labels.has(label): unresolved_tag_found = true
# Figure out which resolution tag to prioritise, and whether we should show the marker.
var show_marker : bool
if resolved_tag_found:
bug.resolution = RESOLVED_TAG
show_marker = show_resolved
elif in_progress_tag_found:
bug.resolution = IN_PROGRESS_TAG
show_marker = show_in_progress
elif unresolved_tag_found or unresolved_labels.is_empty():
bug.resolution = UNRESOLVED_TAG
show_marker = show_unresolved
if not show_marker: continue
bug.id = bug_in["id"]
bug.title = bug_in["title"]
bug.body = bug_in["body"]
bug.component = &"Unused"
bug.platform = &"Unused"
bug.operating_system = &"Unused"
bug.severity = "Severity will go here."
bug.status = bug_in["state"]
bug.duplicate_of = -1
bug.map_name = "Map name will go here."
bug.marker_location = "Marker location will go here."
response_array.append(bug)
elif response_data is Dictionary:
# If the response is a dictionary and not an array, make the assumption
# that this is because the response was an error code.
var error_data : BugbotErrorData = BugbotErrorData.new()
error_data.code = 1
error_data.message = response_data["message"]
error_data.url = response_data["url"]
response_array.append(error_data)
printerr(error_data.message)
callback.call_deferred(response_array)
__bugbot_server_thread.call_deferred("wait_to_finish")
func __send_form_data_thread(callback:Callable) -> void:
var http_client : HTTPClient = HTTPClient.new()
var error : int = __connect_to_server(http_client, DEFAULT_SERVER)
assert(error == Error.OK)
while http_client.get_status() == HTTPClient.STATUS_CONNECTING or http_client.get_status() == HTTPClient.STATUS_RESOLVING:
http_client.poll()
assert(http_client.get_status() == HTTPClient.STATUS_CONNECTED)
var api_url : String = __build_url_string("labels")
var api_key : String = ProjectSettings.get_setting("bugbot/reporting/gitea/API_key", DEFAULT_API_KEY)
var header_data : Array = __create_header_data("application/json", api_key)
error = http_client.request(HTTPClient.METHOD_GET, api_url, header_data)
assert(error == Error.OK)
while http_client.get_status() == HTTPClient.STATUS_REQUESTING:
http_client.poll()
assert(http_client.get_status() == HTTPClient.STATUS_BODY or http_client.get_status() == HTTPClient.STATUS_CONNECTED)
var response_string : String = __get_http_client_chunk_response(http_client)
var response_array : Array
var response_data := JSON.parse_string(response_string)
if response_data is Array:
# If the response is an array, we can make the assumption that this is
# a list of returned bugs.
var bug_label : String = ProjectSettings.get_setting("bugbot/reporting/gitea/bug_label", DEFAULT_BUG_LABEL)
var status_label : String = ProjectSettings.get_setting("bugbot/reporting/gitea/default_status_label", DEFAULT_STATUS_LABEL)
for label_in:Dictionary in response_data:
if label_in["name"] == bug_label or label_in["name"] == status_label:
response_array.append(label_in["id"])
elif response_data is Dictionary:
# If the response is a dictionary and not an array, make the assumption
# that this is because the response was an error code.
var error_data : BugbotErrorData = BugbotErrorData.new()
error_data.code = 1
error_data.message = response_data["message"]
error_data.url = response_data["url"]
response_array.append(error_data)
printerr(error_data.message)
api_url = __build_url_string("issues")
var post_data : Dictionary = {
"title": "This is a test bug. Here's some randomness just for fun: " + String.num(randf_range(0.0, 10000000.0)),
"body": "Fusce ornare ut felis quis aliquet. Nullam mollis dictum elit, vitae gravida metus blandit eu. Donec mi ipsum, luctus vel arcu in, suscipit hendrerit mi. Morbi imperdiet tellus pretium mi semper, vel lacinia risus mattis. Ut dapibus sed nibh eget suscipit. Vestibulum posuere pellentesque lectus, ac mollis odio congue tempus. Phasellus nisi nunc, tincidunt et bibendum non, ornare quis felis. Donec finibus mauris eu sollicitudin pharetra. Pellentesque interdum mi in augue imperdiet molestie. Nulla venenatis nec libero in feugiat. Donec nec mauris molestie, euismod magna nec, aliquet felis.\n\nAenean suscipit auctor nulla, ac aliquam purus porttitor ut. Curabitur lacinia ullamcorper ligula, sit amet tempor arcu volutpat et. Nulla eget nisi sem. Etiam pharetra at orci ut fermentum. In eu neque purus. Aliquam condimentum gravida porttitor. Nullam sem sapien, semper at hendrerit nec, lobortis sed magna. Duis non pharetra orci. Quisque faucibus, sem vitae laoreet suscipit, orci massa convallis lorem, ut malesuada dui felis ac eros.\n\nPellentesque felis lorem, volutpat eu ullamcorper eu, ultrices sed nulla. Proin ac nunc sit amet ex pellentesque sagittis non ut libero. Maecenas viverra, odio eu elementum convallis, erat purus tempor tortor, non suscipit est enim quis ligula. Praesent vestibulum orci nec enim vehicula, id commodo erat sollicitudin. Sed mauris eros, sollicitudin sit amet volutpat ac, ullamcorper dignissim erat. Aenean vitae turpis quis lorem ultrices varius. Donec pellentesque suscipit nulla id consectetur. Quisque nibh nisl, posuere in sapien eget, vehicula dapibus magna. Integer faucibus ligula ut metus sollicitudin viverra. Vestibulum elementum vitae leo sit amet ornare. Sed dapibus egestas nisi id tempus. Proin lorem erat, euismod quis porttitor ac, tincidunt faucibus nisl. Sed aliquam sem in vehicula mattis. Fusce eu libero ac eros tempus tempor ut eu nunc. Duis a turpis erat. Morbi rutrum gravida volutpat.",
"labels": response_array,
}
var post_data_string : String = JSON.stringify(post_data)
header_data = __create_header_data("application/json", api_key, post_data_string.length())
error = http_client.request(HTTPClient.METHOD_POST, api_url, header_data, post_data_string)
assert(error == Error.OK)
while http_client.get_status() == HTTPClient.STATUS_REQUESTING:
http_client.poll()
assert(http_client.get_status() == HTTPClient.STATUS_BODY or http_client.get_status() == HTTPClient.STATUS_CONNECTED)
response_string = __get_http_client_chunk_response(http_client)
callback.call_deferred([response_string])
__bugbot_server_thread.call_deferred("wait_to_finish")
func _current_server_api() -> String:
return "Gitea"
func __build_url_string(_api_suffix:String) -> String:
return "/" + \
ProjectSettings.get_setting("bugbot/reporting/gitea/base_URL", DEFAULT_BASE_URL) + \
"/repos/" + \
ProjectSettings.get_setting("bugbot/reporting/gitea/owner_name", DEFAULT_OWNER_NAME) + \
"/" + \
ProjectSettings.get_setting("bugbot/reporting/gitea/repo_name", DEFAULT_REPO_NAME) + \
"/" + _api_suffix
func __create_header_data(mime_type:String, api_key:String, content_length:int = -1) -> Array:
var header : Array = [
"User-Agent: Pirulo/1.0 (Godot)",
"Accept: " + mime_type,
"Content-Type: " + mime_type,
]
if api_key: header.append("Authorization: token " + api_key)
if content_length >= 0: header.append("Content-Length: " + String.num_uint64(content_length))
return header