Compare commits

..

6 Commits

Author SHA1 Message Date
Trevor Vallender b7ae662fc9 Fixing bin 2024-03-03 20:46:29 +00:00
Trevor Vallender 54c3aca66b First gem release 2024-03-03 20:43:34 +00:00
Trevor Vallender 337f3aa1ca Set recurring events
If we know the birth year, recur from there. Otherwise, recur from the
current year.
2024-03-03 20:42:28 +00:00
Trevor Vallender 57024374ee Refactor to store birthdays in hash
Much more flexible
2024-03-03 20:31:09 +00:00
Trevor Vallender db982373c7 Output an ical file
Almost there—but we’re only adding birthdays to the current year.
2024-03-03 14:52:12 +00:00
Trevor Vallender 36d1e481e9 Output list of birthdays
We can now list all the birthdays for the year, in order.

Started work on icalendar output.
2024-03-03 14:47:25 +00:00
4 changed files with 87 additions and 7 deletions

View File

@ -3,6 +3,7 @@ PATH
specs: specs:
birthdaze (0.0.1) birthdaze (0.0.1)
carddav carddav
icalendar
thor thor
GEM GEM
@ -13,6 +14,9 @@ GEM
nokogiri nokogiri
vcardigan vcardigan
curb (1.0.5) curb (1.0.5)
icalendar (2.10.1)
ice_cube (~> 0.16)
ice_cube (0.16.4)
nokogiri (1.16.2-x86_64-linux) nokogiri (1.16.2-x86_64-linux)
racc (~> 1.4) racc (~> 1.4)
racc (1.7.3) racc (1.7.3)

BIN
birthdaze-0.0.1.gem Normal file

Binary file not shown.

View File

@ -5,10 +5,12 @@ Gem::Specification.new do |s|
s.authors = ["T S Vallender"] s.authors = ["T S Vallender"]
s.email = "t@tsvallender.co.uk" s.email = "t@tsvallender.co.uk"
s.homepage = "https://git.tsvallender.co.uk/tsv/birthdaze" s.homepage = "https://git.tsvallender.co.uk/tsv/birthdaze"
s.files = Dir["lib/**/*", "MIT-LICENSE", "README.md"] s.files = Dir["bin/*", "lib/**/*", "MIT-LICENSE", "README.md"]
s.license = "MIT" s.license = "MIT"
s.bindir = "bin"
s.executables << "birthdaze" s.executables << "birthdaze"
s.add_dependency "thor"
s.add_dependency "carddav" s.add_dependency "carddav"
s.add_dependency "icalendar"
s.add_dependency "thor"
end end

View File

@ -1,12 +1,21 @@
require "carddav" require "carddav"
require "icalendar"
require "thor" require "thor"
require "yaml" require "yaml"
class Birthdaze < Thor class Birthdaze < Thor
desc "generate", "Generate calendars" desc "generate", "Generate calendars"
def generate def generate
puts "Generate calendars" puts "Writing ical file to #{config['ical_output']}"
birthdays File.open(config["ical_output"], 'w') { |file| file.write(calendar.to_ical) }
end
desc "list", "List birthdays"
def list
bdays = birthdays.sort do |a, b|
a[:month] == b[:month] ? a[:day] <=> b[:day] : a[:month] <=> b[:month]
end
bdays.each { |d| puts "🎂 #{d[:day]}/#{d[:month]} - #{d[:name]}" }
end end
private private
@ -25,14 +34,63 @@ class Birthdaze < Thor
end end
def birthdays def birthdays
birthdays = [] return @birthdays if defined? @birthdays
@birthdays = []
client.cards.each do |card| client.cards.each do |card|
card = card.parsed.to_s card = card.parsed.to_s
birthday = birthday_regex.match(card)[1] if birthday_regex.match?(card) birthday = birthday_regex.match(card)[1] if birthday_regex.match?(card)
name = name_regex.match(card)[1] if name_regex.match?(card) name = name_regex.match(card)[1] if name_regex.match?(card)
birthdays << [ name, birthday ] if name && birthday if name && birthday
@birthdays << {
name: name,
month: month_of(birthday),
day: day_of(birthday),
birth_year: birth_year_of(birthday)
}
end end
birthdays end
@birthdays
end
def calendar
return @calendar if defined? @calendar
@calendar = Icalendar::Calendar.new
birthdays.each do |birthday|
@calendar.event do |event|
event.dtstart = Icalendar::Values::Date.new(start_date(birthday))
event.dtend = Icalendar::Values::Date.new(end_date(birthday))
event.summary = summary(birthday)
event.description = description(birthday)
event.rrule = "FREQ=YEARLY;"
end
end
@calendar.publish
end
# Takes a birthday string, with or without a year, and returns a start date
def start_date(birthday)
year = birthday[:birth_year] || Date.today.year
"#{year}#{birthday[:month]}#{birthday[:day]}"
end
def end_date(birthday)
date = Date.parse(start_date(birthday)).next_day
date.strftime("%Y%m%d")
end
def summary(birthday)
"🎂 #{birthday[:name]}s birthday"
end
def description(birthday)
return "" unless birthday[:birth_year]
"#{birthday[:name]} was born in #{birthday[:birth_year]}"
end
def set_reminders
end end
def birthday_regex def birthday_regex
@ -43,4 +101,20 @@ class Birthdaze < Thor
def name_regex def name_regex
/FN.*:(.*)/ /FN.*:(.*)/
end end
def month_of(date)
date.tr("-", "")[-4..-3]
end
def day_of(date)
date.tr("-", "")[-2..-1]
end
def birth_year_of(date)
return nil if date.length < 8
birth_year = date[0..3]
return nil if birth_year == "1604" # This is set (for some reason) by DAVx⁵
birth_year
end
end end