Implementing API
This commit is contained in:
parent
6e2e0d5f00
commit
5809ed3959
188
src/ts_api.erl
188
src/ts_api.erl
@ -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, []).
|
||||
|
Loading…
x
Reference in New Issue
Block a user