require 'net/http' require 'json' require 'date' XKCD_URI = 'https://xkcd.com' DATE_FORMAT_STR = '%B %-d, %Y' $displayed_xkcd = nil $prev_displayed_xkcd = nil # Get's the nth xkcd entry, unless # nil is passed, in which case current def get_nth_xkcd(n) uri = URI.join(XKCD_URI, n.to_s + '/', 'info.0.json') response = Net::HTTP.get(uri) JSON.parse(response) end # Get's the current, featured xkcd entry def get_current_xkcd get_nth_xkcd(nil) end # Get's a random xkcd def get_random_xkcd curr_id = get_current_xkcd['num'] random_id = nil # 404 is reserved for Not found while true do random_id = rand(curr_id) break if random_id != 404 end get_nth_xkcd(random_id) end # Check if provided xkcd was published yesterday def published_yesterday_and_unseen(xkcd_date, xkcd) xkcd_date == Date.today.prev_day and ($prev_displayed_xkcd.nil? or not $prev_displayed_xkcd['num'] == xkcd['num']) end # Basic logic: # - if an xkcd was published today, display it. # - if an xkcd was published yesterday, and we didn't # show it yesterday, display it. # - otherwise, display a random xkcd. SCHEDULER.every '1d', :first_in => 0 do |job| $prev_displayed_xkcd = $displayed_xkcd xkcd = get_current_xkcd xkcd_date = Date.new( xkcd['year'].to_i, xkcd['month'].to_i, xkcd['day'].to_i ) if xkcd_date == Date.today or published_yesterday_and_unseen(xkcd_date, xkcd) $displayed_xkcd = xkcd else $displayed_xkcd = get_random_xkcd xkcd_date = Date.new( $displayed_xkcd['year'].to_i, $displayed_xkcd['month'].to_i, $displayed_xkcd['day'].to_i ) end $displayed_xkcd['datestr'] = xkcd_date.strftime(DATE_FORMAT_STR) send_event('xkcd-of-the-day', $displayed_xkcd) end