Compare commits

..

No commits in common. "main" and "main" have entirely different histories.
main ... main

10 changed files with 97 additions and 179 deletions

3
.gitignore vendored
View File

@ -9,6 +9,3 @@ export_presets.cfg
# Mono-specific ignores # Mono-specific ignores
.mono/ .mono/
data_*/ data_*/
# VSCode config folder
.vscode/

49
Main.gd
View File

@ -17,7 +17,26 @@ func _start_server(port: int = 3001) -> void:
return return
_server = HTTPServer.new() _server = HTTPServer.new()
_server.endpoint(HTTPServer.Method.GET, "/", funcref(self, "_serve_file")) var dir := Directory.new()
if dir.open(server_dir) == OK:
if dir.list_dir_begin() != OK:
# TODO: show error to user here
return
var file_name := dir.get_next()
while file_name != "":
if !dir.current_is_dir():
if file_name.get_extension() == "import":
file_name = dir.get_next()
continue
print(file_name)
_server.endpoint(HTTPServer.Method.GET, "/%s" % file_name, funcref(self, "_serve_file"), [file_name])
file_name = dir.get_next()
_server.endpoint(HTTPServer.Method.GET, "/", funcref(self, "_serve_file"), ["index.html"])
if _server.listen(port) != OK: if _server.listen(port) != OK:
# TODO: show error to user here # TODO: show error to user here
@ -43,25 +62,27 @@ func _process(_delta: float) -> void:
return return
func _serve_file(request: HTTPServer.Request, response: HTTPServer.Response) -> void: func _serve_file(_request: HTTPServer.Request, response: HTTPServer.Response, binds: Array) -> void:
var file_name: String = request.endpoint() var file_name: String = binds[0] as String
if file_name == "/": # if the request is for root, serve index print(file_name)
file_name = "index.html"
var f := File.new() var f := File.new()
var success = f.open(server_dir.plus_file(file_name), File.READ) var success = f.open("res://server_files/%s" % file_name, File.READ)
if success == OK:
if success == OK: # TODO: handle other errors like file not found
var mime := mime_types.get(file_name) var mime := mime_types.get(file_name)
response.type(mime) response.header("content-type", mime.full_type)
var data = f.get_buffer(f.get_len()) # variant
# warning-ignore:incompatible_ternary
var data = f.get_as_text() if mime.type == 'text' else f.get_buffer(f.get_len())
response.data(data) response.data(data)
else: else:
response.type(mime_types.get("txt")) response.header("content-type", "text/plain")
response.status(500) response.data("500 - Read Error")
response.data("Internal Server Error")
func _on_ServerUI_start_server_button_pressed(port: int, new_dir: String) -> void: func _on_ServerUI_start_server_button_pressed(port: int, new_dir: String) -> void:
@ -71,7 +92,3 @@ func _on_ServerUI_start_server_button_pressed(port: int, new_dir: String) -> voi
func _on_ServerUI_stop_server_button_pressed() -> void: func _on_ServerUI_stop_server_button_pressed() -> void:
_stop_server() _stop_server()
func _on_ServerUI_server_folder_changed(new_path: String) -> void:
server_dir = new_path

View File

@ -10,6 +10,5 @@ script = ExtResource( 1 )
[node name="ServerUI" parent="." instance=ExtResource( 2 )] [node name="ServerUI" parent="." instance=ExtResource( 2 )]
[connection signal="server_folder_changed" from="ServerUI" to="." method="_on_ServerUI_server_folder_changed"]
[connection signal="start_server_button_pressed" from="ServerUI" to="." method="_on_ServerUI_start_server_button_pressed"] [connection signal="start_server_button_pressed" from="ServerUI" to="." method="_on_ServerUI_start_server_button_pressed"]
[connection signal="stop_server_button_pressed" from="ServerUI" to="." method="_on_ServerUI_stop_server_button_pressed"] [connection signal="stop_server_button_pressed" from="ServerUI" to="." method="_on_ServerUI_stop_server_button_pressed"]

