-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_timeline{}) -> % pull out the timeline id {_Username, TimelineId} = Record#ts_timeline.ref, % create the EJSON struct {struct, [ {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 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, [ {id, EntryId}, {timestamp, encode_datetime(DateTime)}, {mark, Record#ts_entry.mark}, {notes, Record#ts_entry.notes}]}. encode_datetime({{Year, Month, Day}, {Hour, Minute, Second}}) -> io_lib:format("~2B-~2B-~2BT~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, {Username, _} = Empty#ts_timeline.ref, #ts_timeline{ ref = {Username, element(2, lists:keyfind(id, 1, EJSON))}, created = decode_datetime(element(2, lists:keyfind(created, 1, EJSON))), desc = element(2, lists:keyfind(description, 1, EJSON))}. ejson_to_record(Empty=#ts_entry{}, EJSON) -> {struct, Fields} = EJSON, {Username, TimelineId, _} = Empty#ts_entry.ref, #ts_entry{ ref = {Username, TimelineId, element(2, lists:keyfind(id, 1, EJSON))}, timestamp = calendar:datetime_to_gregorian_seconds(decode_datetime( element(2, lists:keyfind(timestamp, 1, EJSON)))), mark = element(2, lists:keyfind(mark, 1, EJSON)), notes = element(2, lists:keyfind(notes, 1, EJSON))}. 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}.