Skip to content

Instantly share code, notes, and snippets.

@ixmatus
Created December 19, 2014 20:28
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 ixmatus/22b5290322d6b9091d13 to your computer and use it in GitHub Desktop.
Save ixmatus/22b5290322d6b9091d13 to your computer and use it in GitHub Desktop.
-module(new_dim_handler).
-export([init/3]).
-export([allowed_methods/2]).
-export([ content_types_provided/2
, content_types_accepted/2
]).
-export([ dim_to_json/2
, dim_from_json/2
]).
%% ===================================================================
%% Custom Types
%% ===================================================================
-type cowboy_method() :: {bitstring(), cowboy_req:req()}.
%% ===================================================================
%% Cowboy REST interface functions
%% ===================================================================
-spec init(_,_,[]) -> {'upgrade','protocol','cowboy_rest'}.
init(_Transport, _Req, []) ->
{upgrade, protocol, cowboy_rest}.
%% @doc Only allow GET and POST.
-spec allowed_methods(_,_) -> {[<<_:24,_:_*8>>,...],_,_}.
allowed_methods(Req, State) ->
{[<<"GET">>, <<"POST">>], Req, State}.
%% @doc Only serve JSON.
%%
%% TODO: clean this up, it's not RESTful but because the mobile app
%% programmed against the old API surface we have to support the
%% "broken" client implementation which doesn't specify clearly what
%% content type it's sending nor wanting.
-spec content_types_provided(_,_) -> {[{<<_:128>>,'dim_to_json'},...],_,_}.
content_types_provided(Req, State) ->
{[ {<<"application/json">>, dim_to_json}
], Req, State}.
-spec content_types_accepted(_,_) -> {[{<<_:128>>,'dim_to_json'},...],_,_}.
content_types_accepted(Req, State) ->
{[ {<<"application/json">>, dim_from_json}
, {<<"application/json; charset=utf-8">>, dim_from_json}
], Req, State}.
%% ===================================================================
%% Primary method handlers
%% ===================================================================
dim_to_json(Req, State) ->
{Binding, Req2} = cowboy_req:binding(uuid, Req, none),
get_dim(Binding, Req2, State).
dim_from_json(Req, State) ->
{Binding, Req2} = cowboy_req:binding(uuid, Req, none),
Body = cowboy_req:body(Req2),
handle_set_dim(Binding, Body, Req2, State).
respond(Data, Req) ->
R = jsx:encode(Data),
cowboy_req:set_resp_body(R, Req).
handle_set_dim(_, {error, Reason}, Req, State) ->
R = jsx:encode(#{<<"error">> => atom_to_binary(Reason, utf8)}),
Req2 = cowboy_req:set_resp_body(R, Req),
{false, Req2, State};
handle_set_dim(none, {_, Data, Req2}, _, State) ->
Js = jsx:decode(Data, [return_maps]),
R = plumapi:post("dimmer", Js),
{true, respond(R, Req2), State};
handle_set_dim(<<"all">>, {_, Data, Req2}, _, State) ->
Js = jsx:decode(Data, [return_maps]),
R = cluster:do(plumapi, post, ["dimmer", Js]),
{true, respond(R, Req2), State};
handle_set_dim(UUID, {_, Data, Req2}, _, State) ->
Js = jsx:decode(Data, [return_maps]),
R = plumapi:post(UUID, "dimmer", Js),
{true, respond(R, Req2), State}.
get_dim(none, Req, State) ->
Dim = plumapi:get("dimmer"),
{jsx:encode(Dim), Req, State};
get_dim(<<"all">>, Req, State) ->
Dim = cluster:do(plumapi, get, ["dimmer"]),
{jsx:encode(Dim), Req, State};
get_dim(UUID, Req, State) ->
Dim = plumapi:get(UUID, "dimmer"),
{jsx:encode(Dim), Req, State}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment