Placeholder bug report forms can now be posted to Gitea.

This commit is contained in:
Jamie Greunbaum 2024-05-20 01:55:54 -04:00
parent fd156e56f3
commit 1f000909bb
4 changed files with 124 additions and 49 deletions

View File

@ -67,6 +67,8 @@ extends CharacterBody3D
#endregion
#region Private Properties
var __bugbot_server : BugbotServerAPI
var __movement_speed : float = 5.0
var __stored_camera : Camera3D
@ -83,6 +85,8 @@ func _enter_tree() -> void:
__stored_mouse_mode = Input.mouse_mode
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
__bugbot_server = BugbotServerAPI._create_new_server_api()
#region Movement Configuration
InputMap.add_action(&"bugbot_move_forward", 0.1)
@ -295,7 +299,6 @@ func __place_marker(_position:Vector3, _normal:Vector3):
if __raycast_collision:
var collider : Area3D = __raycast_collision["collider"] as Area3D
if collider and collider.is_in_group("BugMarkerInfo"):
print("Hit a guy!")
return
var marker : BugMarker = (load(bug_marker) as PackedScene).instantiate() as BugMarker
@ -304,6 +307,8 @@ func __place_marker(_position:Vector3, _normal:Vector3):
marker.set_rotation_to_normal(_normal)
marker.marker_status = BugMarker.BugStatus.UNRESOLVED
__bugbot_server._send_form_data(func(data:Array):print(data))
func __place_dummy_marker():
if __raycast_collision:

View File

@ -3,22 +3,22 @@ extends Resource
enum BugbotServerError { OK, THREAD_NULL, THREAD_BUSY }
static var __bugbot_server_thread : Thread
var __bugbot_server_thread : Thread
func _init():
__bugbot_server_thread = Thread.new()
static func _return_list_of_bugs(callback:Callable) -> int:
func _return_list_of_bugs(callback:Callable) -> int:
print("Insert list of ", _current_server_api(), " bugs here.")
return BugbotServerError.OK
static func _prepare_form() -> int:
func _prepare_form(callback:Callable) -> int:
print("Prepare ", _current_server_api(), " form here.")
return BugbotServerError.OK
static func _send_form_data() -> int:
func _send_form_data(callback:Callable) -> int:
print("Send ", _current_server_api(), " form data here.")
return BugbotServerError.OK
@ -30,13 +30,44 @@ static func _create_new_server_api() -> BugbotServerAPI:
BugReportPlatform.JIRA: return BugbotServerAPI.new()
return BugbotServerAPI.new()
static func _current_server_api() -> String:
func __connect_to_server(http_client:HTTPClient, default_server:String) -> int:
var full_server : String = ProjectSettings.get_setting("bugbot/reporting/gitea/server", default_server)
var server_and_port : PackedStringArray = full_server.rsplit(":",true,1)
var server : String = server_and_port[0]
var port : int = int(server_and_port[1])
var error : int = http_client.connect_to_host(server if port > 0 else full_server, port if port > 0 else -1)
return error
func __get_http_client_chunk_response(http_client:HTTPClient) -> String:
if http_client.has_response():
var response_body : PackedByteArray = PackedByteArray()
while http_client.get_status() == HTTPClient.STATUS_BODY:
http_client.poll()
var chunk : PackedByteArray = http_client.read_response_body_chunk()
if chunk.size() > 0:
response_body = response_body + chunk
return response_body.get_string_from_utf8()
return ""
static func _build_url_string() -> String:
func __start_thread_with_callback(thread_function:Callable) -> int:
if not __bugbot_server_thread:
printerr("Server thread is null.")
return BugbotServerError.THREAD_NULL
if __bugbot_server_thread.is_started():
printerr("Server thread is currently busy.")
return BugbotServerError.THREAD_BUSY;
__bugbot_server_thread = Thread.new()
__bugbot_server_thread.start(thread_function)
return BugbotServerError.OK
func _current_server_api() -> String:
return ""
static func _create_header_data(mime_type:String, api_key:String) -> Array:
func __build_url_string(_api_suffix:String) -> String:
return ""
func __create_header_data(mime_type:String, api_key:String, content_length:int = -1) -> Array:
return []

View File

