Add Garmin LiveTrack session tracking
A Gmail-watching Apps Script (documented in docs/deployment.adoc) posts the session ID from each LiveTrack email to a new webhook, which stores it in data/livetrack.json; a new sidebar panel lists what's been received.
This commit is contained in:
1 parent
60170efda2
commit
f9ddf860ea
11 files changed
+279
No files matched your search
@@ -0,0 +1,63 @@
|
||||
require "json"
|
||||
require "fileutils"
|
||||
|
||||
module Maptool
|
||||
# JSON-file-backed store of Garmin LiveTrack session IDs, appended to by a
|
||||
# webhook whenever a new LiveTrack email arrives (see docs/deployment.adoc).
|
||||
# Validity/expiry of a session isn't tracked here — checking whether a
|
||||
# given ID still has live data is up to whoever polls Garmin with it.
|
||||
class LiveTrackStore
|
||||
def initialize(path)
|
||||
@path = path
|
||||
@mutex = Mutex.new
|
||||
FileUtils.mkdir_p(File.dirname(@path))
|
||||
File.write(@path, "[]") unless File.exist?(@path)
|
||||
end
|
||||
|
||||
# Records `session_id`, moving it to the front if already present.
|
||||
def add(session_id)
|
||||
@mutex.synchronize do
|
||||
sessions = read
|
||||
sessions.reject! { |s| s["id"] == session_id }
|
||||
sessions.unshift({ "id" => session_id, "received_at" => Time.now.utc.iso8601 })
|
||||
File.write(@path, JSON.pretty_generate(sessions))
|
||||
end
|
||||
end
|
||||
|
||||
# Most recently received first.
|
||||
def list
|
||||
read
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def read
|
||||
JSON.parse(File.read(@path))
|
||||
rescue Errno::ENOENT, JSON::ParserError
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if __FILE__ == $0
|
||||
require "tmpdir"
|
||||
|
||||
Dir.mktmpdir do |dir|
|
||||
store = Maptool::LiveTrackStore.new(File.join(dir, "livetrack.json"))
|
||||
raise "expected empty list" unless store.list == []
|
||||
|
||||
store.add("abc123")
|
||||
store.add("def456")
|
||||
raise "expected 2 sessions" unless store.list.size == 2
|
||||
raise "expected newest first" unless store.list.first["id"] == "def456"
|
||||
|
||||
store.add("abc123")
|
||||
raise "expected re-added session moved to front, not duplicated" \
|
||||
unless store.list.map { |s| s["id"] } == %w[abc123 def456]
|
||||
|
||||
reloaded = Maptool::LiveTrackStore.new(File.join(dir, "livetrack.json"))
|
||||
raise "expected data to survive reload" unless reloaded.list.size == 2
|
||||
end
|
||||
|
||||
puts "ok"
|
||||
end
|
||||
Reference in new issue
Block a user