Skip to content

Instantly share code, notes, and snippets.

@twopoint718
Last active May 2, 2024 22:18
Show Gist options
  • Save twopoint718/e67123ffec10de8a26372edd0e5bf225 to your computer and use it in GitHub Desktop.
Save twopoint718/e67123ffec10de8a26372edd0e5bf225 to your computer and use it in GitHub Desktop.
CalBot schedule your book reading for the year. Produces an iCal file for importing into your reading calendar.
#!/usr/bin/env ruby
require 'date'
require 'securerandom'
require 'optparse'
def header()
<<~EOS
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:-//SENCJW Heavy Industries, Ltd.//CalBot//EN
VERSION:2.0
EOS
end
def event(d, name)
now = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
uuid = SecureRandom.uuid.upcase
dtstart="#{d.year}#{'%02d' % d.month}#{'%02d' % d.day}"
<<~EOS
BEGIN:VEVENT
CREATED:#{now}
DTSTAMP:#{now}
DTSTART;VALUE=DATE:#{dtstart}
SUMMARY:#{name}
TRANSP:TRANSPARENT
UID:#{uuid}
END:VEVENT
EOS
end
options = {}
optp = OptionParser.new do |opts|
opts.banner = "Usage: calbot.rb [options]"
opts.on("-h", "--help", "Show help") do
puts opts
exit 0
end
opts.on("-oFILE", "--output=FILE", "Specify output calendar file (.ics format)") do |f|
options[:filename] = f
end
opts.on("-nNUM", "--num=NUM", "Set number of books to read (default 52)") do |n|
options[:num_books] = n.to_i
end
opts.on("-yYEAR", "--year=YEAR", "Set the reading year (default this year)") do |y|
options[:year] = y.to_i
end
end
optp.parse!
unless options[:filename]
puts "Output filename argument is required (-o)"
puts optp
exit 1
end
if options[:num_books]
days_per_book = 365 / options[:num_books]
else
options[:num_books] = 52
days_per_book = 7
end
unless options[:year]
options[:year] = Time.now.year
end
File.open(options[:filename], 'w') do |f|
f.write(header())
start_date = Date.new(options[:year], 1, 1)
(0...options[:num_books]).each do |n|
date = start_date + n * days_per_book
f.write(event(date, "Book #{n+1}"))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment