diff --git a/Gemfile.lock b/Gemfile.lock index 5f01b25..314fa4a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,7 @@ PATH specs: birthdaze (0.0.1) carddav + icalendar thor GEM @@ -13,6 +14,9 @@ GEM nokogiri vcardigan curb (1.0.5) + icalendar (2.10.1) + ice_cube (~> 0.16) + ice_cube (0.16.4) nokogiri (1.16.2-x86_64-linux) racc (~> 1.4) racc (1.7.3) diff --git a/birthdaze.gemspec b/birthdaze.gemspec index 33c85d7..c55d493 100644 --- a/birthdaze.gemspec +++ b/birthdaze.gemspec @@ -8,7 +8,8 @@ Gem::Specification.new do |s| s.files = Dir["lib/**/*", "MIT-LICENSE", "README.md"] s.license = "MIT" s.executables << "birthdaze" - s.add_dependency "thor" s.add_dependency "carddav" + s.add_dependency "icalendar" + s.add_dependency "thor" end diff --git a/lib/birthdaze.rb b/lib/birthdaze.rb index 6c6ee2e..96d46f7 100644 --- a/lib/birthdaze.rb +++ b/lib/birthdaze.rb @@ -1,4 +1,5 @@ require "carddav" +require "icalendar" require "thor" require "yaml" @@ -6,7 +7,20 @@ class Birthdaze < Thor desc "generate", "Generate calendars" def generate puts "Generate calendars" - birthdays + puts calendar.inspect + 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]}" } end private @@ -25,14 +39,65 @@ class Birthdaze < Thor end def birthdays - 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 + @birthdays << [ name, birthday ] if name && birthday end - birthdays + @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" if birthday.start_with?("-") || birthday.start_with?("1604") + + birth_year = birthday[0..3].to_i + age = Date.today.year - birth_year + 1 + "🎂 #{name}’s #{age} birthday" + end + + def set_reminders end def birthday_regex @@ -43,4 +108,12 @@ class Birthdaze < Thor def name_regex /FN.*:(.*)/ 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 end