Source

webcandy / src / webmstn_notes_resource.erl

The default branch has multiple heads

Full commit
%% @author sunneach http://bitbuckets.com/sunneach
%% @copyright 2009 sunneach
%% @doc Example webmachine_resource.

-module(webmstn_notes_resource).
-export([
		init/1,
		content_types_provided/2,
		allowed_methods/2,
		content_types_accepted/2,
		process_post/2,
		resource_exists/2,
		finish_request/2,
		delete_resource/2
		]).
-export([to_json/2,from_json/2]).

-record(ncontext,{id,data,input}).

-include_lib("webmachine/include/webmachine.hrl").

init([]) -> {ok, #ncontext{}};
init([Cfg]) -> 
    {trace_dir,Dir} = Cfg,
	AbsDir =filename:absname(Dir), 
	{{trace,AbsDir},#ncontext{}}.

content_types_provided(RD,Ctx) ->
    {[{"application/json",to_json}],RD,Ctx}.

to_json(RD, Ctx) ->
    {Ctx#ncontext.data, RD, Ctx}.

allowed_methods(RD, Ctx) ->
    {case wrq:path_info(note, RD) of
          undefined         -> ['POST'];
          _ -> ['GET', 'HEAD', 'PUT','DELETE']
       end,
     RD, Ctx}.

content_types_accepted(RD, Ctx) ->  % called when 'PUT' comes
       {[{"application/x-www-form-urlencoded", from_json}], RD, Ctx}.
%   {[{"application/json", from_json}], RD, Ctx}.

%% PUT
%% update record
from_json(RD, Ctx) ->
    {_Ans,RD1,Ctx1} = action(update,RD,Ctx),
    {true,RD1,Ctx1}.

%% POST
%% Create record
process_post(RD,Ctx) ->
    {_Ans,RD1,Ctx1} = action(create,RD,Ctx),
    {true,RD1,Ctx1}.
  
%% DELETE record
delete_resource(RD, Ctx) ->
    RD1 = wrq:set_resp_header("Content-Type", "application/json",RD),	
    Str = Ctx#ncontext.input, % passed from resource_exists
	case Ctx#ncontext.id of
	all ->
          {true, RD1, Ctx};
	_   ->       
          Ans1 = notes:delete(Str),
          Ans = mochijson2:encode(Ans1),
          {true, RD1, Ctx#ncontext{data=Ans}}
    end.

%% DELETE, PUT support
finish_request(RD, Ctx) ->
    {Ctx#ncontext.data, RD, Ctx}.

%%  POST and PUT
action(Act,RD,Ctx) ->
    Data = mochiweb_util:parse_qs(wrq:req_body(RD)),
    Struct = mochijson2:decode(proplists:get_value("json", Data)),
	%% will crush if action IS NOT Act
    Act = list_to_atom(binary_to_list(struct:get_value(<<"action">>, Struct))),
    RD1 = wrq:set_resp_header("Content-Type", "application/json",RD),
    Ans = mochijson2:encode(notes:Act(Struct)),
    RD2 = wrq:append_to_resp_body(Ans,RD1),
    {Ans, RD2, Ctx}.

%%  GET,HEAD
%%  read_all, 
resource_exists(RD, Ctx) ->
    case wrq:method(RD) of
	'POST' -> 
               {true,RD,[]};
    _ ->
 		    	case wrq:path_info(note, RD) of
    			"all" ->
		        	notes(all,RD,Ctx#ncontext{id=all});
    			Id ->
			    	notes(Id,RD,Ctx#ncontext{id=Id})
				end
	end.

%%  notes access: read_all action
notes(all,RD,Ctx) ->
    RD1 = wrq:set_resp_header("Content-Type", "application/json",RD),
    Ans = mochijson2:encode(notes:read_all([])),
    {true, RD1, Ctx#ncontext{id=all,data=Ans}};

%%  notes access: read Id 
notes(Id,RD,Ctx) ->
    RD1 = wrq:set_resp_header("Content-Type", "application/json",RD),	
    Str = {struct, [{<<"id">>, list_to_integer(Id)}]},
    Ans1 = notes:read(Str),
    Ans = mochijson2:encode(Ans1),
	{case struct:get_value(<<"id">>,Ans1) of
          undefined -> false;
	      _Doc      -> true
     end,
     RD1,Ctx#ncontext{id=Id,data=Ans,input=Str}}. % Ctx defined at Init