From 98032e2b8987b094b445a6c4d3be3f7dccc85c14 Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Fri, 11 Oct 2013 20:06:31 +0000 Subject: [PATCH] Added UUIDs to timestamps, refactored the build process * Added UUIDs to `ts_entry` records. Updated `ts_json:construct_record` to respond to `uuid` member properties if present. UUIDs are not required by the strict parsing functions in `ts_json` because the client will make a request with no UUID if it is a purely new timestamp. IN fact, this is the normal case. The UUID is only present when another tool is syncing its copy of this timeline wand adding entries that it has created and assigned UUIDs to. * `ts_entry:new` will create a UUID for a new entry if it does not already have one. * Restructured the build process to put all build artifacts into a dedicated `build` subdirectory, instead of mising them in an amongst the source code. * Added the `uuid` module to the project. It can be found at https://gitorious.org/avtobiff/erlang-uuid * Rewrote asset URLs to use relative paths instead of absolute paths. Relative paths are correct in this case, becuase assets always live alongside the HTML pages. This change was needed to accomodate the new organization of the JDB Labs dev environment, where all projects live under subdirectories of the same virtual server instead of subdomains. * Tweaked the timestamp entry fields in the web UI to save when the field is blurred, not just when or - is pressed (though those still work). --- .gitignore | 2 +- Makefile | 36 ++++++++++++------------ lib/uuid.app | 7 +++++ src/ts_db_records.hrl | 2 ++ src/ts_entry.erl | 6 +++- src/ts_json.erl | 3 ++ www/index.yaws | 20 +++++++------- www/js/ts.js | 64 ++++++++++++++++++++----------------------- 8 files changed, 77 insertions(+), 63 deletions(-) create mode 100644 lib/uuid.app diff --git a/.gitignore b/.gitignore index 320cf6c..c5222e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ +build/ *.sw? -ebin/ *.beam .sass-cache diff --git a/Makefile b/Makefile index 32f7245..2ae5d28 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ MODS = $(wildcard src/*.erl) -BEAMS = $(MODS:src/%.erl=ebin/%.beam) +BEAMS = $(MODS:src/%.erl=build/ebin/%.beam) TEST_MODS = $(wildcard test/*.erl) -TEST_BEAMS = $(TEST_MODS:test/%.erl=test/%.beam) +TEST_BEAMS = $(TEST_MODS:test/%.erl=build/test/%.beam) TS_ROOT=/usr/local/var/yaws/jdb-labs.com/timestamper CWD = `pwd` -default: compile +default: build all : compile test @@ -17,10 +17,10 @@ test : start-test-server run-test stop-test-server test-shell : compile compile-test config-yaws-dev @echo Starting an interactive YAWS shell with test paths loaded. - @yaws -i --pa test --id test_inst + @yaws -i --pa build/ebin --pa build/test --id test_inst run-test : compile compile-test config-yaws-dev - @erl -pa ./ebin -pa ./test -run timestamper_api_tests test -run init stop -noshell + @erl -pa ./build/ebin -pa ./build/test -run timestamper_api_tests test -run init stop -noshell start-test-server : @yaws -D --id test_inst @@ -29,28 +29,30 @@ stop-test-server : @yaws --stop --id test_inst clean: - rm -rf ebin/* erl_crash.dump test/*.beam + rm -rf build init: - -mkdir ebin + -mkdir -p build/ebin -ebin/%.beam : src/%.erl - erlc -W -o ebin $< +build/ebin/%.beam : src/%.erl + erlc -W -o build/ebin $< -test/%.beam : test/%.erl +build/test/%.beam : test/%.erl @echo Compiling sources... - erlc -W -o test $< + erlc -W -o build/test $< + +build: compile + -mkdir -p build/include + cp -r www build + cp lib/* build/ebin + cp src/ts_db_records.hrl build/include + cp yaws.prod.conf build/yaws.conf deploy: compile @service yaws stop @echo Removing existing artifacts. - @rm -r $(TS_ROOT) @echo Copying current artifacts. - @mkdir -p $(TS_ROOT) - @cp -r www $(TS_ROOT) - @cp -r ebin $(TS_ROOT) - @mkdir $(TS_ROOT)/include - @cp -r src/ts_db_records.hrl $(TS_ROOT)/include/. - @cp yaws.prod.conf $(TS_ROOT)/yaws.conf + @cp -r build $(TS_ROOT) @service yaws start @echo Done. diff --git a/lib/uuid.app b/lib/uuid.app new file mode 100644 index 0000000..5bbd1a0 --- /dev/null +++ b/lib/uuid.app @@ -0,0 +1,7 @@ +{application, uuid, + [{description, "Erlang UUID"}, + {vsn, "0.4.4"}, + {modules, [uuid]}, + {registered, []}, + {applications, [stdlib, crypto]}, + {env, []}]}. diff --git a/src/ts_db_records.hrl b/src/ts_db_records.hrl index cab0f00..37544d9 100644 --- a/src/ts_db_records.hrl +++ b/src/ts_db_records.hrl @@ -28,6 +28,8 @@ -record(ts_entry, { ref, % {username, timelineid, entryid} + uuid, % UUID for this entry across all implementations and copies of + % this timeline. timestamp, % gregorian seconds mark, % String description of entry notes % String with further notes about the entry diff --git a/src/ts_entry.erl b/src/ts_entry.erl index c3d4d3a..a0a9179 100644 --- a/src/ts_entry.erl +++ b/src/ts_entry.erl @@ -24,7 +24,11 @@ new(ER = #ts_entry{}, ExtData) when is_list(ExtData) -> do_new(ER = #ts_entry{}) -> {Username, TimelineId, _} = ER#ts_entry.ref, NextId = id_counter:next_counter(ts_entry_id), - NewRow = ER#ts_entry{ref = {Username, TimelineId, NextId}}, + RowWithRef = ER#ts_entry{ref = {Username, TimelineId, NextId}}, + NewRow = case RowWithRef#ts_entry.uuid of + undefined -> RowWithRef#ts_entry{uuid = uuid:uuid4()}; + _ -> RowWithRef + end, ok = mnesia:write(NewRow), NewRow. diff --git a/src/ts_json.erl b/src/ts_json.erl index ef4ddc2..f24b190 100644 --- a/src/ts_json.erl +++ b/src/ts_json.erl @@ -46,6 +46,7 @@ record_to_ejson(Record=#ts_timeline{}, ExtData) -> % "id": "1", % "timestamp": "2011-01-01T14:01.000Z", % "mark": "Workout.", +% "uuid": "98ed5198-0c98-47c7-96c9-52b57a2c605a", % "notes": "First workout after a long break."} record_to_ejson(Record=#ts_entry{}, ExtData) -> @@ -62,6 +63,7 @@ record_to_ejson(Record=#ts_entry{}, ExtData) -> {id, EntryId}, {timestamp, encode_datetime(DateTime)}, {mark, Record#ts_entry.mark}, + {uuid, uuid:to_string(Record#ts_entry.uuid)}, {notes, Record#ts_entry.notes}] ++ lists:map(fun ext_data_to_ejson/1, ExtData)}. @@ -171,6 +173,7 @@ construct_record(Entry=#ts_entry{}, [{Key, Value}|Fields], ExtData) -> decode_datetime(Value))}, Fields, ExtData); mark -> construct_record(Entry#ts_entry{mark=Value}, Fields, ExtData); + uuid -> construct_record(Entry#ts_entry{uuid=uuid:to_binary(Value)}, Fields, ExtData); notes -> construct_record(Entry#ts_entry{notes=Value}, Fields, ExtData); _Other -> ExtDataProp = ejson_to_ext_data({Key, Value}), diff --git a/www/index.yaws b/www/index.yaws index fe92278..256de7b 100644 --- a/www/index.yaws +++ b/www/index.yaws @@ -3,7 +3,7 @@ TimeStamper - Simple Time Tracking - + @@ -12,13 +12,13 @@ --> - + - - - - - + + + + + @@ -86,8 +86,8 @@ out(YArg) ->