@ -7,62 +7,44 @@ 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_LABEL : StringName = &"Kind/Bug"
const DEFAULT_STATUS : StringName = &"Status/Need More Info"
const DEFAULT_BUG_LABEL : StringName = &"Kind/Bug"
const DEFAULT_STATUS_LABEL : StringName = &"Status/Need More Info"
const UNRESOLVED_TAG : String = &"Status/Unresolved"
const IN_PROGRESS_TAG : String = &"Status/In Progress"
const RESOLVED_TAG : String = &"Status/Resolved"
const UNRESOLVED_TAG : StringName = &"Status/Unresolved"
const IN_PROGRESS_TAG : StringName = &"Status/In Progress"
const RESOLVED_TAG : StringName = &"Status/Resolved"
#endregion
static func _return_list_of_bugs(callback:Callable) -> int:
if not __bugbot_server_thread:
printerr("Server thread is null.")
return BugbotServerError.THREAD_NULL
if __bugbot_server_thread.is_started():
printerr("Server thread is currently busy.")
return BugbotServerError.THREAD_BUSY;
__bugbot_server_thread = Thread.new()
__bugbot_server_thread.start(__return_list_of_bugs_thread.bind(callback))
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
#static func _prepare_form() -> void:
#print("Prepare ", _current_server_api(), " form here.")
#
#static func _send_form_data() -> void:
#print("Send ", _current_server_api(), " form data here.")
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 server : String = ProjectSettings.get_setting("bugbot/reporting/gitea/server", DEFAULT_SERVER)
var error : int = http_client.connect_to_host(server, 443)
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()
api_url += "?state=all&labels=" + ProjectSettings.get_setting("bugbot/reporting/gitea/default_label", DEFAULT_LABEL).uri_encode()
var header_data : Array = _create_header_data("application/json", ProjectSettings.get_setting("bugbot/reporting/gitea/API_key", DEFAULT_API_KEY))
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 = ""
if http_client.has_response():
var response_body : PackedByteArray = PackedByteArray()
while http_client.get_status() == HTTPClient.STATUS_BODY:
http_client.poll()
var chunk : PackedByteArray = http_client.read_response_body_chunk()
if chunk.size() > 0:
response_body = response_body + chunk
response_string = response_body.get_string_from_utf8()
var response_string : String = __get_http_client_chunk_response(http_client)
var response_array : Array
var response_data := JSON.parse_string(response_string)
@ -114,27 +96,84 @@ func __return_list_of_bugs_thread(callback:Callable) -> void:
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")
static func _current_server_api() -> String:
func _current_server_api() -> String:
return "Gitea"
static func _build_url_string() -> String:
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) + \
"/issues"
"/" + _api_suffix
static func _create_header_data(mime_type:String, api_key:String) -> Array:
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

View File

@ -53,8 +53,8 @@ func __initialise_project_settings():
__add_project_setting("bugbot/reporting/gitea/owner_name", TYPE_STRING, BugbotServerGiteaAPI.DEFAULT_OWNER_NAME)
__add_project_setting("bugbot/reporting/gitea/repo_name", TYPE_STRING, BugbotServerGiteaAPI.DEFAULT_REPO_NAME)
__add_project_setting("bugbot/reporting/gitea/API_key", TYPE_STRING, BugbotServerGiteaAPI.DEFAULT_API_KEY)
__add_project_setting("bugbot/reporting/gitea/default_label", TYPE_STRING, BugbotServerGiteaAPI.DEFAULT_LABEL)
__add_project_setting("bugbot/reporting/gitea/default_status", TYPE_STRING, BugbotServerGiteaAPI.DEFAULT_STATUS)
__add_project_setting("bugbot/reporting/gitea/bug_label", TYPE_STRING, BugbotServerGiteaAPI.DEFAULT_BUG_LABEL)
__add_project_setting("bugbot/reporting/gitea/default_status_label", TYPE_STRING, BugbotServerGiteaAPI.DEFAULT_STATUS_LABEL)
__add_project_setting("bugbot/reporting/gitea/status_labels/unresolved_statuses", TYPE_ARRAY, Array(), PROPERTY_HINT_ARRAY_TYPE, &"21/:")
__add_project_setting("bugbot/reporting/gitea/status_labels/in_progress_statuses", TYPE_ARRAY, Array(), PROPERTY_HINT_ARRAY_TYPE, &"21/:")
__add_project_setting("bugbot/reporting/gitea/status_labels/resolved_statuses", TYPE_ARRAY, Array(), PROPERTY_HINT_ARRAY_TYPE, &"21/:")