#!/usr/bin/env ruby # coding: utf-8 require 'open-uri' require 'nokogiri' require 'erb' MONTHS = [ "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", ] def fmt_time t t.strftime "%Y%m%dT%H%M%S" end class Event attr_accessor :title, :url attr_reader :date, :location, :dtstart, :dtend def initialize @location = "AZ Conni, Rudolf-Leonhard-Straße 39" end def date=(s) if s =~ /(\d{1,2})\.\s*(.+?)\s*(\d{4})[^\d]*(\d{1,2}):(\d{2})[^\d]*(\d{1,2}):(\d{2})/ year = $3.to_i month = MONTHS.index($2) + 1 day = $1.to_i @dtstart = Time::local year, month, day, $4.to_i, $5.to_i, 0 @dtend = Time::local year, month, day, $6.to_i, $7.to_i, 0 elsif s =~ /(\d{1,2})\.\s*(.+?)\s*(\d{4})[^\d]*(\d{1,2}):(\d{2})/ year = $3.to_i month = MONTHS.index($2) + 1 day = $1.to_i @dtstart = Time::local year, month, day, $4.to_i, $5.to_i, 0 @dtend = Time::local year, month, day, $4.to_i + 1, $5.to_i, 0 else raise "Invalid date: #{s.inspect}" end while @dtend < @dtstart # @dtend is in new day @dtend += 86400 end end end events = [] url = "https://www.azconni.de/termine/" doc = Nokogiri::HTML URI.open(url) doc.css(".termin").each do |termin| event_url = URI.join url, termin.css("header a").attr("href") event_doc = Nokogiri::HTML URI.open(event_url) termin = event_doc.css(".termin.full")[0] title = termin.css("header").text category = termin.css(".categories").text begin ev = Event::new ev.title = (category.empty? ? "" : "#{category}: ") + title ev.url = event_url ev.date = termin.css(".time").text events << ev rescue STDERR.puts "Omitting: #{$!}" # STDERR.puts $!.backtrace end end ical = ERB::new <<~EOF BEGIN:VCALENDAR VERSION:2.0 METHOD:PUBLISH X-WR-TIMEZONE;VALUE=TEXT:Europe/Berlin <% events.each do |ev| %> BEGIN:VEVENT SUMMARY:<%= ev.title %> DTSTART:<%= fmt_time ev.dtstart %> DTEND:<%= fmt_time ev.dtend %> UID:<%= ev.url %> URL:<%= ev.url %> LOCATION:<%= ev.location %> END:VEVENT <% end %> END:VCALENDAR EOF puts ical.result