123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- -module(nitro_n2o).
- %% N2O Nitrogen Web Framework Protocol
- -include_lib("nitro/include/n2o.hrl").
- -export([
- info/3,
- render_actions/1,
- io/1,
- io/2,
- event/1
- ]).
- % Nitrogen pickle handler
- %% todo mv this from nitro
- % todo compare with n2o (n4u) and cx without token
- info({text, <<"N2O,", Auth/binary>>}, Req, State) ->
- info(#init{token = Auth}, Req, State);
- info(#init{token = Auth}, Req, State) ->
- {'Token', Token} = authenticate([], Auth),
- Sid = case nitro:depickle(Token) of
- {{S, _}, _} -> S;
- X -> X
- end,
- New = State#cx{session = Sid, token = Auth},
- erlang:put(context, New),
- {reply, {bert,
- case io(init, State) of
- {io, _, {stack, _}} = Io -> Io;
- {io, Code, _} -> {io, Code, {'Token', Token}}
- end},
- Req, New};
- info(#client{data = Message}, Req, State) ->
- erlang:put(actions, []),
- {reply, {bert, io(#client{data = Message}, State)}, Req, State};
- info(#pickle{} = Event, Req, State) ->
- erlang:put(actions, []),
- {reply, {bert, html_events(Event, State)}, Req, State};
- info(#flush{data = Actions}, Req, State) ->
- erlang:put(actions, Actions),
- {reply, {bert, io(<<>>)}, Req, State};
- info(#direct{data = Message}, Req, State) ->
- erlang:put(actions, []),
- {reply, {bert,
- case io(Message, State) of
- {io, _, {stack, _}} = Io -> Io;
- {io, Code, Res} -> {io, Code, {direct, Res}}
- end},
- Req, State};
- info(Message, Req, State) -> {unknown, Message, Req, State}.
- %% double render: actions could generate actions
- render_actions(Actions) ->
- erlang:put(actions, []),
- First = nitro:render(Actions),
- Second = nitro:render(erlang:get(actions)),
- erlang:put(actions, []),
- nitro:to_binary([First, Second]).
- %% n2o events
- html_events(#pickle{source = Source, pickled = Pickled, args = Linked}, State = #cx{token = Token}) ->
- Ev = nitro:depickle(Pickled),
- L = prolongate(),
- Res = case Ev of
- #ev{} when L =:= false ->
- render_ev(Ev, Source, Linked, State),
- <<>>;
- #ev{} ->
- render_ev(Ev, Source, Linked, State),
- authenticate([], Token);
- _CustomEnvelop ->
- %?LOG_ERROR("EV expected: ~p~n",[CustomEnvelop]),
- {error, "EV expected"}
- end,
- io(Res).
- %% todo move work with session to n2o (n4u)
- prolongate() -> %% todo mv this from nitro
- case application:get_env(n2o, session) of
- {ok, M} -> M:prolongate();
- undefined -> false
- end.
- authenticate(I, Auth) -> %% todo mv this from nitro
- (application:get_env(n2o, session, n2o_session)):authenticate(I, Auth).
- %% calling user code in exception-safe manner
- -ifdef(OTP_RELEASE).
- render_ev(#ev{module = M, name = F, msg = P, trigger = T}, _Source, Linked, State) ->
- try case F of
- api_event ->
- M:F(P, Linked, State);
- event ->
- [erlang:put(K, V) || {K, V} <- Linked],
- M:F(P);
- _ ->
- M:F(P, T, State)
- end
- catch E:R:S ->
- ?LOG_EXCEPTION(E, R, S),
- {stack, S}
- end.
- io(Event, #cx{module = Module}) ->
- try
- X = Module:event(Event),
- {io, render_actions(erlang:get(actions)), X}
- catch E:R:S ->
- ?LOG_EXCEPTION(E, R, S),
- {io, [], {stack, S}}
- end.
- io(Data) ->
- try {io, render_actions(erlang:get(actions)), Data}
- catch E:R:S ->
- ?LOG_EXCEPTION(E, R, S),
- {io, [], {stack, S}}
- end.
- -else.
- render_ev(#ev{module = M, name = F, msg = P, trigger = T}, _Source, Linked, State) ->
- try
- case F of
- api_event ->
- M:F(P, Linked, State);
- event ->
- [erlang:put(K, V) || {K, V} <- Linked],
- M:F(P);
- _ ->
- M:F(P, T, State)
- end
- catch E:R ->
- S = erlang:get_stacktrace(),
- ?LOG_EXCEPTION(E, R, S),
- {stack, S}
- end.
- io(Event, #cx{module = Module}) ->
- try
- X = Module:event(Event),
- {io, render_actions(erlang:get(actions)), X}
- catch E:R ->
- S = erlang:get_stacktrace(),
- ?LOG_EXCEPTION(E, R, S),
- {io, <<>>, {stack, S}}
- end.
- io(Data) ->
- try {io, render_actions(erlang:get(actions)), Data}
- catch E:R ->
- S = erlang:get_stacktrace(),
- ?LOG_EXCEPTION(E, R, S),
- {io, <<>>, {stack, S}}
- end.
- -endif.
- %% event Nitrogen Web Framework protocol
- event(_) -> [].
|