Skip to content

Instantly share code, notes, and snippets.

@craigeley
Created December 30, 2017 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craigeley/a839c9dc5e29d5106805c67519335b93 to your computer and use it in GitHub Desktop.
Save craigeley/a839c9dc5e29d5106805c67519335b93 to your computer and use it in GitHub Desktop.
Find completed Things tasks, cross reference them with Google Timeline, and send the output of each location to Day One.
#!/usr/local/bin/ruby
# Scipt for using Using Google Time to create summary records of Things in Day One
require 'time'
require 'date'
require 'json'
require 'yaml/store'
require 'nokogiri'
# To prevent encoding errors on OSX
if RUBY_VERSION =~ /2.*.*/
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
end
# Read from the Google Timeline file and get day
f = File.open("#{ARGV[0]}")
kmldoc = Nokogiri::XML(f)
date = kmldoc.css('Document/name').to_s
/(?<dateString>\d*-\d*-\d*)/ =~ date
today = Time.parse(dateString).strftime("%Y%m%d")
datestamp = Time.parse(dateString).utc.iso8601
num = (Date.today - Date.parse(dateString)).to_i
secs = (86400*num)
# Set filepath and persistent variables
yml = File.expand_path("../../../2018/data/data.yml", __FILE__)
store = YAML::Store.new(yml)
tz_token = store.transaction { store[:google_tz ] }
# Get Tasks from Things
output = ''
tasktext = %x{ osascript <<APPLESCRIPT
set theDate to date string of ((current date) - #{secs})
tell application "Things3"
set output to ""
repeat with toDo in (to dos whose status is completed)
set toDoName to name of toDo
set toDoDate to completion date of toDo
set toDoTime to time string of toDoDate
set toDoDone to date string of toDoDate
if toDoDone is equal to theDate then
if tag names of toDo as text = "" then
set toDoTag to "inbox"
else
set toDoTag to tag names of toDo
end if
set output to output & "- " & toDoTime & " - " & toDoName & " @" & toDoTag & linefeed
end if
end repeat
return output
end tell
APPLESCRIPT}
taskarray = []
tasktext.lines.each do |line|
if match = line.match(/(-\s)(.*?)\s-(.*)@(.*)/)
dash, time, task, tag = match.captures
time = time.to_s
task = task.strip
if tag == ""
tag = "Inbox"
end
time = Time.parse(time).strftime("%s").to_i - secs
inject = { :name => task, :time => time, :tag => tag }
taskarray.push(inject)
end
end
taskarray = taskarray.sort_by {|h| h[:time] }
# Get places from Google Timeline, plug in todos if the times line up, send to Day One
kmldoc.xpath('//xmlns:Placemark').each do |place|
placetext = ''
tagtext = ''
currentarray = []
location = place.css('name').text
sTime = place.css('begin').text
eTime = place.css('end').text
coord = place.css('gx|coord').first.text
lon, lat, zero = coord.split(/\s/)
timeIso = Time.parse(sTime).utc.iso8601
sTime = Time.parse(sTime).strftime("%s").to_i
eTime = Time.parse(eTime).strftime("%s").to_i
taskarray.each do |unit|
if (sTime...eTime).include?(unit[:time])
currentarray.push(unit)
end
end
currentarray = currentarray.sort_by {|h| [h[:tag],h[:time]]}
uniq_tags = currentarray.map { |e| e[:tag] }.uniq
uniq_tags.each do |tagger|
tagcap = tagger.capitalize
tagtext += "\n### #{tagcap}\n"
currentarray.each do |unit|
if unit.has_value?(tagger)
tagtext += "- " + Time.at(unit[:time]).strftime("%I:%M %p") + " - " + unit[:name] + "\n"
end
end
end
tz_url = "https://maps.googleapis.com/maps/api/timezone/json?location=#{lat},#{lon}&timestamp=#{eTime}&key=#{tz_token}"
tz_response = %x{curl -sS "#{tz_url}"}
tz_data = JSON.parse(tz_response)
tz = tz_data["timeZoneId"]
placetext += "## #{location}\n#{tagtext}"
`/usr/local/bin/dayone2 new "#{placetext}" --coordinate #{lat} #{lon} --isoDate "#{timeIso}" -z "#{tz}"`
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment