birthdaze/lib/birthdaze.rb

116 lines
3.0 KiB
Ruby
Raw Normal View History

2024-03-02 14:50:16 +00:00
require "carddav"
require "icalendar"
2024-03-02 14:50:16 +00:00
require "thor"
require "yaml"
class Birthdaze < Thor
desc "generate", "Generate calendars"
def generate
puts "Writing ical file to #{config['ical_output']}"
File.open(config["ical_output"], 'w') { |file| file.write(calendar.to_ical) }
end
desc "list", "List birthdays"
def list
display = birthdays.map do |name, birthday|
{
name: name,
month: month_of(start_date(birthday)),
day: day_of(start_date(birthday)),
}
end
display.sort! { |a, b| a[:month] == b[:month] ? a[:day] <=> b[:day] : a[:month] <=> b[:month] }
display.each { |d| puts "🎂 #{d[:month]}/#{d[:day]} - #{d[:name]}" }
2024-03-02 14:50:16 +00:00
end
private
def config(config_file = "#{ENV["HOME"]}/.config/birthdaze.yaml")
2024-03-02 14:50:16 +00:00
unless File.file?(config_file)
puts "Please add a configuration file"
return
end
2024-03-02 14:50:16 +00:00
@config ||= YAML.load_file(config_file)
end
def client(url: config["url"], username: config["username"], password: config["password"])
@client ||= Carddav::Client.new(url, username, password)
end
def birthdays
return @birthdays if defined? @birthdays
@birthdays = []
client.cards.each do |card|
card = card.parsed.to_s
birthday = birthday_regex.match(card)[1] if birthday_regex.match?(card)
name = name_regex.match(card)[1] if name_regex.match?(card)
@birthdays << [ name, birthday ] if name && birthday
end
@birthdays
end
def calendar
return @calendar if defined? @calendar
@calendar = Icalendar::Calendar.new
birthdays.each do |name, birthday|
@calendar.event do |event|
puts name
event.dtstart = Icalendar::Values::Date.new(start_date(birthday))
event.dtend = Icalendar::Values::Date.new(end_date(birthday))
event.summary = summary(name, birthday)
end
end
@calendar.publish
end
# Takes a birthday string, with or without a year, and returns a start date
def start_date(birthday)
year = Date.today.year
birthday = birthday.tr("-", "")
birthday = birthday.gsub("1604", "") if birthday.start_with?("1604")
if birthday.length < 8 # No year specified
"#{year}#{birthday[0..3]}"
else
"#{year}#{birthday[4..7]}"
end
end
def end_date(birthday)
year = Date.today.year
birthday = birthday.tr("-", "")
birthday = birthday.gsub("1604", "") if birthday.start_with?("1604")
if birthday.length < 8 # No year specified
"#{year}#{birthday[0..1]}#{birthday[2..3].to_i + 1}"
else
"#{year}#{birthday[4..5]}#{birthday[6..7].to_i + 1}"
end
end
def summary(name, birthday)
return "🎂 #{name}s birthday"
end
def set_reminders
end
def birthday_regex
# We need the dash for dates which dont specify a year
/.*BDAY.*:([\d-]*).*/
end
def name_regex
/FN.*:(.*)/
2024-03-02 14:50:16 +00:00
end
def month_of(date)
date.length < 8 ? date[0..1] : date[4..5]
end
def day_of(date)
date.length < 8 ? date[2..3] : date[6..7]
end
2024-03-02 14:50:16 +00:00
end