Last active
December 10, 2015 13:58
-
-
Save edvardm/4444476 to your computer and use it in GitHub Desktop.
finnish holiday calendar supporting local file cache
This file contains hidden or 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
require 'date' | |
require 'tmpdir' | |
require 'open-uri' | |
require 'digest' | |
require 'ri_cal' | |
class HolidayCalendar | |
DEFAULT_CAL_URI = 'https://www.google.com/calendar/ical/fi.finnish%23holiday%40group.v.calendar.google.com/public/basic.ics' | |
CACHE_MAX_DAYS = 360 | |
def initialize(opts={}) | |
@opts = {} | |
@holidays = nil | |
@cal_uri = opts[:cal_uri] || DEFAULT_CAL_URI | |
@calendar_cache = opts[:cache_file] || cache_path | |
end | |
def cache_path | |
File.join(Dir.tmpdir, cache_basename) | |
end | |
def parse | |
if needs_cache_refresh?(@calendar_cache) | |
write_cache(@calendar_cache, read_calendar(@cal_uri)) | |
end | |
@holidays = build_hash RiCal.parse(open(@calendar_cache)) | |
end | |
# read calendar from uri. Can be local file or remote path | |
def read_calendar(uri) | |
open(uri).read | |
end | |
def needs_cache_refresh?(fpath) | |
!File.exist?(fpath) || cache_age_in_days(fpath) > CACHE_MAX_DAYS | |
end | |
def cache_age_in_days(fpath) | |
(Time.now - File.mtime(fpath)) / 86400 | |
end | |
# return hash keyed by holiday date object, with holiday name as value | |
def holidays | |
parse unless @holidays | |
@holidays | |
end | |
def weekday?(date) | |
!holiday? | |
end | |
def holiday?(date) | |
weekend?(date) || holidays.has_key?(date) | |
end | |
def weekend?(date) | |
[0, 6].include?(date.wday) | |
end | |
private | |
def write_cache(fpath, content) | |
STDERR.puts 'creating cache' | |
File.open(fpath, 'w') do |f| | |
f.write content | |
end | |
end | |
def cache_basename | |
[Digest::MD5.hexdigest(@cal_uri), 'calendar_cache.ics'].join('-') | |
end | |
def build_hash(cal) | |
cal.each_with_object({}) do |occ, days| | |
occ.events.each do |evt| | |
day = evt.dtstart | |
days[day] = evt.summary | |
end | |
end | |
end | |
end | |
# example usage: | |
# c = HolidayCalendar.new | |
# c.holidays.sort.each do |d, v| | |
# puts "%s: %s" % [d, v] | |
# end | |
# c.holiday?(Date.new(2013, 1, 1)) # => true | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment