tmueller@0
|
1 |
#!/usr/bin/env lua
|
tmueller@0
|
2 |
--
|
tmueller@0
|
3 |
-- $ bvvcal [bezirksname] [startdatum] [enddatum]
|
tmueller@0
|
4 |
--
|
tmueller@0
|
5 |
-- bezirksname : Default "friedrichshain-kreuzberg"
|
tmueller@1
|
6 |
-- startdatum : in deutscher Notation (z.B. 31.12.2010), Default: heute
|
tmueller@0
|
7 |
-- enddatum : Default: startdatum
|
tmueller@0
|
8 |
--
|
tmueller@0
|
9 |
-- Konvertiert den Berliner BVV-Sitzungskalender
|
tmueller@0
|
10 |
-- ins iCalendar 2.0 (vCal) Format
|
tmueller@0
|
11 |
--
|
tmueller@0
|
12 |
-- Benötigt:
|
tmueller@0
|
13 |
-- - htmltidy : http://tidy.sourceforge.net/
|
tmueller@0
|
14 |
-- - wget : http://www.gnu.org/software/wget/
|
tmueller@0
|
15 |
-- - Lua 5.1.x : http://www.lua.org/
|
tmueller@0
|
16 |
-- - LuaExpat : http://www.keplerproject.org/luaexpat/
|
tmueller@0
|
17 |
--
|
tmueller@1
|
18 |
-- Revisionen:
|
tmueller@1
|
19 |
-- - 0.2 : Uhrzeiten waren lokal, nicht GMT. Korrigiert.
|
tmueller@1
|
20 |
-- - 0.1 : initial release
|
tmueller@1
|
21 |
--
|
tmueller@1
|
22 |
-- Autor: Timm S. Müller <timm-pirat@schulze-mueller.de>
|
tmueller@1
|
23 |
--
|
tmueller@0
|
24 |
|
tmueller@0
|
25 |
local lxp = require "lxp"
|
tmueller@0
|
26 |
|
tmueller@0
|
27 |
local district = arg[1] or "friedrichshain-kreuzberg"
|
tmueller@0
|
28 |
local startdate = arg[2] or os.date("%d.%m.%Y")
|
tmueller@0
|
29 |
local enddate = arg[3] or startdate
|
tmueller@0
|
30 |
local uid_uri = district .. ".bvv.berlin.piratenpartei.de"
|
tmueller@0
|
31 |
|
tmueller@0
|
32 |
----- --- --- -- - - - - -
|
tmueller@0
|
33 |
|
tmueller@1
|
34 |
-- Encoding ist laut RFC 2445 UTF-8, dies ist ein Zugeständnis
|
tmueller@1
|
35 |
-- an Kalendertools, die das nicht mitbekommen haben:
|
tmueller@1
|
36 |
|
tmueller@1
|
37 |
local umlconv = {
|
tmueller@1
|
38 |
["ä"] = "ae", ["Ä"] = "Ae",
|
tmueller@1
|
39 |
["ö"] = "oe", ["Ö"] = "Oe",
|
tmueller@1
|
40 |
["ü"] = "ue", ["Ü"] = "Ue",
|
tmueller@1
|
41 |
["ß"] = "ss"
|
tmueller@1
|
42 |
}
|
tmueller@1
|
43 |
|
tmueller@0
|
44 |
local state = "waitcontent"
|
tmueller@0
|
45 |
local record, cell, result = { }, { }, { }
|
tmueller@0
|
46 |
local lnr = 1
|
tmueller@0
|
47 |
local parser = lxp.new {
|
tmueller@0
|
48 |
StartElement = function(parser, tagname, attr)
|
tmueller@0
|
49 |
if state == "waitcontent" then
|
tmueller@0
|
50 |
if tagname == "div" and attr.id == "allrisContent" then
|
tmueller@0
|
51 |
state = "waittab"
|
tmueller@0
|
52 |
end
|
tmueller@0
|
53 |
elseif state == "waittab" then
|
tmueller@0
|
54 |
if tagname == "table" and attr.class == "tl1" then
|
tmueller@0
|
55 |
state = "waitrow"
|
tmueller@0
|
56 |
end
|
tmueller@0
|
57 |
elseif state == "waitrow" then
|
tmueller@0
|
58 |
if tagname == "tr" then
|
tmueller@0
|
59 |
state = "waitcell"
|
tmueller@0
|
60 |
end
|
tmueller@0
|
61 |
end
|
tmueller@0
|
62 |
end,
|
tmueller@0
|
63 |
EndElement = function(parser, tagname)
|
tmueller@0
|
64 |
if state == "waitrow" or state == "waittable" then
|
tmueller@0
|
65 |
if tagname == "table" then
|
tmueller@0
|
66 |
state = "end"
|
tmueller@0
|
67 |
end
|
tmueller@0
|
68 |
elseif state == "waitcell" then
|
tmueller@0
|
69 |
if tagname == "tr" then
|
tmueller@0
|
70 |
local day = table.remove(record, 1)
|
tmueller@0
|
71 |
local sdate = table.remove(record, 1)
|
tmueller@0
|
72 |
local d, m, y = (sdate or ""):match("^%s*(%d+)%.(%d+)%.(%d+)")
|
tmueller@0
|
73 |
local time = table.remove(record, 1)
|
tmueller@0
|
74 |
if d and m and y and time then
|
tmueller@0
|
75 |
local sH, sM, eH, eM = time:match("^%s*(%d+):(%d+)%s*%-%s*(%d+):(%d+)")
|
tmueller@0
|
76 |
if not sH then
|
tmueller@0
|
77 |
sH, sM = time:match("^%s*(%d+):(%d+)")
|
tmueller@0
|
78 |
end
|
tmueller@0
|
79 |
if sH then
|
tmueller@1
|
80 |
-- convert dates to GMT
|
tmueller@1
|
81 |
local startdate = os.date("!%s", os.time { day=d, month=m, year=y, hour=sH, min=sM })
|
tmueller@1
|
82 |
local enddate = eH and os.date("!%s", os.time { day=d, month=m, year=y, hour=eH, min=eM })
|
tmueller@0
|
83 |
local what = table.concat(record, " "):match("^%s*(.-)%s*$")
|
tmueller@1
|
84 |
what = what:gsub("([\128-\255].)", umlconv)
|
tmueller@1
|
85 |
table.insert(result, { startdate, enddate, what })
|
tmueller@0
|
86 |
end
|
tmueller@0
|
87 |
end
|
tmueller@0
|
88 |
state = "waitrow"
|
tmueller@0
|
89 |
record = { }
|
tmueller@0
|
90 |
elseif tagname == "td" then
|
tmueller@0
|
91 |
table.insert(record, table.concat(cell))
|
tmueller@0
|
92 |
cell = { }
|
tmueller@0
|
93 |
end
|
tmueller@0
|
94 |
end
|
tmueller@0
|
95 |
end,
|
tmueller@0
|
96 |
CharacterData = function(parser, s)
|
tmueller@0
|
97 |
if state == "waitcell" then
|
tmueller@0
|
98 |
table.insert(cell, s)
|
tmueller@0
|
99 |
end
|
tmueller@0
|
100 |
end
|
tmueller@0
|
101 |
}
|
tmueller@0
|
102 |
|
tmueller@0
|
103 |
parser:setencoding("ISO-8859-1")
|
tmueller@0
|
104 |
|
tmueller@0
|
105 |
----- --- --- -- - - - - -
|
tmueller@0
|
106 |
|
tmueller@0
|
107 |
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
|
108 |
-- print(cmd)
|
tmueller@0
|
109 |
local f = io.popen(cmd)
|
tmueller@0
|
110 |
for line in f:lines() do
|
tmueller@0
|
111 |
-- print(lnr .. " : " .. line)
|
tmueller@0
|
112 |
parser:parse(line)
|
tmueller@0
|
113 |
lnr = lnr + 1
|
tmueller@0
|
114 |
end
|
tmueller@0
|
115 |
|
tmueller@0
|
116 |
----- --- --- -- - - - - -
|
tmueller@0
|
117 |
|
tmueller@0
|
118 |
print "BEGIN:VCALENDAR"
|
tmueller@0
|
119 |
print "PRODID:BVV2CAL"
|
tmueller@0
|
120 |
print "VERSION:2.0"
|
tmueller@0
|
121 |
print ""
|
tmueller@0
|
122 |
for i = 1, #result do
|
tmueller@0
|
123 |
local r = result[i]
|
tmueller@0
|
124 |
print "BEGIN:VEVENT"
|
tmueller@1
|
125 |
local startdate = os.date("%Y%m%dT%H%M", r[1])
|
tmueller@1
|
126 |
print("UID:" .. startdate .. "." .. uid_uri)
|
tmueller@1
|
127 |
print("SUMMARY:" .. r[3])
|
tmueller@1
|
128 |
print("DTSTART:" .. startdate .. "00Z")
|
tmueller@1
|
129 |
if r[2] then
|
tmueller@1
|
130 |
local enddate = r[2] and os.date("%Y%m%dT%H%M", r[2])
|
tmueller@1
|
131 |
print("DTEND:" .. enddate .. "00Z")
|
tmueller@0
|
132 |
end
|
tmueller@0
|
133 |
print "END:VEVENT"
|
tmueller@0
|
134 |
print ""
|
tmueller@0
|
135 |
end
|
tmueller@0
|
136 |
print "END:VCALENDAR"
|