Current section
Files
Jump to
Current section
Files
src/tale@server.erl
-module(tale@server).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/tale/server.gleam").
-export([serve/1, main/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/tale/server.gleam", 62).
?DOC(" Detects the public root\n").
-spec detect_public_root() -> binary().
detect_public_root() ->
case tale@site:resolved_public_root() of
{ok, Path} ->
Path;
{error, Error} ->
erlang:error(#{gleam_error => panic,
message => Error,
file => <<?FILEPATH/utf8>>,
module => <<"tale/server"/utf8>>,
function => <<"detect_public_root"/utf8>>,
line => 65})
end.
-file("src/tale/server.gleam", 114).
?DOC(" Page not found response\n").
-spec not_found() -> gleam@http@response:response(ewe:response_body()).
not_found() ->
_pipe = gleam@http@response:new(404),
_pipe@1 = gleam@http@response:set_header(
_pipe,
<<"content-type"/utf8>>,
<<"text/plain; charset=utf-8"/utf8>>
),
gleam@http@response:set_body(_pipe@1, {text_data, <<"Not found"/utf8>>}).
-file("src/tale/server.gleam", 121).
?DOC(" Content type development server supports\n").
-spec content_type(binary()) -> binary().
content_type(Path) ->
case begin
_pipe = gleam@string:split(Path, <<"."/utf8>>),
_pipe@1 = lists:reverse(_pipe),
gleam@list:first(_pipe@1)
end of
{ok, <<"html"/utf8>>} ->
<<"text/html; charset=utf-8"/utf8>>;
{ok, <<"css"/utf8>>} ->
<<"text/css; charset=utf-8"/utf8>>;
{ok, <<"js"/utf8>>} ->
<<"application/javascript; charset=utf-8"/utf8>>;
{ok, <<"json"/utf8>>} ->
<<"application/json; charset=utf-8"/utf8>>;
{ok, <<"svg"/utf8>>} ->
<<"image/svg+xml"/utf8>>;
{ok, <<"png"/utf8>>} ->
<<"image/png"/utf8>>;
{ok, <<"jpg"/utf8>>} ->
<<"image/jpeg"/utf8>>;
{ok, <<"jpeg"/utf8>>} ->
<<"image/jpeg"/utf8>>;
{ok, <<"ico"/utf8>>} ->
<<"image/vnd.microsoft.icon"/utf8>>;
_ ->
<<"application/octet-stream"/utf8>>
end.
-file("src/tale/server.gleam", 107).
?DOC(" Succesfull Response\n").
-spec success_response(binary(), ewe:response_body()) -> gleam@http@response:response(ewe:response_body()).
success_response(Path, Body) ->
_pipe = gleam@http@response:new(200),
_pipe@1 = gleam@http@response:set_header(
_pipe,
<<"content-type"/utf8>>,
content_type(Path)
),
gleam@http@response:set_body(_pipe@1, Body).
-file("src/tale/server.gleam", 93).
-spec serve_candidates(binary(), list(binary())) -> gleam@http@response:response(ewe:response_body()).
serve_candidates(Root, Paths) ->
case Paths of
[] ->
not_found();
[Path | Rest] ->
Absolute = <<<<Root/binary, "/"/utf8>>/binary, Path/binary>>,
case ewe:file(Absolute, none, none) of
{ok, Body} ->
success_response(Path, Body);
{error, _} ->
serve_candidates(Root, Rest)
end
end.
-file("src/tale/server.gleam", 139).
-spec has_extension(binary()) -> boolean().
has_extension(Path) ->
gleam_stdlib:contains_string(Path, <<"."/utf8>>).
-file("src/tale/server.gleam", 74).
-spec candidate_paths(list(binary())) -> list(binary()).
candidate_paths(Segments) ->
Clean = begin
_pipe = Segments,
_pipe@1 = gleam@list:filter(
_pipe,
fun(Segment) ->
(Segment /= <<"."/utf8>>) andalso (Segment /= <<""/utf8>>)
end
),
gleam@list:filter(
_pipe@1,
fun(Segment@1) -> Segment@1 /= <<".."/utf8>> end
)
end,
case Clean of
[] ->
[<<"index.html"/utf8>>];
[<<""/utf8>> | Rest] ->
candidate_paths(Rest);
Segments@1 ->
Joined = gleam@string:join(Segments@1, <<"/"/utf8>>),
case has_extension(Joined) of
true ->
[Joined];
false ->
[<<Joined/binary, ".html"/utf8>>,
<<Joined/binary, "/index.html"/utf8>>]
end
end.
-file("src/tale/server.gleam", 69).
-spec static_handler(
gleam@http@request:request(ewe@internal@http1:connection()),
binary()
) -> gleam@http@response:response(ewe:response_body()).
static_handler(Req, Root) ->
Candidates = candidate_paths(gleam@http@request:path_segments(Req)),
serve_candidates(Root, Candidates).
-file("src/tale/server.gleam", 143).
-spec rebuild_site() -> nil.
rebuild_site() ->
case tale@site:build_site() of
{ok, Messages} ->
gleam@list:each(
Messages,
fun(Message) -> logging:log(info, Message) end
);
{error, Problem} ->
logging:log(error, <<"Build failed: "/utf8, Problem/binary>>)
end.
-file("src/tale/server.gleam", 183).
-spec dedup(list(binary())) -> list(binary()).
dedup(Paths) ->
gleam@list:fold(
Paths,
[],
fun(Acc, Path) -> case gleam@list:contains(Acc, Path) of
true ->
Acc;
false ->
[Path | Acc]
end end
).
-file("src/tale/server.gleam", 192).
-spec absolute_path(binary(), binary()) -> binary().
absolute_path(Base, Path) ->
Joined = case filepath:is_absolute(Path) of
true ->
Path;
false ->
filepath:join(Base, Path)
end,
case filepath:expand(Joined) of
{ok, Expanded} ->
Expanded;
{error, _} ->
Joined
end.
-file("src/tale/server.gleam", 152).
?DOC(" Paths in the directory that watcher monitor for changes\n").
-spec paths_to_watch() -> list(binary()).
paths_to_watch() ->
Cwd = begin
_pipe = simplifile:current_directory(),
gleam@result:unwrap(_pipe, <<"."/utf8>>)
end,
case tale@config:load() of
{ok, Site_config} ->
Site_paths = tale@config:site_paths(Site_config),
_pipe@1 = dedup(
[<<"config.toml"/utf8>>,
erlang:element(8, Site_config),
erlang:element(3, Site_paths),
erlang:element(4, Site_paths),
erlang:element(5, Site_paths),
erlang:element(6, Site_paths)]
),
gleam@list:map(_pipe@1, fun(Path) -> absolute_path(Cwd, Path) end);
{error, Problem} ->
logging:log(
warning,
<<"Watcher fallback paths: "/utf8, Problem/binary>>
),
[absolute_path(Cwd, <<"config.toml"/utf8>>),
absolute_path(Cwd, <<"content"/utf8>>),
absolute_path(Cwd, <<"layouts"/utf8>>),
absolute_path(Cwd, <<"assets"/utf8>>),
absolute_path(Cwd, <<"static"/utf8>>)]
end.
-file("src/tale/server.gleam", 26).
-spec serve(integer()) -> nil.
serve(Port) ->
logging_ffi:configure(),
logging:set_level(info),
rebuild_site(),
Root = detect_public_root(),
logging:log(
info,
<<<<<<"Serving "/utf8, Root/binary>>/binary,
" on http://localhost:"/utf8>>/binary,
(erlang:integer_to_binary(Port))/binary>>
),
_ = tale@watch:start({watch_config, paths_to_watch(), fun rebuild_site/0}),
Handler = fun(Req) -> static_handler(Req, Root) end,
case begin
_pipe = ewe:new(Handler),
_pipe@1 = ewe:bind_all(_pipe),
_pipe@2 = ewe:listening(_pipe@1, Port),
ewe:start(_pipe@2)
end of
{ok, _} ->
gleam_erlang_ffi:sleep_forever();
{error, Error} ->
logging:log(
error,
<<"Failed to start server: "/utf8,
(gleam@string:inspect(Error))/binary>>
)
end.
-file("src/tale/server.gleam", 22).
-spec main() -> nil.
main() ->
serve(8000).