Skip to content

Instantly share code, notes, and snippets.

@zkessin
Created November 1, 2017 11:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zkessin/44204d9e258662e879e5bf0f4ff5506c to your computer and use it in GitHub Desktop.
Save zkessin/44204d9e258662e879e5bf0f4ff5506c to your computer and use it in GitHub Desktop.
-module(wm_elm).
-compile(export_all).
%-compile({parse_transform, ct_expand}).
%-pt_pp_src(false).
-include_lib("webmachine/include/webmachine.hrl").
-include("squaretarget.hrl").
-spec(routes() ->[webmachine_dispatcher:route()]).
-type rd() :: wrq:reqdata().
-type elm_file() :: elm|elm_trial.
-type state() :: term().
-ifndef(DEV).
-compile({parse_transform, ct_expand}).
-define(PT(X),ct_expand:term(X)).
-else.
-define(PT(X),identity(X)).
-endif.
identity(X) ->
X.
routes() ->
[
{["elm-front.js"], ?MODULE, ['elm_front']}
,{["elm-reset.js"], ?MODULE, ['elm_reset']}
,{["elm-dashboard.js"], ?MODULE, ['elm_dashboard']}
,{["elm-dashboard-login.js"], ?MODULE, ['elm_dashboard_login']}
].
-spec( init([elm_file()]) -> {?INIT_RETURN_TYPE, elm_file()}).
init([File]) ->
{?INIT_RETURN_CODE, File }.
resource_exists(RD, State) ->
{true, RD, State}.
-spec encodings_provided(rd(), state()) -> {[{Encoding::string(), Encoder}], rd(), state()}
when Encoder :: fun((iodata()) -> iodata()).
encodings_provided(ReqData, State) ->
{[{"identity", fun(X) -> X end},
{"gzip", fun(X) -> zlib:gzip(X) end}],
ReqData, State}.
% IN dev mode we load the elm from disk, in prod load it from the beam file
-spec to_javascript(wrq:reqdata(), term()) -> {iodata(), wrq:reqdata(), term()}.
to_javascript(ReqData, State) ->
lager:debug("Load Elm", []),
{ok, Elm} = case State of
elm_front -> ?PT(elm_front_live());
elm_reset -> ?PT(elm_reset_live());
elm_dashboard -> ?PT(elm_dashboard_live());
elm_dashboard_login -> ?PT(elm_dashboard_login_live())
end,
{Elm, ReqData, State}.
-spec generate_etag(rd(), state()) -> {string() | undefined, rd(), state()}.
generate_etag(RD, State= elm_front) ->
{?PT(etag(elm_front)), RD, State};
generate_etag(RD, State= elm_reset) ->
{?PT(etag(elm_reset)), RD, State};
generate_etag(RD, State= elm_dashboard) ->
{?PT(etag(elm_dashboard)), RD, State};
generate_etag(RD, State= elm_dashboard_login) ->
{?PT(etag(elm_dashboard_login)), RD, State}.
-spec content_types_provided(wrq:reqdata(), state()) -> {[{MediaType::string(), Handler::atom()}], wrq:reqdata(), state()}.
content_types_provided(ReqData, State) ->
{[{"application/javascript", to_javascript}],ReqData,State}.
etag(elm_front) ->
{ok, Data} = elm_front_live(),
binary_to_list(base64:encode(crypto:hash(md5,Data)));
etag(elm_reset) ->
{ok, Data} =elm_reset_live(),
binary_to_list(base64:encode(crypto:hash(md5,Data)));
etag(elm_dashboard) ->
{ok, Data} =elm_dashboard_live(),
binary_to_list(base64:encode(crypto:hash(md5,Data)));
etag(elm_dashboard_login) ->
{ok, Data} =elm_dashboard_login_live(),
binary_to_list(base64:encode(crypto:hash(md5,Data))).
elm_front_live() ->
PrivDir = code:priv_dir('squaretarget'),
Filename = filename:join([PrivDir, "elm-front.js"]),
{ok, Data} = file:read_file(Filename),
{ok, Data}.
elm_reset_live() ->
PrivDir = code:priv_dir('squaretarget'),
Filename = filename:join([PrivDir, "elm-reset.js"]),
{ok, Data} = file:read_file(Filename),
{ok, Data}.
elm_dashboard_live() ->
PrivDir = code:priv_dir('squaretarget'),
Filename = filename:join([PrivDir, "elm-dashboard.js"]),
{ok, Data} = file:read_file(Filename),
{ok, Data}.
elm_dashboard_login_live() ->
PrivDir = code:priv_dir('squaretarget'),
Filename = filename:join([PrivDir, "elm-dashboard-login.js"]),
{ok, Data} = file:read_file(Filename),
{ok, Data}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment