|
1 /* |
|
2 * geoloc.c -- Pep geographical location events |
|
3 * |
|
4 * Copyright (C) 2009-2012 Myhailo Danylenko <isbear@ukrpost.net> |
|
5 * |
|
6 * This program is free software; you can redistribute it and/or modify |
|
7 * it under the terms of the GNU General Public License as published by |
|
8 * the Free Software Foundation; either version 2 of the License, or (at |
|
9 * your option) any later version. |
|
10 * |
|
11 * This program is distributed in the hope that it will be useful, but |
|
12 * WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU General Public License |
|
17 * along with this program; if not, write to the Free Software |
|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
|
19 * USA |
|
20 */ |
|
21 |
|
22 #include <glib.h> |
|
23 #include <string.h> |
|
24 |
|
25 #include <mcabber/commands.h> |
|
26 #include <mcabber/compl.h> |
|
27 #include <mcabber/utils.h> |
|
28 #include <mcabber/screen.h> |
|
29 #include <mcabber/logprint.h> |
|
30 #include <mcabber/hbuf.h> // HBUF_PREFIX_* |
|
31 #include <mcabber/roster.h> |
|
32 #include <mcabber/hooks.h> |
|
33 #include <mcabber/modules.h> |
|
34 |
|
35 #include "geoloc.h" |
|
36 |
|
37 #include "config.h" |
|
38 |
|
39 // |
|
40 // module description |
|
41 // |
|
42 |
|
43 void geoloc_init (void); |
|
44 void geoloc_uninit (void); |
|
45 |
|
46 #define DESCRIPTION ( \ |
|
47 "PEP geoloc event handling\n" \ |
|
48 "Provides command /geoloc" ) |
|
49 |
|
50 static const gchar *deps[] = { "pep_geoloc", NULL }; |
|
51 |
|
52 static module_info_t info_geoloc_dev = { |
|
53 .branch = "dev", |
|
54 .api = 20, |
|
55 .version = PROJECT_VERSION, |
|
56 .description = DESCRIPTION, |
|
57 .requires = deps, |
|
58 .init = geoloc_init, |
|
59 .uninit = geoloc_uninit, |
|
60 .next = NULL, |
|
61 }; |
|
62 |
|
63 module_info_t info_geoloc = { |
|
64 .branch = "0.10.1", |
|
65 .api = 1, |
|
66 .version = PROJECT_VERSION, |
|
67 .description = DESCRIPTION, |
|
68 .requires = deps, |
|
69 .init = geoloc_init, |
|
70 .uninit = geoloc_uninit, |
|
71 .next = &info_geoloc_dev, |
|
72 }; |
|
73 |
|
74 // |
|
75 // globals |
|
76 // |
|
77 |
|
78 #ifdef MCABBER_API_HAVE_CMD_ID |
|
79 static gpointer geoloc_cmid = NULL; |
|
80 static gboolean geoloc_set_safe = FALSE; |
|
81 #endif |
|
82 |
|
83 static guint geoloc_cid = 0; |
|
84 static guint geoloc_hid_geolocin = 0; |
|
85 |
|
86 // |
|
87 // code |
|
88 // |
|
89 |
|
90 static void do_geoloc (char *arg) |
|
91 { |
|
92 geoloc_pair_t tags[] = { |
|
93 { "accuracy", NULL }, |
|
94 { "alt", NULL }, |
|
95 { "area", NULL }, |
|
96 { "bearing", NULL }, |
|
97 { "building", NULL }, |
|
98 { "country", NULL }, |
|
99 { "countrycode", NULL }, |
|
100 { "datum", NULL }, |
|
101 { "description", NULL }, |
|
102 { "error", NULL }, |
|
103 { "floor", NULL }, |
|
104 { "lat", NULL }, |
|
105 { "locality", NULL }, |
|
106 { "lon", NULL }, |
|
107 { "postalcode", NULL }, |
|
108 { "region", NULL }, |
|
109 { "room", NULL }, |
|
110 { "speed", NULL }, |
|
111 { "street", NULL }, |
|
112 { "text", NULL }, |
|
113 { "timestamp", NULL }, |
|
114 { "uri", NULL }, |
|
115 { NULL, NULL }, |
|
116 }; |
|
117 |
|
118 if (!*arg) { // request |
|
119 |
|
120 GError *error = NULL; |
|
121 |
|
122 geoloc_request ( CURRENT_JID, &error ); |
|
123 if ( error ) { |
|
124 scr_log_print ( LPRINT_NORMAL, "Error sending request: %s.", error -> message ); |
|
125 g_error_free ( error ); |
|
126 } else |
|
127 scr_log_print ( LPRINT_NORMAL, "Request sent." ); |
|
128 |
|
129 return; |
|
130 |
|
131 } else if (arg[0] != '-' || arg[1] != '\0') { // publish |
|
132 |
|
133 char *p; |
|
134 char *argstart = NULL; |
|
135 char *argstop = NULL; |
|
136 char *tagstart = NULL; |
|
137 char *tagstop = NULL; |
|
138 char *wordstart = arg; |
|
139 gboolean proceed = TRUE; |
|
140 |
|
141 // pt = p, ws = wordstart, ts = tagstart, tt = tagstop, as = argstart, at = arstop |
|
142 // tag=value value tag=value |
|
143 // w p |
|
144 // s t |
|
145 // t ta |
|
146 // s t* |
|
147 // tag=value value tag=value |
|
148 // t ta p |
|
149 // s t* t |
|
150 // t ta aw |
|
151 // s ts ts |
|
152 // tag=value value tag=value |
|
153 // t ta aw p |
|
154 // s ts ts t |
|
155 // t ta aw |
|
156 // s ts ts |
|
157 // tag=value value tag=value |
|
158 // t ta aw p |
|
159 // s ts ts t |
|
160 // t ta |
|
161 // s t* |
|
162 // tag=value value tag=value |
|
163 // t ta p |
|
164 // s t* t |
|
165 // t ta a |
|
166 // s ts t |
|
167 |
|
168 for (p = arg; proceed; ++p) { |
|
169 switch (*p) { |
|
170 case '=': |
|
171 if (tagstart && tagstop - tagstart) { |
|
172 // process previous args |
|
173 geoloc_pair_t *tag; |
|
174 |
|
175 for (tag = tags; tag->name; ++tag) { |
|
176 if (!strncmp (tag->name, tagstart, tagstop - tagstart)) { |
|
177 g_free ( (gchar *) tag -> value ); |
|
178 if (argstop - argstart) { |
|
179 *argstop = '\0'; |
|
180 tag->value = to_utf8 (argstart); |
|
181 } |
|
182 break; |
|
183 } |
|
184 } |
|
185 } |
|
186 |
|
187 tagstart = wordstart; |
|
188 tagstop = p; |
|
189 argstop = p+1; |
|
190 argstart = p+1; |
|
191 break; |
|
192 |
|
193 case '\0': |
|
194 argstop = p; |
|
195 |
|
196 if (tagstop - tagstart) { |
|
197 // process previous args |
|
198 geoloc_pair_t *tag; |
|
199 |
|
200 for (tag = tags; tag->name; ++tag) { |
|
201 if (!strncmp (tag->name, tagstart, tagstop - tagstart)) { |
|
202 g_free ( (gchar *) tag -> value ); |
|
203 if (argstop - argstart) |
|
204 tag->value = to_utf8 (argstart); |
|
205 break; |
|
206 } |
|
207 } |
|
208 } |
|
209 |
|
210 proceed = FALSE; |
|
211 break; |
|
212 |
|
213 case ' ': |
|
214 argstop = p; |
|
215 wordstart = p+1; |
|
216 break; |
|
217 |
|
218 default: |
|
219 break; |
|
220 } |
|
221 } |
|
222 } |
|
223 |
|
224 hk_run_handlers ( HOOK_GEOLOC_OUT, (hk_arg_t *) tags ); |
|
225 |
|
226 { |
|
227 geoloc_pair_t *tag; |
|
228 |
|
229 for ( tag = tags; tag -> name; ++ tag ) |
|
230 g_free ( (gchar *) tag -> value ); |
|
231 } |
|
232 } |
|
233 |
|
234 static guint geoloc_hgih ( const gchar *hid, hk_arg_t *args, gpointer userdata ) |
|
235 { |
|
236 GString *mesg = g_string_new (NULL); |
|
237 const gchar *from = NULL; |
|
238 |
|
239 { |
|
240 hk_arg_t *arg; |
|
241 for ( arg = args; arg -> name; ++ arg ) |
|
242 if ( arg -> value ) { |
|
243 if ( ! strcmp ( arg -> name, "from" ) ) |
|
244 from = arg -> value; |
|
245 else |
|
246 g_string_append_printf ( mesg, "\n - %s: %s", arg -> name, arg -> value); |
|
247 } |
|
248 } |
|
249 |
|
250 if (mesg->len) |
|
251 g_string_prepend (mesg, "Now located at:"); |
|
252 else |
|
253 g_string_overwrite (mesg, 0, "No location information."); |
|
254 |
|
255 { // print to buddy's buffer |
|
256 gchar *jid = jidtodisp (from); |
|
257 |
|
258 scr_write_incoming_message (jid, mesg->str, 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); // NO conversion from utf-8 |
|
259 |
|
260 g_free (jid); |
|
261 } |
|
262 |
|
263 g_string_free (mesg, TRUE); |
|
264 |
|
265 return HOOK_HANDLER_RESULT_ALLOW_MORE_HANDLERS; |
|
266 } |
|
267 |
|
268 void geoloc_init ( void ) |
|
269 { |
|
270 geoloc_cid = compl_new_category (); |
|
271 if (geoloc_cid) { |
|
272 compl_add_category_word (geoloc_cid, "accuracy="); |
|
273 compl_add_category_word (geoloc_cid, "alt="); |
|
274 compl_add_category_word (geoloc_cid, "area="); |
|
275 compl_add_category_word (geoloc_cid, "bearing="); |
|
276 compl_add_category_word (geoloc_cid, "building="); |
|
277 compl_add_category_word (geoloc_cid, "country="); |
|
278 compl_add_category_word (geoloc_cid, "countrycode="); |
|
279 compl_add_category_word (geoloc_cid, "datum="); |
|
280 compl_add_category_word (geoloc_cid, "description="); |
|
281 compl_add_category_word (geoloc_cid, "error="); |
|
282 compl_add_category_word (geoloc_cid, "floor="); |
|
283 compl_add_category_word (geoloc_cid, "lat="); |
|
284 compl_add_category_word (geoloc_cid, "locality="); |
|
285 compl_add_category_word (geoloc_cid, "lon="); |
|
286 compl_add_category_word (geoloc_cid, "postalcode="); |
|
287 compl_add_category_word (geoloc_cid, "region="); |
|
288 compl_add_category_word (geoloc_cid, "room="); |
|
289 compl_add_category_word (geoloc_cid, "speed="); |
|
290 compl_add_category_word (geoloc_cid, "street="); |
|
291 compl_add_category_word (geoloc_cid, "text="); |
|
292 compl_add_category_word (geoloc_cid, "timestamp="); |
|
293 compl_add_category_word (geoloc_cid, "uri="); |
|
294 } |
|
295 |
|
296 #ifndef MCABBER_API_HAVE_CMD_ID |
|
297 cmd_add ("geoloc", "", geoloc_cid, geoloc_cid, do_geoloc, NULL); |
|
298 #else |
|
299 geoloc_cmid = cmd_add ("geoloc", "", geoloc_cid, geoloc_cid, do_geoloc, NULL); |
|
300 geoloc_set_safe = cmd_set_safe ("geoloc", TRUE); |
|
301 #endif |
|
302 |
|
303 geoloc_hid_geolocin = hk_add_handler (geoloc_hgih, HOOK_GEOLOC_IN, G_PRIORITY_DEFAULT, NULL); |
|
304 } |
|
305 |
|
306 void geoloc_uninit ( void ) |
|
307 { |
|
308 hk_del_handler (HOOK_GEOLOC_IN, geoloc_hid_geolocin); |
|
309 |
|
310 #ifndef MCABBER_API_HAVE_CMD_ID |
|
311 cmd_del ("geoloc"); |
|
312 #else |
|
313 if (geoloc_cmid) |
|
314 cmd_del (geoloc_cmid); |
|
315 if (geoloc_set_safe) |
|
316 cmd_set_safe ("geoloc", FALSE); |
|
317 #endif |
|
318 |
|
319 if (geoloc_cid) |
|
320 compl_del_category (geoloc_cid); |
|
321 } |
|
322 |
|
323 /* vim: se ts=4 sw=4: */ |