Implementing API

This commit is contained in:
Jonathan Bernard 2011-02-05 08:57:34 -06:00
parent 6e2e0d5f00
commit 5809ed3959

@ -130,12 +130,12 @@ put_user(YArg) ->
% will not create, record exists
{error, {record_exists, ExistingRecord}} ->
JSONReturn = json:encode({struct, [
JSONResponse = json:encode({struct, [
{status, "username taken"},
{see_docs, "/ts_api_doc/user#PUT"}
]}),
[{status, 409}, {content, "application/json", JSONReturn}];
[{status, 409}, {content, "application/json", JSONResponse}];
_Error -> make_json_500(YArg)
end.
@ -164,11 +164,14 @@ list_timelines(YArg, Username) ->
% read or default the Start
Start = case lists:keyfind(start, 1, PostData) of
{start, StartVal} -> StartVal; false -> 0 end,
{start, StartVal} -> list_to_integer(StartVal);
false -> 0
end,
% read or default the Length
Length = case lists:keyfind(length, 1, PostData) of
{length, LengthVal} -> erlang:min(LengthVal, 50);
{length, LengthVal} ->
erlang:min(list_to_integer(LengthVal), 50);
false -> 50
end,
@ -190,7 +193,7 @@ get_timeline(YArg, Username, TimelineId) ->
% look for timeline
case ts_timeline:lookup(Username, TimelineId) of
% no such timeline, return 404
no_record -> make_json_404(YArg);
no_record -> make_json_404(YArg, [{status, "no_such_timeline"}]);
% return the timeline data
Timeline -> make_json_200(YArg, Timeline)
end.
@ -212,13 +215,13 @@ put_timeline(YArg, Username) ->
{error, {record_exists, ExistingRecord}} ->
EJSONRec = ts_json:record_to_ejson(ExistingRecord),
JSONReturn = json:encode({struct, [
JSONResponse = json:encode({struct, [
{status, "ignored"},
{timeline, EJSONRec},
{see_docs, "/ts_api_doc/timeline#PUT"}
{see_docs, "/ts_api_doc/timelines#PUT"}
]}),
{content, "application/json", JSONReturn};
{content, "application/json", JSONResponse};
_Error -> make_json_500(YArg)
end.
@ -234,48 +237,156 @@ post_timeline(YArg, Username, TimelineId) ->
ok -> make_json_200(YArg, NewRecord);
no_record -> make_json_404(YArg,
[{status, "no_record"}, {see_docs, "/ts_api_doc/timeline#PSOT"}]);
[{status, "no_such_timeline"},
{see_docs, "/ts_api_doc/timelines#POST"}]);
_Error -> make_json_500(YArg)
end.
delete_timeline(YArg, Username, TimelineId) -> {status, 405}.
list_entries(YArg, Username, Timeline) ->
list_entries(YArg, Username, TimelineId) ->
% pull out the POST data
PostData = yaws_api:parse_post(YArg),
% first determine if we are listing by date
case lists:keyfind(byDate, 1, PostData) of
{byDate, "true"} ->
_Other
% read or default the Start
Start = case lists:keyfind(start, 1, PostData) of
{start, StartVal} -> StartVal; false -> 0 end,
case {ts_timeline:lookup(Username, TimelineId),
lists:keyfind(byDate, 1, PostData)} of
% read or default the Length
Length = case lists:keyfind(length, 1, PostData) of
{length, LengthVal} -> erlang:min(LengthVal, 500);
false -> 50
end,
{no_record, _ByDateField} -> make_json_404(
[{status, "no_such_timeline"},
{see_docs, "/ts_api_doc/entries#LIST"}]);
% read or default the sort order
SortOrder = case lists:keyfind(order, 1, PostData) of
{order, "asc"} -> asc;
{order, "desc"} -> desc;
_Other -> asc
end,
% listing by date range
{Timeline, {byDate, "true"}} ->
Entries = case SortOrder of
asc -> ts_entry:list_asc({Username, Timeline}, Start, Length);
desc -> ts_entry:list_desc({Username, Timeline}, Start, Length)
% look for the start date; default to the beginning of the timeline
StartDate = case lists:keyfind(startDate, 1, PostData) of
% TODO: error handling if the date is badly formatted
{startDate, StartDateVal} -> ts_json:decode_date(StartDateVal);
false -> Timeline#ts_timeline.created
end,
% look for end date; default to right now
EndDate = case lists:keyfind(endDate, 1, PostData) of
% TODO: error handling if the date is badly formatted
{endDate, EndDateVal} -> ts_json:decode_date(EndDateVal);
false -> calendar:now_to_universal_time(erlang:now())
end,
% read sort order and list entries
Entries = case lists:keyfind(order, 1, PostData) ->
% descending sort order
{order, "desc"} -> ts_entry:list_desc(
{Username, TimelineId}, StartDate, EndDate);
% ascending order--{other, asc}--and default
_Other -> ts_entry:list_asc(
{Username, TimelineId}, StartDate, EndDate)
end,
EJSONEntries = {array, lists:map(
fun ts_json:record_to_ejson/1, Entries)},
JSONResponse = json:encode({struct, [
{status, "ok"},
{entries, EJSONEntries}]}),
{content, "application/json", JSONResponse;
% listing by table position
_Other ->
% read or default the Start
Start = case lists:keyfind(start, 1, PostData) of
{start, StartVal} -> list_to_integer(StartVal);
false -> 0
end,
% read or default the Length
Length = case lists:keyfind(length, 1, PostData) of
{length, LengthVal} ->
erlang:min(list_to_integer(LengthVal), 500);
false -> 50
end,
% read sort order and list entries
Entries = case lists:keyfind(order, 1, PostData) of
{order, "desc"} -> ts_entry:list_desc(
{Username, TimelineId}, Start, Length);
_Other -> ts_entry:list_asc(
{Username, TimelineId}, Start, Length)
end,
EJSONEntries = {array, lists:map(
fun ts_json:record_to_ejson/1, Entries)},
JSONResponse = json:encode({struct, [
{status, "ok"},
{entries, EJSONEntries}]}),
{content, "application/json", JSONResponse
end.
get_entry(YArg, Username, TimelineId, EntryId) -> todo.
get_entry(YArg, Username, TimelineId, EntryId) ->
case ts_entry:lookup(Username, TimelineId, EntryId) of
% no such entry
no_record -> make_json_404(YArg, [{status, "no_such_entry"}]);
% return the entry data
Entry -> make_json_200(YArg, Entry)
end.
put_entry(YArg, Username, TimelineId) -> todo.
put_entry(YArg, Username, TimelineId) ->
post_entry(YArg, Username, TimelineId, EntryId) -> todo.
% parse the request body
{done, {ok, EJSON}, _} = json:decode([], binary_to_list(YArg#arg.clidata)),
% pull out the entry data
{struct, Fields} = EJSON,
EJSONEntry = lists:findkey(entry, 1, Fields), % TODO: check for errors
% parse into ts_entry record
NewRecord = ts_json:ejson_to_record(#ts_entry{}, EJSONEntry),
case ts_entry:new(NewRecord) of
% record created
ok -> [{status, 201}, make_json_200(YArg, NewRecord)];
% will not create, record exists
{error, {record_exists, ExistingRecord}} ->
EJSONRec = ts_json:record_to_ejson(ExistingRecord),
JSONResponse = json:encode({struct, [
{status, "ignored"},
{entry, EJSONRec},
{see_docs, "/ts_api_doc/entries#PUT"}
]}),
{content, "application/json", JSONResposne};
_Error -> make_json_500(YArg)
end.
post_entry(YArg, Username, TimelineId, EntryId) ->
% parse the POST data
{done, {ok, EJSON}, _} = json:decode([], binary_to_list(YArg#arg.clidata)),
% pull out the entry data
{struct, Fields} = EJSON,
EJSONEntry = lists:findkey(entry, 1, Fields), % TODO: error handling
% parse into ts_entry record
NewRecord = ts_json:ejson_to_record(#ts_entry{}, EJSONEntry),
case ts_entry:update(NewRecord) of
ok -> make_json_200(YArg, NewRecord);
no_record -> make_json_404(YArg,
[{status, "no_such_entry"}, {see_docs, "/ts_api_doc/entries#POST"}]);
_Error -> make_json_500(YArg)
end.
delete_entry(YArg, Username, TimelineId, EntryId) -> todo.
@ -290,12 +401,17 @@ path_element_to_atom(PE) ->
%% Create a JSON 200 response.
make_json_200(YArg, Record) ->
EJSONRecord = ts_json:record_to_ejson(Record),
JSONReturn = json:encode({struct, [
Tag = case element(1, Record) of
ts_user -> user;
ts_timeilne -> timeline;
ts_entry -> entry
end,
JSONResponse = json:encode({struct, [
{status, "ok"},
{element(1, Record), EJSONRecord}
{Tag, EJSONRecord}
]}),
{content, "application/json", JSONReturn}.
{content, "application/json", JSONResponse}.
%% Create a JSON 404 response.
make_json_404(YArg) -> make_json_404(YArg, []).