Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Daily background logger to write completed TaskPaper tasks (system-wide) to a Day One entry
#!/usr/bin/ruby
# tp-dailylog.rb - Log TaskPaper tasks completed on the current day to a Day One entry
# Brett Terpstra 2012 <http://brettterpstra.com>
#
# Run it with launchd at 11pm and forget about it
#
# Notes:
# * Uses `mdfind` to locate all .taskpaper files changed in the last day
# * Scans for @done(xxxx-xx-xx) tags in each line matching today's date
# * Does not alter TaskPaper files in any way
# * Does not require the Day One CLI tool
# * Only generates report if there are completed tasks found
# * It's configured to locate an iCloud-synced journal.
# If you use Dropbox or other, you'll want to just hardcode the path (comment line 23, edit `dayonepath` line 24)
# * To set the automatic Day One entries to starred, just change `starred = false` to true
require 'time'
require 'erb'
uuid = %x{uuidgen}.gsub(/-/,'').strip
datestamp = Time.now.utc.iso8601
starred = false
dayonedir = %x{ls ~/Library/Mobile\\ Documents/|grep dayoneapp}.strip
dayonepath = "~/Library/Mobile\ Documents/#{dayonedir}/Documents/Journal_dayone/entries/"
template = ERB.new <<-XMLTEMPLATE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Creation Date</key>
<date><%= datestamp %></date>
<key>Entry Text</key>
<string><%= entrytext %></string>
<key>Starred</key>
<<%= starred %>/>
<key>UUID</key>
<string><%= uuid %></string>
</dict>
</plist>
XMLTEMPLATE
today = Time.now().strftime('%Y-%m-%d')
files = %x{mdfind 'kMDItemContentModificationDate >= "$time.today(-1)" && kMDItemKind == "TaskPaperDocumentType"'}
projects = []
files.each do |file|
if File.exists?(file.strip)
f = File.open(file.strip)
lines = f.read
f.close
project = "### " + File.dirname(file).gsub(/^.*?\/([^\/]+)$/,"\\1") + ":\n\n"
found_completed = false
lines.each do |line|
if line =~ /@done\(#{today}\)/
found_completed = true
project += line.gsub(/@done\(.*?\)/,'').strip + "\n"
end
end
if found_completed
projects.push(project)
end
end
end
def e_sh(str)
str.to_s.gsub(/(?=["\\])/, '\\')
end
if projects.length > 0
entrytext = "# Task report for #{today}\n\n"
projects.each do |project|
entrytext += project + "\n\n"
end
fh = File.new(File.expand_path(dayonepath+uuid+".doentry"),'w+')
fh.puts template.result(binding)
fh.close
end
@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Mar 16, 2012

The if condition projects.length always returns true, so even on days with no completed tasks, a header-only entry will be created in Day One. I changed the test to projects.length > 0 to avoid this. (In Ruby, zero does not evaluate to false)

Also, on my system the mdfind command above does not work. I can only imagine it has something to do with the locale on my machine. In my script I replaced the mdfind command with the following:

mdfind 'kMDItemContentModificationDate >= "$time.today(-1)" && kMDItemKind == "TaskPaperDocumentType"'
@ttscoff

This comment has been minimized.

Copy link
Owner Author

@ttscoff ttscoff commented Mar 17, 2012

Very nice, thanks for the fixes. I've updated this gist with both suggestions.

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Mar 18, 2012

You are very welcome. I have had so much good use of the various scripts you have provided, so I am just happy to be able to contribute a tiny bit.

@craigeley

This comment has been minimized.

Copy link

@craigeley craigeley commented Jan 8, 2014

Got this to work on Mavericks by changing line 48 to files.split("\n").each do |file| and line 50 to f = File.open(file.strip, encoding: 'UTF-8')

@matt-the-ogre

This comment has been minimized.

Copy link

@matt-the-ogre matt-the-ogre commented Feb 8, 2014

I had to add lines = lines.split("\n") between lines 52 and 53 for this to work on my Mavericks installation. (After the f.close line.)
Otherwise I got ./tp-dailylog.rb:55:in 'block in <main>': undefined method 'each' for #<String:0x007fcd1b103c78> (NoMethodError)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment