add Teckids utility suite, by request from Natureshadow
[shellsnippets/shellsnippets.git] / mksh / teckids / nominatim
1 # -*- mode: sh -*-
2 #-
3 # Copyright © 2014, 2016
4 #       Dominik George <dominik.george@teckids.org>
5 # Copyright © 2014, 2015
6 #       mirabilos <thorsten.glaser@teckids.org>
7 #
8 # Provided that these terms and disclaimer and all copyright notices
9 # are retained or reproduced in an accompanying document, permission
10 # is granted to deal in this work without restriction, including un‐
11 # limited rights to use, publicly perform, distribute, sell, modify,
12 # merge, give away, or sublicence.
13 #
14 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
15 # the utmost extent permitted by applicable law, neither express nor
16 # implied; without malicious intent or gross negligence. In no event
17 # may a licensor, author or contributor be held liable for indirect,
18 # direct, other damage, loss, or other issues arising in any way out
19 # of dealing in the work, even if advised of the possibility of such
20 # damage or existence of a defect, except proven that it results out
21 # of said person’s immediate fault when using the work as intended.
22
23 # Teckids utility subcommand that pulls location data of a person from nominatim
24
25 teckids_sourcing_wrapper=1
26 . "$(dirname "$0")/teckids"
27
28 function parse_address {
29         local _a="$*"
30
31         # Check what format the address is in
32         if [[ $_a = +([!,])" "+([0-9])?([a-zA-Z])", "[0-9][0-9][0-9][0-9][0-9]" "+([!,]) ]]; then
33                 # Deutsche Anschrift in der Form „Musterstr. 17b, 12345 Musterstadt“
34                 str_nr=${_a%%, *}
35                 nr=${str_nr##* }
36                 str=${str_nr% *}
37                 str=${str/%str./straße}
38                 str=${str/%Str./Straße}
39                 plz_ort=${_a#*, }
40                 plz=${plz_ort%% *}
41                 ort=${plz_ort#* }
42                 land=Germany
43         elif [[ $_a = +([!,])" "+([0-9])?([a-zA-Z])", "[0-9][0-9][0-9][0-9]" "+([!,])", Switzerland" ]]; then
44                 # Schweizer Anschrift in der Form „Musterstr. 17b, 12345 Musterstadt, Switzerland“
45                 str_nr=${_a%%, *}
46                 nr=${str_nr##* }
47                 str=${str_nr% *}
48                 str=${str/%str./straße}
49                 str=${str/%Str./Straße}
50                 plz_ort=${_a#*, }
51                 plz_ort=${plz_ort%%, *}
52                 plz=${plz_ort%% *}
53                 ort=${plz_ort#* }
54                 land=${_a##*, }
55         elif [[ $_a = +([0-9])" "+([!,])", "+([!,])", "[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]" "[A-Z0-9][A-Z0-9][A-Z0-9]", Great Britain" ]]; then
56                 # Britische Anschrift in der Form „32 Whatever Road, Cambridge, CB24 8XL, Great Britain“
57                 str_nr=${_a%%, *}
58                 nr=${str_nr%% *}
59                 str=${str_nr#* }
60                 ort=${_a#*, }
61                 ort=${ort%%, *}
62                 plz=${_a#*, }
63                 plz=${plz#*, }
64                 plz=${plz%%, *}
65                 land=${_a##*, }
66         elif [[ $_a = +([!0-9])", "*([!0-9])", "*([!0-9]) ]]; then
67                 # Nur Ortsname mit Bundesland und ggf. Land
68                 ort=${_a%%, *}
69                 bl=${_a#*, }
70                 bl=${bl%, *}
71                 land=${_a##*, }
72                 : ${land:=Germany}
73         else
74                 return 1
75         fi
76
77         if [[ -n $str ]]; then
78                 print -r -- "street=$(uri_escape "$nr $str")&city=$(uri_escape "$ort")&postalcode=$(uri_escape "$plz")&country=$(uri_escape "$land")"
79         elif [[ -n $bl ]]; then
80                 print -r -- "city=$(uri_escape "$ort")&state=$(uri_escape "$bl")&country=$(uri_escape "$land")"
81         else
82                 print -r -- "city=$(uri_escape "$ort")&country=$(uri_escape "$land")"
83         fi
84         return 0
85 }
86
87 function addr2latlon {
88         if (( $# == 1 )); then
89                 q=$(parse_address "$1")
90         else
91                 q=$(parse_address "$1, $2, $3")
92         fi
93
94         if [[ $? = 0 ]]; then
95                 set -- $(wget --timeout=1 -t 3 -O- -U "Teckids addr2latlon converter" -q \
96                     "http://nominatim.openstreetmap.org/search?format=xml&limit=1&$q)" | \
97                     xmlstarlet pyx - | sort | sed -n '/^Al[ao][tn] /s///p')
98                 sleep 1
99                 [[ -n $1$2 ]] && print -r -- "$1,$2"
100         fi
101 }
102
103 (( export_only )) && return
104
105 if (( $# == 0 )); then
106         dn=$(cat "$TECKIDS_CACHE_DIR"/last_whois)
107 elif (( $# == 1 )); then
108         dn=$1
109 fi
110
111 asso_setldap_sasl users -- -b "$dn" -s base \
112         homePostalAddress l st c cn
113
114 teckids_loadk_users
115 for user_dn in "${asso_y[@]}"; do
116         homePostalAddress=$(asso_getv users "$user_dn" homePostalAddress 0)
117         l=$(asso_getv users "$user_dn" l 0)
118         st=$(asso_getv users "$user_dn" st 0)
119         c=$(asso_getv users "$user_dn" c 0)
120         cn=$(asso_getv users "$user_dn" cn 0)
121
122         r=
123         if [[ -n $homePostalAddress ]]; then
124                 r=$(addr2latlon "$homePostalAddress")
125         fi
126         if [[ -z $r && -n $l ]]; then
127                 r=$(addr2latlon "$l" "$st" "$c")
128         fi
129
130         print -r -- "$r"
131 done
132
133 exit 0