timestamper/src/ts_json.erl

83 lines
2.8 KiB
Erlang
Raw Normal View History

-module(ts_json).
-export([encode_record/1, record_to_ejson/1, ejson_to_record/2]).
-include("ts_db_records.hrl").
encode_record(Record) -> lists:flatten(json:encode(record_to_ejson(Record))).
record_to_ejson(Record=#ts_user{}) ->
{struct, [
{username, atom_to_list(Record#ts_user.username)},
{name, Record#ts_user.name},
{email, Record#ts_user.email},
{join_date, encode_datetime(Record#ts_user.join_date)}]};
record_to_ejson(Record=#ts_timeline{}) ->
% pull out the username and timeline id
{Username, TimelineId} = Record#ts_timeline.ref,
% create the EJSON struct
{struct, [
{username, atom_to_list(Username)},
{timeline_id, atom_to_list(TimelineId)},
{created, encode_datetime(Record#ts_timeline.created)},
{description, Record#ts_timeline.desc}]};
record_to_ejson(Record=#ts_entry{}) ->
% pull out the username, timeline id, and entry id
{Username, TimelineId, EntryId} = Record#ts_entry.ref,
% convert the timestamp to a date-time
DateTime = calendar:gregorian_seconds_to_datetime(Record#ts_entry.timestamp),
% create the EJSON struct
{struct, [
{username, Username},
{timeline_id, TimelineId},
{entry_id, EntryId},
{timestamp, encode_datetime(DateTime)},
{mark, Record#ts_entry.mark},
{notes, Record#ts_entry.notes}]}.
encode_datetime({{Year, Month, Day}, {Hour, Minute, Second}}) ->
lists:flatten(io_lib:format("~4.10.0B-~2.10.0B-~2.10.0BT~2.10.0B:~2.10.0B:~2.10.0BZ",
[Year, Month, Day, Hour, Minute, Second])).
ejson_to_record(_Empty=#ts_timeline{}, EJSON) ->
{struct, Fields} = EJSON,
#ts_timeline{
ref = {undefined, undefined},
created = decode_datetime(element(2, lists:keyfind(created, 1, Fields))),
desc = element(2, lists:keyfind(description, 1, Fields))};
ejson_to_record(_Empty=#ts_entry{}, EJSON) ->
{struct, Fields} = EJSON,
#ts_entry{
ref = {undefined, undefined, undefined},
timestamp = calendar:datetime_to_gregorian_seconds(decode_datetime(
element(2, lists:keyfind(timestamp, 1, Fields)))),
mark = element(2, lists:keyfind(mark, 1, Fields)),
notes = element(2, lists:keyfind(notes, 1, Fields))}.
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}]),
[HourString, MinuteString, SecondString] =
re:split(TimeString, ":", [{return, list}]),
Date = {list_to_integer(YearString), list_to_integer(MonthString),
list_to_integer(DayString)},
Time = {list_to_integer(HourString), list_to_integer(MinuteString),
list_to_integer(SecondString)},
{Date, Time}.