View File

@ -1,9 +1,9 @@
# Godot frontend for Tickle # Godot frontend for Ticle
Tickle is a WIP tiny static site "generator" that parses Markdown files right in the browser, with no compilation to HTML necessary, intended for equally tiny blogs. Ticle is a WIP tiny static site "generator" that parses Markdown files right in the browser, with no compilation to HTML necessary, intended for equally tiny blogs.
This project aims to provide a nice frontend/UI to manage Tickle files and an easy way to run your site locally. This project aims to provide a nice frontend/UI to manage Ticle files and an easy way to run your site locally.
It uses a slightly modified version of [godot-http-server](https://github.com/velopman/godot-http-server) for the server side. It uses a slightly modified version of [godot-http-server](https://github.com/velopman/godot-http-server) for the server side.
The version of Godot used for this project is 3.5rc5. The version of Godot used for this project is 3.5rc4.

View File

@ -1,16 +1,11 @@
extends Control extends Control
const SERVER_STATUS_TEXT: Dictionary = { const SERVER_STATUS_TEXT: Dictionary = {
true: "Server is running!", "RUNNING": "Server is running!",
false: "Server is not running.", "NOT_RUNNING": "Server is not running."
} }
const START_BUTTON_SERVER_TEXT: Dictionary = { const ACCEPTED_FILE_FORMATS := ["md"] # server should ignore these file types when adding endpoints
true: "Stop server",
false: "Start server",
}
const ACCEPTED_FILE_FORMATS := ["md"]
export(bool) var enable_file_autosave := true # if true, will save the active file's contents every save_file_timeout seconds. export(bool) var enable_file_autosave := true # if true, will save the active file's contents every save_file_timeout seconds.
export(float) var save_file_timeout := 4.0 # the time to save document content after the edited signal of TextEdit export(float) var save_file_timeout := 4.0 # the time to save document content after the edited signal of TextEdit
@ -24,7 +19,6 @@ onready var server_path_label := $"%ServerPathLabel"
onready var port_spin_box := $"%PortSpinBox" onready var port_spin_box := $"%PortSpinBox"
onready var start_server_button := $"%StartServerButton" onready var start_server_button := $"%StartServerButton"
onready var server_status_label := $"%ServerStatusLabel" onready var server_status_label := $"%ServerStatusLabel"
onready var open_browser_button := $"%OpenBrowserButton"
onready var document_title_lineedit := $"%DocTitleLineEdit" onready var document_title_lineedit := $"%DocTitleLineEdit"
onready var document_date_lineedit := $"%DocDateLineEdit" onready var document_date_lineedit := $"%DocDateLineEdit"
@ -38,12 +32,12 @@ onready var content_preview_richtextlabel := $"%ContentPreviewRichTextLabel"
onready var server_folder_dialog := $"%ServerFolderDialog" onready var server_folder_dialog := $"%ServerFolderDialog"
signal server_folder_changed(new_path) # new_path: String signal server_folder_changed(new_path) # new_path: String
signal server_port_changed(new_port) # new_port: int
signal start_server_button_pressed(port, path) # port: int, path: String signal start_server_button_pressed(port, path) # port: int, path: String
signal stop_server_button_pressed() # emit from %StartServerButton, when the server is not running. signal stop_server_button_pressed() # emit from %StartServerButton, when the server is not running.
signal open_browser_button_pressed(port) # port: int
#signal server_port_changed(new_port) # new_port: int signal files_selection_changed(new_files) # new_files: Array<String>
#signal open_browser_button_pressed(port) # port: int
#signal files_selection_changed(new_files) # new_files: Array<String>
var server_dir: String setget set_server_dir var server_dir: String setget set_server_dir
var is_server_running: bool = false setget set_server_running var is_server_running: bool = false setget set_server_running
@ -74,10 +68,9 @@ func set_server_dir(dir: String) -> void:
var directory := Directory.new() var directory := Directory.new()
if directory.open(dir) == OK: if directory.open(dir) == OK:
if directory.list_dir_begin() != OK: directory.list_dir_begin()
push_error("Directory error") # TODO: show a user-facing error
var file_name: String = directory.get_next() var file_name: String = directory.get_next()
var idx: int = 0
while file_name != "": while file_name != "":
if !directory.current_is_dir() && (file_name.get_extension() in ACCEPTED_FILE_FORMATS): if !directory.current_is_dir() && (file_name.get_extension() in ACCEPTED_FILE_FORMATS):
var fd = FileDef(file_name, false) var fd = FileDef(file_name, false)
@ -91,18 +84,16 @@ func set_server_dir(dir: String) -> void:
fd.title = file_metadata["title"] fd.title = file_metadata["title"]
fd.date = file_metadata["date"] fd.date = file_metadata["date"]
idx += 1
file_name = directory.get_next() file_name = directory.get_next()
directory.list_dir_end() directory.list_dir_end()
_reconstruct_tree_from_working_files() _reconstruct_tree_from_working_files()
emit_signal("server_folder_changed", server_dir)
func _reconstruct_tree_from_working_files() -> void: func _reconstruct_tree_from_working_files() -> void:
current_file = null
current_tree_selection = null
file_tree.clear() file_tree.clear()
var root: TreeItem = file_tree.create_item() var root: TreeItem = file_tree.create_item()
root.set_text(0, "Server files") root.set_text(0, "Server files")
@ -137,11 +128,6 @@ func _on_FileTree_item_selected() -> void:
func _on_FileTree_item_rmb_selected(position: Vector2) -> void: func _on_FileTree_item_rmb_selected(position: Vector2) -> void:
current_tree_selection = file_tree.get_selected() current_tree_selection = file_tree.get_selected()
file_tree_context_menu.rect_position = position + file_tree.rect_global_position file_tree_context_menu.rect_position = position + file_tree.rect_global_position
file_tree_context_menu.popup()
if is_server_running:
return # the file tree can't be edited while the server is running, so disable moving items as well
if (current_tree_selection.get_metadata(0)["id"] as int) == 0: if (current_tree_selection.get_metadata(0)["id"] as int) == 0:
file_tree_context_menu.set_item_disabled(ContextMenuOptions.MOVE_UP, true) file_tree_context_menu.set_item_disabled(ContextMenuOptions.MOVE_UP, true)
else: else:
@ -153,23 +139,29 @@ func _on_FileTree_item_rmb_selected(position: Vector2) -> void:
file_tree_context_menu.set_item_disabled(ContextMenuOptions.MOVE_DOWN, false) file_tree_context_menu.set_item_disabled(ContextMenuOptions.MOVE_DOWN, false)
file_tree_context_menu.popup()
func _on_OpenServerFolderButton_pressed() -> void: func _on_OpenServerFolderButton_pressed() -> void:
server_folder_dialog.popup() server_folder_dialog.popup()
func set_server_running(running: bool) -> void: func set_server_running(running: bool) -> void:
is_server_running = running is_server_running = running
if is_server_running:
port_spin_box.editable = !running server_status_label.text = SERVER_STATUS_TEXT.RUNNING
document_date_lineedit.editable = !running start_server_button.text = "Stop server"
document_title_lineedit.editable = !running port_spin_box.editable = false
document_input_textedit.readonly = running document_date_lineedit.editable = false
open_browser_button.disabled = !running document_title_lineedit.editable = false
_set_file_tree_disabled(running) document_input_textedit.readonly = true
_set_context_menu_disabled(running) else:
server_status_label.text = SERVER_STATUS_TEXT.NOT_RUNNING
server_status_label.text = SERVER_STATUS_TEXT[running] start_server_button.text = "Start server"
start_server_button.text = START_BUTTON_SERVER_TEXT[running] port_spin_box.editable = !false
document_date_lineedit.editable = !false
document_title_lineedit.editable = !false
document_input_textedit.readonly = !true
func _generate_filestxt(): func _generate_filestxt():
@ -178,7 +170,7 @@ func _generate_filestxt():
for file in working_files: for file in working_files:
file = file as FileDef file = file as FileDef
if file.include_in_filestxt: if file.include_in_filestxt:
files += ("%s %s %s" % [file.file_path, file.date, file.title]).strip_edges(false, true) + "\n" files += "%s %s %s\n" % [file.file_path, file.date, file.title]
var f := File.new() var f := File.new()
if f.open(server_dir.plus_file("files.txt"), File.WRITE) == OK: if f.open(server_dir.plus_file("files.txt"), File.WRITE) == OK:
@ -243,25 +235,6 @@ func _get_file_content(path: String) -> String:
return content return content
func _set_file_tree_disabled(disabled: bool) -> void:
var root = file_tree.get_root()
var tree_item = root.get_children() as TreeItem
while tree_item != null:
tree_item.set_editable(0, !disabled)
tree_item = tree_item.get_next()
func _set_context_menu_disabled(disabled: bool) -> void:
for i in file_tree_context_menu.get_item_count():
file_tree_context_menu.set_item_disabled(i, disabled)
func _commit_all_files() -> void:
for file in working_files:
file = file as FileDef
file.commit(server_dir)
func _on_FileTreeContextMenu_id_pressed(id: int) -> void: func _on_FileTreeContextMenu_id_pressed(id: int) -> void:
var idx = current_tree_selection.get_metadata(0)["id"] as int var idx = current_tree_selection.get_metadata(0)["id"] as int
var fd = working_files[idx] as FileDef var fd = working_files[idx] as FileDef
@ -286,17 +259,6 @@ func _on_DocDateLineEdit_text_changed(new_text: String) -> void:
current_file.date = new_text current_file.date = new_text
func _on_OpenBrowserButton_pressed() -> void:
if OS.shell_open("http://localhost:%s" % port_spin_box.value) != OK:
push_error("Error opening browser!") # TODO: show a user-facing error
func _on_RefreshFilesButton_pressed() -> void:
_commit_all_files()
_generate_filestxt()
self.server_dir = server_dir
func _on_DocInputTextEdit_text_changed() -> void: func _on_DocInputTextEdit_text_changed() -> void:
if current_file: if current_file:
var new_text: String = document_input_textedit.text var new_text: String = document_input_textedit.text
@ -308,7 +270,6 @@ func _on_DocInputTextEdit_text_changed() -> void:
t.one_shot = true t.one_shot = true
current_file.timer = t current_file.timer = t
add_child(t) add_child(t)
# warning-ignore:return_value_discarded
t.connect("timeout", self, "_on_EditedTimeout_timeout", [t, current_file]) t.connect("timeout", self, "_on_EditedTimeout_timeout", [t, current_file])
else: else:
current_file.timer.stop() current_file.timer.stop()
@ -319,7 +280,9 @@ func _on_EditedTimeout_timeout(timer: Timer, file: FileDef) -> void:
file.timer = null file.timer = null
timer.queue_free() timer.queue_free()
file.commit(server_dir) var f := File.new()
if f.open(server_dir.plus_file(file.file_path), File.WRITE) == OK:
f.store_string(file.content)
func FileDef( func FileDef(
@ -345,15 +308,3 @@ class FileDef:
var content: String var content: String
var timer: Timer var timer: Timer
func commit(server_dir: String) -> void:
var f := File.new()
var open := f.open(server_dir.plus_file(file_path), File.WRITE)
if open == OK:
f.store_string(content)
if timer && !timer.is_stopped(): # if there's an autosave pending, stop it since we're setting it here.
timer.stop()
else:
push_error("Error committing file %s, code %s" % [file_path, open]) # TODO: show a user-facing error

View File

@ -78,13 +78,11 @@ margin_bottom = 23.0
text = "Server is not running." text = "Server is not running."
[node name="OpenBrowserButton" type="Button" parent="VBoxContainer/HBoxContainer"] [node name="OpenBrowserButton" type="Button" parent="VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
margin_left = 922.0 margin_left = 922.0
margin_right = 1040.0 margin_right = 1040.0
margin_bottom = 32.0 margin_bottom = 32.0
rect_min_size = Vector2( 0, 32 ) rect_min_size = Vector2( 0, 32 )
size_flags_horizontal = 12 size_flags_horizontal = 12
disabled = true
text = "Open in browser" text = "Open in browser"
[node name="HSplitContainer" type="HSplitContainer" parent="VBoxContainer"] [node name="HSplitContainer" type="HSplitContainer" parent="VBoxContainer"]
@ -190,19 +188,19 @@ size_flags_vertical = 3
split_offset = 328 split_offset = 328
[node name="ContentEditContainer" type="VBoxContainer" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/HSplitContainer"] [node name="ContentEditContainer" type="VBoxContainer" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/HSplitContainer"]
margin_right = 848.0 margin_right = 378.0
margin_bottom = 514.0 margin_bottom = 514.0
size_flags_vertical = 3 size_flags_vertical = 3
[node name="Label" type="Label" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/HSplitContainer/ContentEditContainer"] [node name="Label" type="Label" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/HSplitContainer/ContentEditContainer"]
margin_right = 848.0 margin_right = 378.0
margin_bottom = 14.0 margin_bottom = 14.0
text = "Content" text = "Content"
[node name="DocInputTextEdit" type="TextEdit" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/HSplitContainer/ContentEditContainer"] [node name="DocInputTextEdit" type="TextEdit" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/HSplitContainer/ContentEditContainer"]
unique_name_in_owner = true unique_name_in_owner = true
margin_top = 18.0 margin_top = 18.0
margin_right = 848.0 margin_right = 378.0
margin_bottom = 514.0 margin_bottom = 514.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
@ -210,7 +208,6 @@ show_line_numbers = true
wrap_enabled = true wrap_enabled = true
[node name="ContentPreviewContainer" type="VBoxContainer" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/HSplitContainer"] [node name="ContentPreviewContainer" type="VBoxContainer" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/VBoxContainer/HSplitContainer"]
visible = false
margin_left = 390.0 margin_left = 390.0
margin_right = 848.0 margin_right = 848.0
margin_bottom = 514.0 margin_bottom = 514.0
@ -251,8 +248,6 @@ items = [ "Move Up", null, 0, false, false, 0, 0, null, "", false, "Move Down",
[connection signal="pressed" from="VBoxContainer/HBoxContainer/OpenServerFolderButton" to="." method="_on_OpenServerFolderButton_pressed"] [connection signal="pressed" from="VBoxContainer/HBoxContainer/OpenServerFolderButton" to="." method="_on_OpenServerFolderButton_pressed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/StartServerButton" to="." method="_on_StartServerButton_pressed"] [connection signal="pressed" from="VBoxContainer/HBoxContainer/StartServerButton" to="." method="_on_StartServerButton_pressed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/OpenBrowserButton" to="." method="_on_OpenBrowserButton_pressed"]
[connection signal="pressed" from="VBoxContainer/HSplitContainer/VBoxContainer2/HBoxContainer2/RefreshFilesButton" to="." method="_on_RefreshFilesButton_pressed"]
[connection signal="item_edited" from="VBoxContainer/HSplitContainer/VBoxContainer2/FileTree" to="." method="_on_FileTree_item_edited"] [connection signal="item_edited" from="VBoxContainer/HSplitContainer/VBoxContainer2/FileTree" to="." method="_on_FileTree_item_edited"]
[connection signal="item_rmb_selected" from="VBoxContainer/HSplitContainer/VBoxContainer2/FileTree" to="." method="_on_FileTree_item_rmb_selected"] [connection signal="item_rmb_selected" from="VBoxContainer/HSplitContainer/VBoxContainer2/FileTree" to="." method="_on_FileTree_item_rmb_selected"]
[connection signal="item_selected" from="VBoxContainer/HSplitContainer/VBoxContainer2/FileTree" to="." method="_on_FileTree_item_selected"] [connection signal="item_selected" from="VBoxContainer/HSplitContainer/VBoxContainer2/FileTree" to="." method="_on_FileTree_item_selected"]

View File

@ -13,7 +13,7 @@ const Status = preload("res://addons/http_server/status.gd")
var __endpoints: Dictionary = { var __endpoints: Dictionary = {
# key: [Int, String], array with 0 index representing method, 1 index representing endpoint # key: [Int, String], array with 0 index representing method, 1 index representing endpoint
# value: FuncRef, reference to function to call # value: [FuncRef, Array], index 0 = reference to function to call, index 1 = binds to pass to func
} }
var __fallback: FuncRef = null var __fallback: FuncRef = null
var __server: TCP_Server = null var __server: TCP_Server = null
@ -32,7 +32,7 @@ func endpoint(type: int, endpoint: String, function: FuncRef, binds: Array = [])
) )
return return
__endpoints[endpoint_hash] = function __endpoints[endpoint_hash] = [function, binds]
func fallback(function: FuncRef) -> void: func fallback(function: FuncRef) -> void:
@ -106,7 +106,7 @@ func __process_connection(connection: StreamPeerTCP) -> void:
body = PoolStringArray(body_parts).join("\r\n") body = PoolStringArray(body_parts).join("\r\n")
var response: Response = __process_request(method, endpoint, headers, body) var response: Response = __process_request(method, endpoint, headers, body)
connection.put_data(response.get_data()) connection.put_data(response.to_utf8())
func __process_request(method: String, endpoint: String, headers: Dictionary, body: String) -> Response: func __process_request(method: String, endpoint: String, headers: Dictionary, body: String) -> Response:
@ -121,15 +121,22 @@ func __process_request(method: String, endpoint: String, headers: Dictionary, bo
var endpoint_func: FuncRef = null var endpoint_func: FuncRef = null
var endpoint_parts: PoolStringArray = endpoint.split("/", false) var endpoint_parts: PoolStringArray = endpoint.split("/", false)
var binds
while !endpoint_func: # special case for if endpoint is just root
var endpoint_hash: Array = [type, "/" + endpoint_parts.join("/")] if endpoint == "/":
var endpoint_hash: Array = [type, "/"]
if __endpoints.has(endpoint_hash): if __endpoints.has(endpoint_hash):
endpoint_func = __endpoints[endpoint_hash] endpoint_func = __endpoints[endpoint_hash][0]
elif endpoint_parts.empty(): binds = __endpoints[endpoint_hash][1]
break else:
else: while (!endpoint_func && !endpoint_parts.empty()):
endpoint_parts.remove(endpoint_parts.size() - 1) var endpoint_hash: Array = [type, "/" + endpoint_parts.join("/")]
if __endpoints.has(endpoint_hash):
endpoint_func = __endpoints[endpoint_hash][0]
binds = __endpoints[endpoint_hash][1]
else:
endpoint_parts.remove(endpoint_parts.size() - 1)
if !endpoint_func: if !endpoint_func:
@ -153,7 +160,10 @@ func __process_request(method: String, endpoint: String, headers: Dictionary, bo
"[INF] Recieved request method: %s, endpoint: %s" % [method, endpoint] "[INF] Recieved request method: %s, endpoint: %s" % [method, endpoint]
) )
endpoint_func.call_func(request, response) if !binds:
endpoint_func.call_func(request, response)
else:
endpoint_func.call_func(request, response, binds)
return response return response

View File

@ -11,7 +11,7 @@ enum SOURCE{
const UTF8 := "UTF-8" const UTF8 := "UTF-8"
class MimeType: class MimeType:
var full_type := "application/octet-stream" var full_type := "application/octet-stream"
var type := "application" var type := "application"
var sub_type := "octet-stream" var sub_type := "octet-stream"
@ -49,20 +49,20 @@ class MimeTypeDb:
func process_raw_db(raw_db: Dictionary) -> void: func process_raw_db(raw_db: Dictionary) -> void:
for type in raw_db: for type in raw_db:
var mime_type := MimeType.new() var mime_type := MimeType.new()
mime_type.setup(type, raw_db[type]) mime_type.setup(type, raw_db[type])
if not mime_type.extensions or type == _default_mime_type.type: if not mime_type.extensions or type == _default_mime_type.type:
continue; continue;
for extension in mime_type.extensions: for extension in mime_type.extensions:
if extension in _types and (_types[extension] as MimeType).source > mime_type.source: if extension in _types and (_types[extension] as MimeType).source > mime_type.source:
continue continue
_types[extension] = mime_type _types[extension] = mime_type
func get(ext_or_filename: String) -> MimeType: func get(ext_or_filename: String) -> MimeType:
var ext := ("x."+ext_or_filename.trim_prefix(".")).get_extension().to_lower() var ext := ("x."+ext_or_filename.trim_prefix(".")).get_extension().to_lower()
if not (ext in _types): if not (ext in _types):

View File

@ -11,7 +11,6 @@ var __headers: Dictionary = {
# value: Variant, header value # value: Variant, header value
} }
var __status: int = 200 var __status: int = 200
var __type: MimeTypeHelper.MimeType
# Public methods # Public methods
@ -33,10 +32,6 @@ func status(status: int) -> void:
__status = status __status = status
func type(type: MimeTypeHelper.MimeType) -> void:
__type = type
func to_utf8() -> PoolByteArray: func to_utf8() -> PoolByteArray:
var content = PoolStringArray() var content = PoolStringArray()
@ -50,7 +45,6 @@ func to_utf8() -> PoolByteArray:
data = JSON.print(data) data = JSON.print(data)
__headers['content-length'] = len(data) __headers['content-length'] = len(data)
__headers["content-type"] = "application/octet-stream" if !__type else __type.full_type
for header in __headers: for header in __headers:
content.append("%s: %s" % [header, String(__headers[header])]) content.append("%s: %s" % [header, String(__headers[header])])
@ -61,48 +55,3 @@ func to_utf8() -> PoolByteArray:
content.append(data) content.append(data)
return content.join("\r\n").to_utf8() return content.join("\r\n").to_utf8()
func get_data() -> PoolByteArray:
var res = __response_headers()
var data = __data
if !data:
return res
var type: MimeTypeHelper.MimeType = __type
if !type:
type = MimeTypeHelper.MimeType.new()
if data is String: # else, assume data is PoolByteArray
data = data.to_utf8()
res.append_array(data)
return res
# Private methods
func __response_headers() -> PoolByteArray:
var res = PoolStringArray()
res.append(Status.code_to_status_line(__status))
var data = __data
if !data:
data = Status.code_to_description(__status)
__headers["content-length"] = len(data)
__headers["content-type"] = "application/octet-stream" if !__type else __type.full_type
for header in __headers:
res.append("%s: %s" % [header, String(__headers[header])])
res.append("")
var s = res.join("\r\n")
s = s + "\r\n"
return s.to_utf8()

View File

@ -26,7 +26,7 @@ _global_script_class_icons={
[application] [application]
config/name="Tickle Frontend" config/name="Ticle Frontend"
run/main_scene="res://Main.tscn" run/main_scene="res://Main.tscn"
config/icon="res://icon.png" config/icon="res://icon.png"