/
hello_wiki_rest_client.opa
93 lines (81 loc) · 2.94 KB
/
hello_wiki_rest_client.opa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import stdlib.tools.markdown
uri_for_topic(topic) =
Uri.of_absolute(
{Uri.default_absolute with
schema = {some = "http"} : option(string)
domain = "localhost"
port = {some = 8080} : option(int)
path = ["_rest_", topic]
}
)
@publish load_source(topic) =
match WebClient.Get.try_get(uri_for_topic(topic)) with
| {failure = _} -> "Error, could not connect"
| {~success} ->
match WebClient.Result.get_class(success) with
| {success} -> success.content
| _ -> "Error {success.code}"
end
@publish load_rendered(topic) =
source = load_source(topic)
Markdown.xhtml_of_string(Markdown.default_options, source)
@publish save_source(topic, source) =
match WebClient.Post.try_post(uri_for_topic(topic), source) with
| { failure = _ } ->
{failure = "Could not reach the distant server"}
| { success = s } ->
match WebClient.Result.get_class(s) with
| {success} -> {success = load_rendered(topic)}
| _ -> {failure = "Error {s.code}"}
end
remove_topic(topic) =
_ = WebClient.Delete.try_delete(uri_for_topic(topic))
void
edit(topic) =
do Dom.transform([#show_messages <- <></>])
do Dom.set_value(#edit_content, load_source(topic))
do Dom.hide(#show_content)
do Dom.show(#edit_content)
do Dom.give_focus(#edit_content)
void
save(topic) =
match save_source(topic, Dom.get_value(#edit_content)) with
| { ~success } ->
do Dom.transform([#show_content <- success]);
do Dom.hide(#edit_content);
do Dom.show(#show_content);
void
| {~failure} ->
do Dom.transform([#show_messages <- <>{failure}</>])
void
display(topic) =
Resource.styled_page("About {topic}", ["/resources/css.css"],
<div id=#header><div id=#logo></div>About {topic}</div>
<div class="show_content" id=#show_content ondblclick={_ -> edit(topic)}>{load_rendered(topic)}</>
<div class="show_messages" id=#show_messages />
<textarea class="edit_content" id=#edit_content style="display:none" cols="40" rows="30" onblur={_ -> save(topic)}></>
)
rest(topic) =
match HttpRequest.get_method() with
| {some = method} ->
match method with
| {post} ->
_ = save_source(topic, HttpRequest.get_body()?"")
Resource.raw_status({success})
| {delete} ->
do remove_topic(topic)
Resource.raw_status({success})
| {get} ->
Resource.source(load_source(topic), "text/plain")
| _ ->
Resource.raw_status({method_not_allowed})
end
| _ -> Resource.raw_status({bad_request})
topic_of_path(path) =
String.capitalize(String.to_lower(List.to_string_using("", "", "::", path)))
start =
| {path = [] ... } -> display("Hello")
| {path = ["rest" | path] ...} -> rest(topic_of_path(path))
| {~path ...} -> display(topic_of_path(path))
server = Server.of_bundle([@static_include_directory("resources")])
server = Server.simple_dispatch(start)