tmueller@0: #!/usr/bin/env lua tmueller@0: -- tmueller@0: -- $ bvvcal [bezirksname] [startdatum] [enddatum] tmueller@0: -- tmueller@0: -- bezirksname : Default "friedrichshain-kreuzberg" tmueller@1: -- startdatum : in deutscher Notation (z.B. 31.12.2010), Default: heute tmueller@0: -- enddatum : Default: startdatum tmueller@0: -- tmueller@0: -- Konvertiert den Berliner BVV-Sitzungskalender tmueller@0: -- ins iCalendar 2.0 (vCal) Format tmueller@0: -- tmueller@0: -- Benötigt: tmueller@0: -- - htmltidy : http://tidy.sourceforge.net/ tmueller@0: -- - wget : http://www.gnu.org/software/wget/ tmueller@0: -- - Lua 5.1.x : http://www.lua.org/ tmueller@0: -- - LuaExpat : http://www.keplerproject.org/luaexpat/ tmueller@0: -- tmueller@1: -- Revisionen: tmueller@1: -- - 0.2 : Uhrzeiten waren lokal, nicht GMT. Korrigiert. tmueller@1: -- - 0.1 : initial release tmueller@1: -- tmueller@1: -- Autor: Timm S. Müller tmueller@1: -- tmueller@0: tmueller@0: local lxp = require "lxp" tmueller@0: tmueller@0: local district = arg[1] or "friedrichshain-kreuzberg" tmueller@0: local startdate = arg[2] or os.date("%d.%m.%Y") tmueller@0: local enddate = arg[3] or startdate tmueller@0: local uid_uri = district .. ".bvv.berlin.piratenpartei.de" tmueller@0: tmueller@0: ----- --- --- -- - - - - - tmueller@0: tmueller@1: -- Encoding ist laut RFC 2445 UTF-8, dies ist ein Zugeständnis tmueller@1: -- an Kalendertools, die das nicht mitbekommen haben: tmueller@1: tmueller@1: local umlconv = { tmueller@1: ["ä"] = "ae", ["Ä"] = "Ae", tmueller@1: ["ö"] = "oe", ["Ö"] = "Oe", tmueller@1: ["ü"] = "ue", ["Ü"] = "Ue", tmueller@1: ["ß"] = "ss" tmueller@1: } tmueller@1: tmueller@2: local function local2gmt(y, m, d, hour, min) tmueller@2: return os.date("%s", os.time { day=d, month=m, year=y, hour=hour, min=min }) tmueller@2: end tmueller@2: tmueller@2: tmueller@0: local state = "waitcontent" tmueller@0: local record, cell, result = { }, { }, { } tmueller@0: local lnr = 1 tmueller@0: local parser = lxp.new { tmueller@0: StartElement = function(parser, tagname, attr) tmueller@0: if state == "waitcontent" then tmueller@0: if tagname == "div" and attr.id == "allrisContent" then tmueller@0: state = "waittab" tmueller@0: end tmueller@0: elseif state == "waittab" then tmueller@0: if tagname == "table" and attr.class == "tl1" then tmueller@0: state = "waitrow" tmueller@0: end tmueller@0: elseif state == "waitrow" then tmueller@0: if tagname == "tr" then tmueller@0: state = "waitcell" tmueller@0: end tmueller@0: end tmueller@0: end, tmueller@0: EndElement = function(parser, tagname) tmueller@0: if state == "waitrow" or state == "waittable" then tmueller@0: if tagname == "table" then tmueller@0: state = "end" tmueller@0: end tmueller@0: elseif state == "waitcell" then tmueller@0: if tagname == "tr" then tmueller@0: local day = table.remove(record, 1) tmueller@0: local sdate = table.remove(record, 1) tmueller@0: local d, m, y = (sdate or ""):match("^%s*(%d+)%.(%d+)%.(%d+)") tmueller@0: local time = table.remove(record, 1) tmueller@0: if d and m and y and time then tmueller@0: local sH, sM, eH, eM = time:match("^%s*(%d+):(%d+)%s*%-%s*(%d+):(%d+)") tmueller@0: if not sH then tmueller@0: sH, sM = time:match("^%s*(%d+):(%d+)") tmueller@0: end tmueller@0: if sH then tmueller@1: -- convert dates to GMT tmueller@2: local startdate = local2gmt(y, m, d, sH, sM) tmueller@2: local enddate = eH and local2gmt(y, m, d, eH, eM) tmueller@0: local what = table.concat(record, " "):match("^%s*(.-)%s*$") tmueller@1: what = what:gsub("([\128-\255].)", umlconv) tmueller@1: table.insert(result, { startdate, enddate, what }) tmueller@0: end tmueller@0: end tmueller@0: state = "waitrow" tmueller@0: record = { } tmueller@0: elseif tagname == "td" then tmueller@0: table.insert(record, table.concat(cell)) tmueller@0: cell = { } tmueller@0: end tmueller@0: end tmueller@0: end, tmueller@0: CharacterData = function(parser, s) tmueller@0: if state == "waitcell" then tmueller@0: table.insert(cell, s) tmueller@0: end tmueller@0: end tmueller@0: } tmueller@0: tmueller@0: parser:setencoding("ISO-8859-1") tmueller@0: tmueller@0: ----- --- --- -- - - - - - tmueller@0: tmueller@0: local cmd = ("wget --quiet --post-data 'kaldatvon=%s&kaldatbis=%s' 'http://www.berlin.de/ba-%s/bvv-online/si010.asp' -O - | tidy -latin1 -asxml -i -w 0 2>/dev/null -q"):format(startdate, enddate, district) tmueller@0: -- print(cmd) tmueller@0: local f = io.popen(cmd) tmueller@0: for line in f:lines() do tmueller@0: -- print(lnr .. " : " .. line) tmueller@0: parser:parse(line) tmueller@0: lnr = lnr + 1 tmueller@0: end tmueller@0: tmueller@0: ----- --- --- -- - - - - - tmueller@0: tmueller@0: print "BEGIN:VCALENDAR" tmueller@0: print "PRODID:BVV2CAL" tmueller@0: print "VERSION:2.0" tmueller@0: print "" tmueller@0: for i = 1, #result do tmueller@0: local r = result[i] tmueller@0: print "BEGIN:VEVENT" tmueller@2: local startdate = os.date("!%Y%m%dT%H%M", r[1]) tmueller@1: print("UID:" .. startdate .. "." .. uid_uri) tmueller@1: print("SUMMARY:" .. r[3]) tmueller@1: print("DTSTART:" .. startdate .. "00Z") tmueller@1: if r[2] then tmueller@2: local enddate = r[2] and os.date("!%Y%m%dT%H%M", r[2]) tmueller@1: print("DTEND:" .. enddate .. "00Z") tmueller@0: end tmueller@0: print "END:VEVENT" tmueller@0: print "" tmueller@0: end tmueller@0: print "END:VCALENDAR"