Skip to content

Instantly share code, notes, and snippets.

@gms8994
Forked from quad/hey.rb
Last active August 29, 2015 14:23
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 gms8994/7cf4744a34ed19cea6e3 to your computer and use it in GitHub Desktop.
Save gms8994/7cf4744a34ed19cea6e3 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#
# hey! a minimalist CRM for http://todotxt.com/
#
# hey tells you one thing you should do regularly, but haven't done lately.
#
# $ todo.sh lf hey
# 1 @phone Mom (+1 234 567 8901) +family
# 2 @skype Dad +family
# 3 @email mentor
# 4 @write old flame <hot@example.com>
# --
# HEY: 4 of 4 tasks shown
#
# $ todo.sh hey
# 37 @phone Mom (+1 234 567 8901) +family
# TODO: 37 added
#
# How To Install:
#
# $ mkdir -p ~/.todo.actions.d/ && pushd ~/.todo.actions.d/
# $ git clone git://gist.github.com/4241425.git hey.git
# $ ln -s hey.git/hey.rb hey && popd
# $ todo.sh addto hey.txt @phone Mom
# $ todo.sh hey
#
# A New Definition of Regularly:
#
# $ echo 'export HEY_CYCLE=30' >> ~/.todo.cfg
#
# Copyright 2012 Scott Robinson <sr@thoughtworks.com>
# Licensed under the Apache License, Version 2.0
require 'date'
module Todo
class List < Array
def initialize fn
replace File.readlines(fn).map { |l| Task.new l }
end
end
class Task < String
DONE_REGEXP = /^x\s+/
PRIORITY_REGEXP = /^\([A-Za-z]\)\s+/
DATE_REGEXP = /
# A date is either ...
(?:
^ | # after the beginning of a line
#{PRIORITY_REGEXP} | # or, after a priority
#{DONE_REGEXP} # or, after a done mark
)
([0-9]{4}-[0-9]{2}-[0-9]{2})\b/x
CONTEXT_REGEXP = /(?:^|\s)@\w+\b/
PROJECT_REGEXP= /(?:^|\s)\+\w+\b/
def date
@date ||= begin
if self =~ DATE_REGEXP
Date.parse $1
end
end
end
def text
@text ||= self.
gsub(DONE_REGEXP, '').
gsub(DATE_REGEXP, '').
gsub(PRIORITY_REGEXP, '').
gsub(CONTEXT_REGEXP, '').
gsub(PROJECT_REGEXP, '').
strip
end
end
end
cmd = ARGV.shift
if cmd == 'usage'
puts <<-EOF
Minimalist CRM:
hey
hey [TERM...]
Adds one task, that hasn't been seen recently, from your hey.txt.
(30 days reocurrence)
EOF
exit
end
['TODO_DIR', 'TODO_FILE', 'DONE_FILE'].each do |fn|
raise "Hey! Where's your $#{fn}?" unless File.exist? ENV[fn].to_s
end
log = Todo::List.new(ENV['TODO_FILE']) + Todo::List.new(ENV['DONE_FILE'])
hey_files = Hash.new
hey_files[ENV['HEY_FILE'] || File.join(ENV['TODO_DIR'], 'hey.txt')] = ENV['HEY_CYCLE'].to_i.zero? ? 30 : ENV['HEY_CYCLE'].to_i
Dir["#{ENV['TODO_DIR']}/hey*.txt"].each { |heyfile|
heyfile.match(/hey(\d+)\.txt/)
if (! $1.nil?)
hey_files[heyfile] = $1.to_i
end
}
hey_files.each { |file, days|
todo = Todo::List.new file
todo = todo.grep(/#{ARGV.join ' '}/i) unless ARGV.empty?
cutoff = Date.today - days
done_or_scheduled = log.select { |t| (t.date || Date.today) > cutoff }.map &:text
new = todo.reject { |t| done_or_scheduled.include? t.text }
hey = if new.respond_to? :choice
new.choice
else
new.sample
end
system ENV['TODO_FULL_SH'], 'add', hey.strip if hey
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment