Last active
April 30, 2017 06:04
-
-
Save siers/19981104ca7223361842 to your computer and use it in GitHub Desktop.
a more natural alarm clock command line interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'time' | |
def die(str) | |
$stderr.puts str | |
exit | |
end | |
def usage | |
die "Usage: nap { for <float>[<h|m|s>] | until <date(1) parsable datestr> | cycles [<int>[+<int>]] }" + | |
"\ne.g. nap for 3h\n nap until 10AM\n nap cycles 4\n " + | |
"nap cycles 4+10 # 10 minutes to brush teeth" | |
end | |
def hourminutes(hours) | |
wholes = hours.to_i | |
minutes = (hours - hours.to_i) * 60 | |
"#{ wholes }:#{ ("0" + minutes.to_i.to_s)[-2..-1] }" | |
end | |
def kind_for(time) | |
aliases = {'m' => 60, 'h' => 3600, 's' => 1} | |
prefix = aliases[(time.match('[hms]$') || ['s'])[0]] | |
yield "# date format bogus" unless time.match(/^\d+(\.\d+)?([hms])?$/) | |
"sudo rtcwake -m mem -s #{ time.to_f.*(prefix).to_i }" | |
end | |
def successfully(args) | |
errors, pipe = IO.pipe | |
IO.popen(args, err: pipe) do |p| p.read end.tap do | |
pipe.close | |
die errors.read unless $?.success? | |
end | |
end | |
def kind_until(time) | |
date = successfully(%w{date -d} + [time]) | |
secs = successfully(%w{date -d} + [time] + %w{+%s}).to_i | |
hours = (((secs.to_i - Time.now.to_i) / 36) / 100.0) | |
yield "# %s hours" % hourminutes(hours) if (0.40..60).include? hours | |
yield "# #{ date }" | |
"sudo rtcwake -m mem -t #{ secs }" | |
end | |
def kind_cycles(n = nil, &block) | |
# Print time, if n = nil. | |
# n = '1' -> sleep one cycle + 14 minutes | |
# n = '1+20' -> sleep one cylce + 14 minutes + 20 minutes to brush teeth | |
gen = proc do |i, j| | |
cycle = 3600 * 3 / 2 | |
tts = 14 * 60 # a joke on Time To Live | |
(Time.now + (cycle * i + tts + (j || 0) * 60)).strftime('%H:%M') | |
end | |
enough = 6 | |
times = (1..enough).map { |i| gen.call i } | |
if n | |
m, o = n.split('+').map(&:to_i) | |
unless (1..enough).include? m | |
yield "# only cycles 1 through #{ enough } are meant to be used" | |
end | |
kind_until(gen.call(m, o), &block) | |
else | |
yield "# according to http://sleepyti.me" | |
yield "# you should wake up at:" | |
yield("# " + times.join(', ')) | |
end | |
end | |
kind = ARGV[0] | |
timedescr = ARGV[1..-1] | |
if ARGV.length == 2 | |
usage if !kind.match(/^(until|for|cycles)$/) | |
elsif ARGV.length == 1 | |
usage if kind != 'cycles' | |
else | |
usage | |
end | |
cmd = send(:"kind_#{ kind }", *timedescr) { |info| $stderr.puts info } | |
puts cmd if cmd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment