2011-01-30 08:28:56 -06:00
|
|
|
-module(ts_json).
|
2011-06-07 20:47:23 -05:00
|
|
|
-export([encode_record/1, record_to_ejson/1, ejson_to_record/2, ejson_to_record_strict/2]).
|
2011-01-30 08:28:56 -06:00
|
|
|
|
|
|
|
-include("ts_db_records.hrl").
|
|
|
|
|
|
|
|
encode_record(Record) -> lists:flatten(json:encode(record_to_ejson(Record))).
|
|
|
|
|
2011-06-07 20:47:23 -05:00
|
|
|
% User JSON record structure:
|
|
|
|
% {"id": "john_doe",
|
|
|
|
% "name": "John Doe",
|
|
|
|
% "email": "john.doe@example.com",
|
|
|
|
% "join_date": "2011-01-01T12:00.000Z",
|
|
|
|
% "ext_data": {"last_timeline", "personal"}}
|
|
|
|
|
2011-02-03 17:23:40 -06:00
|
|
|
record_to_ejson(Record=#ts_user{}) ->
|
|
|
|
{struct, [
|
2011-05-03 12:17:00 -05:00
|
|
|
{id, Record#ts_user.username},
|
2011-02-03 17:23:40 -06:00
|
|
|
{name, Record#ts_user.name},
|
|
|
|
{email, Record#ts_user.email},
|
2011-05-03 12:17:00 -05:00
|
|
|
{join_date, encode_datetime(Record#ts_user.join_date)},
|
|
|
|
{ext_data, Record#ts_user.ext_data}]};
|
2011-02-03 17:23:40 -06:00
|
|
|
|
2011-06-07 20:47:23 -05:00
|
|
|
% Timeline JSON record stucture:
|
|
|
|
% {"user_id": "john_doe",
|
|
|
|
% "id": "personal",
|
|
|
|
% "created": "2011-01-01T14:00.000Z",
|
|
|
|
% "description:"Personal time-tracking."}
|
|
|
|
|
2011-01-30 08:28:56 -06:00
|
|
|
record_to_ejson(Record=#ts_timeline{}) ->
|
2011-02-03 17:23:40 -06:00
|
|
|
% pull out the username and timeline id
|
|
|
|
{Username, TimelineId} = Record#ts_timeline.ref,
|
2011-01-30 08:28:56 -06:00
|
|
|
|
|
|
|
% create the EJSON struct
|
|
|
|
{struct, [
|
2011-05-03 12:17:00 -05:00
|
|
|
{user_id, Username},
|
|
|
|
{id, TimelineId},
|
2011-01-30 08:28:56 -06:00
|
|
|
{created, encode_datetime(Record#ts_timeline.created)},
|
2011-02-02 16:57:58 -06:00
|
|
|
{description, Record#ts_timeline.desc}]};
|
2011-01-30 08:28:56 -06:00
|
|
|
|
2011-06-07 20:47:23 -05:00
|
|
|
% Entry JSON record structure:
|
|
|
|
% {"user_id": "john_doe",
|
|
|
|
% "timeline_id": "personal",
|
|
|
|
% "id": "1",
|
|
|
|
% "timestamp": "2011-01-01T14:01.000Z",
|
|
|
|
% "mark": "Workout.",
|
|
|
|
% "notes": "First workout after a long break."}
|
|
|
|
|
2011-01-30 08:28:56 -06:00
|
|
|
record_to_ejson(Record=#ts_entry{}) ->
|
2011-02-03 17:23:40 -06:00
|
|
|
% pull out the username, timeline id, and entry id
|
|
|
|
{Username, TimelineId, EntryId} = Record#ts_entry.ref,
|
2011-01-30 08:28:56 -06:00
|
|
|
|
|
|
|
% convert the timestamp to a date-time
|
|
|
|
DateTime = calendar:gregorian_seconds_to_datetime(Record#ts_entry.timestamp),
|
|
|
|
|
|
|
|
% create the EJSON struct
|
|
|
|
{struct, [
|
2011-05-03 12:17:00 -05:00
|
|
|
{user_id, Username},
|
|
|
|
{timeline_id, TimelineId},
|
2011-04-15 13:51:01 -05:00
|
|
|
{id, EntryId},
|
2011-01-30 08:28:56 -06:00
|
|
|
{timestamp, encode_datetime(DateTime)},
|
|
|
|
{mark, Record#ts_entry.mark},
|
|
|
|
{notes, Record#ts_entry.notes}]}.
|
|
|
|
|
|
|
|
encode_datetime({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
2011-05-03 12:17:00 -05:00
|
|
|
lists:flatten(io_lib:format("~4.10.0B-~2.10.0B-~2.10.0BT~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0BZ",
|
2011-03-07 16:43:40 -06:00
|
|
|
[Year, Month, Day, Hour, Minute, Second, 000])).
|
2011-01-30 08:28:56 -06:00
|
|
|
|
2011-06-07 20:47:23 -05:00
|
|
|
ejson_to_record(Rec=#ts_timeline{}, EJSON) ->
|
|
|
|
{struct, Fields} = EJSON,
|
|
|
|
|
|
|
|
Created = case lists:keyfind(created, 1, Fields) of
|
|
|
|
false -> undefined;
|
|
|
|
{created, CreatedVal} -> decode_datetime(CreatedVal)
|
|
|
|
end,
|
|
|
|
|
|
|
|
Desc = case lists:keyfind(description, 1, Fields) of
|
|
|
|
false -> undefined;
|
|
|
|
{description, DescVal} -> DescVal
|
|
|
|
end,
|
|
|
|
|
|
|
|
Rec#ts_timeline{
|
|
|
|
created = Created,
|
|
|
|
desc = Desc };
|
|
|
|
|
|
|
|
ejson_to_record(Rec=#ts_entry{}, EJSON) ->
|
|
|
|
{struct, Fields} = EJSON,
|
|
|
|
|
|
|
|
Timestamp = case lists:keyfind(timestamp, 1, Fields) of
|
|
|
|
false -> undefined;
|
|
|
|
{timestamp, TSVal} -> calendar:datetime_to_gregorian_seconds(
|
|
|
|
decode_datetime(TSVal))
|
|
|
|
end,
|
|
|
|
|
|
|
|
Mark = case lists:keyfind(mark, 1, Fields) of
|
|
|
|
false -> undefined;
|
|
|
|
{mark, MarkVal} -> MarkVal
|
|
|
|
end,
|
|
|
|
|
|
|
|
Notes = case lists:keyfind(notes, 1, Fields) of
|
|
|
|
false -> undefined;
|
|
|
|
{notes, NotesVal} -> NotesVal
|
|
|
|
end,
|
|
|
|
|
|
|
|
Rec#ts_entry{
|
|
|
|
timestamp = Timestamp,
|
|
|
|
mark = Mark,
|
|
|
|
notes = Notes}.
|
|
|
|
|
|
|
|
ejson_to_record_strict(Rec=#ts_timeline{}, EJSON) ->
|
2011-01-30 08:28:56 -06:00
|
|
|
{struct, Fields} = EJSON,
|
|
|
|
|
2011-06-07 20:47:23 -05:00
|
|
|
Rec#ts_timeline{
|
2011-02-02 16:57:58 -06:00
|
|
|
created = decode_datetime(element(2, lists:keyfind(created, 1, Fields))),
|
|
|
|
desc = element(2, lists:keyfind(description, 1, Fields))};
|
2011-01-30 08:28:56 -06:00
|
|
|
|
2011-06-07 20:47:23 -05:00
|
|
|
ejson_to_record_strict(Rec=#ts_entry{}, EJSON) ->
|
2011-01-30 08:28:56 -06:00
|
|
|
{struct, Fields} = EJSON,
|
|
|
|
|
2011-06-07 20:47:23 -05:00
|
|
|
Rec#ts_entry{
|
2011-01-30 08:28:56 -06:00
|
|
|
timestamp = calendar:datetime_to_gregorian_seconds(decode_datetime(
|
2011-02-02 16:57:58 -06:00
|
|
|
element(2, lists:keyfind(timestamp, 1, Fields)))),
|
|
|
|
mark = element(2, lists:keyfind(mark, 1, Fields)),
|
|
|
|
notes = element(2, lists:keyfind(notes, 1, Fields))}.
|
2011-01-30 08:28:56 -06:00
|
|
|
|
|
|
|
decode_datetime(DateTimeString) ->
|
|
|
|
% TODO: catch badmatch and badarg on whole function
|
|
|
|
|
|
|
|
[DateString, TimeString] = re:split(DateTimeString, "[TZ]",
|
|
|
|
[{return, list}, trim]),
|
|
|
|
|
|
|
|
[YearString, MonthString, DayString] =
|
|
|
|
re:split(DateString, "-", [{return, list}]),
|
|
|
|
|
2011-03-07 16:43:40 -06:00
|
|
|
[HourString, MinuteString, SecondString] =
|
|
|
|
case re:split(TimeString, "[:\\.]", [{return, list}]) of
|
|
|
|
[HS, MS, SS, _MSS] -> [HS, MS, SS];
|
|
|
|
[HS, MS, SS] -> [HS, MS, SS]
|
|
|
|
end,
|
2011-01-30 08:28:56 -06:00
|
|
|
|
|
|
|
Date = {list_to_integer(YearString), list_to_integer(MonthString),
|
2011-02-02 16:57:58 -06:00
|
|
|
list_to_integer(DayString)},
|
2011-01-30 08:28:56 -06:00
|
|
|
|
|
|
|
Time = {list_to_integer(HourString), list_to_integer(MinuteString),
|
2011-02-02 16:57:58 -06:00
|
|
|
list_to_integer(SecondString)},
|
2011-01-30 08:28:56 -06:00
|
|
|
|
|
|
|
{Date, Time}.
|