|
|
tics2tsv - ics2txt - convert icalendar .ics file to plain text |
|
|
 |
git clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
|
--- |
|
|
|
tics2tsv (2949B) |
|
|
|
--- |
|
|
|
1 #!/usr/bin/awk -f |
|
|
|
2 |
|
|
|
3 function isleap(year) |
|
|
|
4 { |
|
|
|
5 return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0) |
|
|
|
6 } |
|
|
|
7 |
|
|
|
8 function mdays(mon, year) |
|
|
|
9 { |
|
|
|
10 return (mon == 2) ? (28 + isleap(year)) : (30 + (mon + (mon > 7)) % 2) |
|
|
|
11 } |
|
|
|
12 |
|
|
|
13 function timegm(tm, |
|
|
|
14 sec, mon, day) |
|
|
|
15 { |
|
|
|
16 sec = tm["sec"] + tm["min"] * 60 + tm["hour"] * 3600 |
|
|
|
17 |
|
|
|
18 day = tm["mday"] - 1 |
|
|
|
19 |
|
|
|
20 for (mon = tm["mon"] - 1; mon > 0; mon--) |
|
|
|
21 day = day + mdays(mon, tm["year"]) |
|
|
|
22 |
|
|
|
23 # constants: x * 365 + x / 400 - x / 100 + x / 4 |
|
|
|
24 day = day + int(tm["year"] / 400) * 146097 |
|
|
|
25 day = day + int(tm["year"] % 400 / 100) * 36524 |
|
|
|
26 day = day + int(tm["year"] % 100 / 4) * 1461 |
|
|
|
27 day = day + int(tm["year"] % 4 / 1) * 365 |
|
|
|
28 |
|
|
|
29 return sec + (day - 719527) * 86400 |
|
|
|
30 } |
|
|
|
31 |
|
|
|
32 function print_vevent(ev, fields, |
|
|
|
33 i) |
|
|
|
34 { |
|
|
|
35 for (i = 1; i in fields; i++) |
|
|
|
36 printf("%s%s", (i > 1 ? "\t" : ""), ev[fields[i]]) |
|
|
|
37 printf("\n") |
|
|
|
38 } |
|
|
|
39 |
|
|
|
40 function ical_parse_line(str, content, params, |
|
|
|
41 i, eq) |
|
|
|
42 { |
|
|
|
43 if ((i = index(str, ":")) == 0) |
|
|
|
44 return -1 |
|
|
|
45 content["value"] = substr(str, i + 1) |
|
|
|
46 str = substr(str, 1, i - 1) |
|
|
|
47 |
|
|
|
48 if ((i = index(str, ";")) == 0) { |
|
|
|
49 content["name"] = str |
|
|
|
50 return 0 |
|
|
|
51 } |
|
|
|
52 content["name"] = substr(str, 1, i - 1) |
|
|
|
53 str = substr(str, i + 1) |
|
|
|
54 |
|
|
|
55 while ((i = index(str, ";")) > 0) { |
|
|
|
56 if ((eq = index(str, "=")) == 0) |
|
|
|
57 return -1 |
|
|
|
58 param[substr(str, 1, eq - 1)] = substr(str, eq + 1, i - 1) |
|
|
|
59 str = substr(str, eq + 1) |
|
|
|
60 } |
|
|
|
61 if ((eq = index(str, "=")) == 0) |
|
|
|
62 return -1 |
|
|
|
63 params[substr(str, 1, eq - 1)] = substr(str, eq + 1) |
|
|
|
64 return 0 |
|
|
|
65 } |
|
|
|
66 |
|
|
|
67 function ical_set_tz(tzid) |
|
|
|
68 { |
|
|
|
69 gsub("'", "", tzid) |
|
|
|
70 cmd = "TZ='" tzid "' exec date +%z" |
|
|
|
71 cmd | getline tzid |
|
|
|
72 close(cmd) |
|
|
|
73 TZ = substr(tzid, 1, 1) substr(tzid, 2, 2)*3600 + substr(tzid, 4, 2)*60 |
|
|
|
74 } |
|
|
|
75 |
|
|
|
76 function ical_to_epoch(content, param, |
|
|
|
77 tz, cmd) |
|
|
|
78 { |
|
|
|
79 if (param["TZID"]) |
|
|
|
80 ical_set_tz(param["TZID"]) |
|
|
|
81 |
|
|
|
82 tm["year"] = substr(content["value"], 1, 4) |
|
|
|
83 tm["mon"] = substr(content["value"], 5, 2) |
|
|
|
84 tm["mday"] = substr(content["value"], 7, 2) |
|
|
|
85 tm["hour"] = substr(content["value"], 10, 2) |
|
|
|
86 tm["min"] = substr(content["value"], 12, 2) |
|
|
|
87 tm["sec"] = substr(content["value"], 14, 2) |
|
|
|
88 |
|
|
|
89 return timegm(tm) + TZ |
|
|
|
90 } |
|
|
|
91 |
|
|
|
92 BEGIN { |
|
|
|
93 split("DTSTART DTEND CATEGORIES LOCATION SUMMARY DESCRIPTION URL", |
|
|
|
94 FIELDS, " ") |
|
|
|
95 DT["DTSTART"] = DT["DTEND"] = DT["DUE"] = 1 |
|
|
|
96 |
|
|
|
97 # by default: "CATEGORIES" -> "cat", "LOCATION" -> "loc"... |
|
|
|
98 translate["DTSTART"] = "beg" |
|
|
|
99 translate["DTEND"] = "end" |
|
|
|
100 |
|
|
|
101 for (i = 1; i in FIELDS; i++) { |
|
|
|
102 if (!(s = translate[FIELDS[i]])) |
|
|
|
103 s = tolower(substr(FIELDS[i], 1, 3)) |
|
|
|
104 printf("%s%s", (i > 1 ? "\t" : ""), s) |
|
|
|
105 } |
|
|
|
106 printf("\n") |
|
|
|
107 |
|
|
|
108 FS = "[:;]" |
|
|
|
109 } |
|
|
|
110 |
|
|
|
111 { |
|
|
|
112 gsub("\r", "") |
|
|
|
113 gsub("\t", "\\\\t") |
|
|
|
114 } |
|
|
|
115 |
|
|
|
116 sub("^ ", "") { |
|
|
|
117 content["value"] = content["value"] $0 |
|
|
|
118 next |
|
|
|
119 } |
|
|
|
120 |
|
|
|
121 { |
|
|
|
122 delete content |
|
|
|
123 delete param |
|
|
|
124 |
|
|
|
125 if (ical_parse_line($0, content, params) < 0) |
|
|
|
126 next |
|
|
|
127 |
|
|
|
128 if (content["name"] == "TZID") { |
|
|
|
129 ical_set_tz(content["value"]) |
|
|
|
130 } else if (DT[content["name"]]) { |
|
|
|
131 vevent[content["name"]] = ical_to_epoch(content, params) |
|
|
|
132 } else { |
|
|
|
133 vevent[content["name"]] = content["value"] |
|
|
|
134 } |
|
|
|
135 } |
|
|
|
136 |
|
|
|
137 /^END:VEVENT/ { |
|
|
|
138 print_vevent(vevent, FIELDS) |
|
|
|
139 delete vevent |
|
|
|
140 next |
|
|
|
141 } |
|