rename accountopt.[ch] to purpleaccountoption.[ch]
[pidgin-git.git] / libpurple / protocols / gg / pubdir-prpl.c
blobe209cc26e9a7bf6d1f5f5b7ae4ce8dc1f7e911fd
1 /* purple
3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
7 * Rewritten from scratch during Google Summer of Code 2012
8 * by Tomek Wasilczyk (http://www.wasilczyk.pl).
10 * Previously implemented by:
11 * - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
12 * - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
13 * - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
30 #include "pubdir-prpl.h"
32 #include <debug.h>
33 #include <http.h>
34 #include <request.h>
36 #include "oauth/oauth-purple.h"
37 #include "xml.h"
38 #include "utils.h"
39 #include "status.h"
41 typedef struct
43 PurpleConnection *gc;
44 ggp_pubdir_request_cb cb;
45 void *user_data;
46 enum
48 GGP_PUBDIR_REQUEST_TYPE_INFO,
49 GGP_PUBDIR_REQUEST_TYPE_SEARCH,
50 } type;
51 union
53 struct
55 uin_t uin;
56 } user_info;
57 ggp_pubdir_search_form *search_form;
58 } params;
59 } ggp_pubdir_request;
61 void ggp_pubdir_request_free(ggp_pubdir_request *request);
62 void ggp_pubdir_record_free(ggp_pubdir_record *records, int count);
64 static void ggp_pubdir_get_info_got_token(PurpleConnection *gc,
65 const gchar *token, gpointer _request);
66 static void ggp_pubdir_got_data(PurpleHttpConnection *http_conn,
67 PurpleHttpResponse *response, gpointer user_data);
69 static void ggp_pubdir_get_info_protocol_got(PurpleConnection *gc,
70 int records_count, const ggp_pubdir_record *records, int next_offset,
71 void *_uin_p);
73 static void ggp_pubdir_request_buddy_alias_got(PurpleConnection *gc,
74 int records_count, const ggp_pubdir_record *records, int next_offset,
75 void *user_data);
77 /* Searching for buddies. */
79 #define GGP_PUBDIR_SEARCH_TITLE _("Gadu-Gadu Public Directory")
80 #define GGP_PUBDIR_SEARCH_PER_PAGE 20
82 struct _ggp_pubdir_search_form
84 gchar *nick, *city;
85 ggp_pubdir_gender gender;
86 int offset;
87 int limit;
89 void *display_handle;
92 void ggp_pubdir_search_form_free(ggp_pubdir_search_form *form);
93 ggp_pubdir_search_form * ggp_pubdir_search_form_clone(
94 const ggp_pubdir_search_form *form);
96 static void ggp_pubdir_search_request(PurpleConnection *gc,
97 PurpleRequestFields *fields);
98 static gchar * ggp_pubdir_search_make_query(const ggp_pubdir_search_form *form);
99 static void ggp_pubdir_search_execute(PurpleConnection *gc,
100 const ggp_pubdir_search_form *form,
101 ggp_pubdir_request_cb cb, void *user_data);
102 static void ggp_pubdir_search_got_token(PurpleConnection *gc,
103 const gchar *token, gpointer _request);
104 static void ggp_pubdir_search_results_display(PurpleConnection *gc,
105 int records_count, const ggp_pubdir_record *records, int next_offset,
106 void *user_data);
107 static void ggp_pubdir_search_results_close(gpointer _form);
108 static void ggp_pubdir_search_results_next(PurpleConnection *gc, GList *row,
109 gpointer _form);
110 static void ggp_pubdir_search_results_add(PurpleConnection *gc, GList *row,
111 gpointer _form);
112 static void ggp_pubdir_search_results_im(PurpleConnection *gc, GList *row,
113 gpointer _form);
114 static void ggp_pubdir_search_results_info(PurpleConnection *gc, GList *row,
115 gpointer _form);
116 static void ggp_pubdir_search_results_new(PurpleConnection *gc, GList *row,
117 gpointer _form);
119 /* Own profile. */
121 static void ggp_pubdir_set_info_dialog(PurpleConnection *gc, int records_count,
122 const ggp_pubdir_record *records, int next_offset, void *user_data);
123 static void ggp_pubdir_set_info_request(PurpleConnection *gc,
124 PurpleRequestFields *fields);
125 static void ggp_pubdir_set_info_got_token(PurpleConnection *gc,
126 const gchar *token, gpointer _record);
128 static void ggp_pubdir_set_info_got_response(PurpleHttpConnection *http_conn,
129 PurpleHttpResponse *response, gpointer user_data);
131 /******************************************************************************/
133 static const gchar *ggp_pubdir_provinces[] =
135 N_("Not specified"),
136 "dolnośląskie",
137 "kujawsko-pomorskie",
138 "lubelskie",
139 "lubuskie",
140 "łódzkie",
141 "małopolskie",
142 "mazowieckie",
143 "opolskie",
144 "podkarpackie",
145 "podlaskie",
146 "pomorskie",
147 "śląskie",
148 "świętokrzyskie",
149 "warmińsko-mazurskie",
150 "wielkopolskie",
151 "zachodniopomorskie",
154 static gsize ggp_pubdir_provinces_count = sizeof(ggp_pubdir_provinces)/sizeof(gchar*);
156 /******************************************************************************/
158 void ggp_pubdir_record_free(ggp_pubdir_record *records, int count)
160 int i;
161 for (i = 0; i < count; i++) {
162 g_free(records[i].label);
163 g_free(records[i].nickname);
164 g_free(records[i].first_name);
165 g_free(records[i].last_name);
166 g_free(records[i].city);
168 g_free(records);
171 void ggp_pubdir_request_free(ggp_pubdir_request *request)
173 if (request->type == GGP_PUBDIR_REQUEST_TYPE_SEARCH)
174 ggp_pubdir_search_form_free(request->params.search_form);
175 g_free(request);
178 void ggp_pubdir_get_info(PurpleConnection *gc, uin_t uin,
179 ggp_pubdir_request_cb cb, void *user_data)
181 ggp_pubdir_request *request = g_new0(ggp_pubdir_request, 1);
182 gchar *url;
184 request->type = GGP_PUBDIR_REQUEST_TYPE_INFO;
185 request->gc = gc;
186 request->cb = cb;
187 request->user_data = user_data;
188 request->params.user_info.uin = uin;
190 url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u", uin);
191 ggp_oauth_request(gc, ggp_pubdir_get_info_got_token, request,
192 "GET", url);
193 g_free(url);
196 static void ggp_pubdir_get_info_got_token(PurpleConnection *gc,
197 const gchar *token, gpointer _request)
199 PurpleHttpRequest *req;
200 ggp_pubdir_request *request = _request;
202 PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
204 if (!token) {
205 request->cb(gc, -1, NULL, 0, request->user_data);
206 ggp_pubdir_request_free(request);
207 return;
210 req = purple_http_request_new(NULL);
211 purple_http_request_set_url_printf(req,
212 "http://api.gadu-gadu.pl/users/%u",
213 request->params.user_info.uin);
214 purple_http_request_header_set(req, "Authorization", token);
215 purple_http_request(gc, req, ggp_pubdir_got_data, request);
216 purple_http_request_unref(req);
219 static void ggp_pubdir_got_data(PurpleHttpConnection *http_conn,
220 PurpleHttpResponse *response, gpointer _request)
222 ggp_pubdir_request *request = _request;
223 PurpleConnection *gc = request->gc;
224 gboolean succ = TRUE;
225 PurpleXmlNode *xml;
226 const gchar *xml_raw;
227 unsigned int status, next_offset;
228 int record_count, i;
229 ggp_pubdir_record *records;
231 xml_raw = purple_http_response_get_data(response, NULL);
233 if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
234 purple_debug_misc("gg", "ggp_pubdir_got_data: xml=[%s]\n",
235 xml_raw);
238 xml = purple_xmlnode_from_str(xml_raw, -1);
239 if (xml == NULL) {
240 purple_debug_error("gg", "ggp_pubdir_got_data: "
241 "invalid xml\n");
242 request->cb(gc, -1, NULL, 0, request->user_data);
243 ggp_pubdir_request_free(request);
244 return;
247 succ &= ggp_xml_get_uint(xml, "status", &status);
248 if (!ggp_xml_get_uint(xml, "nextOffset", &next_offset))
249 next_offset = 0;
250 xml = purple_xmlnode_get_child(xml, "users");
251 if (!succ || status != 0 || !xml) {
252 purple_debug_error("gg", "ggp_pubdir_got_data: "
253 "invalid reply\n");
254 request->cb(gc, -1, NULL, 0, request->user_data);
255 ggp_pubdir_request_free(request);
256 return;
259 record_count = ggp_xml_child_count(xml, "user");
260 records = g_new0(ggp_pubdir_record, record_count);
262 xml = purple_xmlnode_get_child(xml, "user");
263 i = 0;
264 while (xml) {
265 ggp_pubdir_record *record = &records[i++];
266 gchar *city = NULL, *birth_s = NULL;
267 unsigned int gender = 0;
268 const gchar *uin_s;
270 g_assert(i <= record_count);
272 record->uin = ggp_str_to_uin(purple_xmlnode_get_attrib(xml, "uin"));
273 if (record->uin == 0)
274 ggp_xml_get_uint(xml, "uin", &record->uin);
275 if (record->uin == 0)
276 purple_debug_error("gg", "ggp_pubdir_got_data:"
277 " invalid uin\n");
278 uin_s = ggp_uin_to_str(record->uin);
280 ggp_xml_get_string(xml, "label", &record->label);
281 ggp_xml_get_string(xml, "nick", &record->nickname);
282 ggp_xml_get_string(xml, "name", &record->first_name);
283 ggp_xml_get_string(xml, "surname", &record->last_name);
284 ggp_xml_get_string(xml, "city", &city);
285 ggp_xml_get_string(xml, "birth", &birth_s);
286 ggp_xml_get_uint(xml, "gender", &gender);
287 ggp_xml_get_uint(xml, "age", &record->age);
288 ggp_xml_get_uint(xml, "province", &record->province);
290 record->label = ggp_free_if_equal(record->label, uin_s);
291 record->label = ggp_free_if_equal(record->label, "");
292 record->nickname = ggp_free_if_equal(record->nickname, uin_s);
293 record->nickname = ggp_free_if_equal(record->nickname, "");
294 record->first_name = ggp_free_if_equal(record->first_name, "");
295 record->last_name = ggp_free_if_equal(record->last_name, "");
297 if (record->label) {}
298 else if (record->nickname)
299 record->label = g_strdup(record->nickname);
300 else if (record->first_name && record->last_name)
301 record->label = g_strdup_printf("%s %s",
302 record->first_name, record->last_name);
303 else if (record->first_name)
304 record->label = g_strdup(record->first_name);
305 else if (record->last_name)
306 record->label = g_strdup(record->last_name);
307 if (record->label)
308 g_strstrip(record->label);
309 if (record->nickname)
310 g_strstrip(record->nickname);
312 if (gender == 1)
313 record->gender = GGP_PUBDIR_GENDER_FEMALE;
314 else if (gender == 2)
315 record->gender = GGP_PUBDIR_GENDER_MALE;
316 else
317 record->gender = GGP_PUBDIR_GENDER_UNSPECIFIED;
319 if (city && city[0] != '\0')
320 record->city = g_strdup(city);
321 if (record->city)
322 g_strstrip(record->city);
323 if (!record->city) {
324 g_free(record->city);
325 record->city = NULL;
328 record->birth = ggp_date_from_iso8601(birth_s);
329 /*TODO: calculate age from birth */
331 if (purple_debug_is_verbose()) {
332 purple_debug_misc("gg", "ggp_pubdir_got_data: [uin:%d] "
333 "[label:%s] [nick:%s] [first name:%s] "
334 "[last name:%s] [city:%s] [gender:%d] [age:%d] "
335 "[birth:%lu]\n", record->uin, record->label,
336 record->nickname, record->first_name,
337 record->last_name, record->city, record->gender,
338 record->age, record->birth);
341 g_free(city);
343 xml = purple_xmlnode_get_next_twin(xml);
346 request->cb(gc, record_count, records, next_offset, request->user_data);
348 ggp_pubdir_request_free(request);
349 ggp_pubdir_record_free(records, record_count);
352 void ggp_pubdir_get_info_protocol(PurpleConnection *gc, const char *name)
354 uin_t uin = ggp_str_to_uin(name);
355 uin_t *uin_p = g_new0(uin_t, 1);
357 *uin_p = uin;
359 purple_debug_info("gg", "ggp_pubdir_get_info_protocol: %u\n", uin);
361 ggp_pubdir_get_info(gc, uin, ggp_pubdir_get_info_protocol_got, uin_p);
364 static void ggp_pubdir_get_info_protocol_got(PurpleConnection *gc,
365 int records_count, const ggp_pubdir_record *records, int next_offset,
366 void *_uin_p)
368 uin_t uin = *((uin_t*)_uin_p);
369 PurpleNotifyUserInfo *info = purple_notify_user_info_new();
370 const ggp_pubdir_record *record = &records[0];
371 PurpleBuddy *buddy;
373 g_free(_uin_p);
375 if (records_count < 1) {
376 purple_debug_error("gg", "ggp_pubdir_get_info_protocol_got: "
377 "couldn't get info for %u\n", uin);
378 purple_notify_user_info_add_pair_plaintext(info, NULL,
379 _("Cannot get user information"));
380 purple_notify_userinfo(gc, ggp_uin_to_str(uin), info,
381 NULL, NULL);
382 purple_notify_user_info_destroy(info);
383 return;
386 purple_debug_info("gg", "ggp_pubdir_get_info_protocol_got: %u\n", uin);
387 g_assert(uin == record->uin);
388 g_assert(records_count == 1);
390 buddy = purple_blist_find_buddy(purple_connection_get_account(gc),
391 ggp_uin_to_str(uin));
392 if (buddy) {
393 const char *alias;
394 PurpleStatus *status;
395 gchar *status_message;
397 alias = purple_buddy_get_alias_only(buddy);
398 if (alias)
399 purple_notify_user_info_add_pair_plaintext(info,
400 _("Alias"), alias);
402 status = purple_presence_get_active_status(
403 purple_buddy_get_presence(buddy));
404 ggp_status_from_purplestatus(status, &status_message);
405 purple_notify_user_info_add_pair_plaintext(info, _("Status"),
406 purple_status_get_name(status));
407 if (status_message) {
408 purple_notify_user_info_add_pair_plaintext(info,
409 _("Message"), status_message);
413 if (record->nickname) {
414 purple_notify_user_info_add_pair_plaintext(info,
415 _("Nickname"), record->nickname);
417 if (record->first_name) {
418 purple_notify_user_info_add_pair_plaintext(info,
419 _("First name"), record->first_name);
421 if (record->last_name) {
422 purple_notify_user_info_add_pair_plaintext(info,
423 _("Last name"), record->last_name);
425 if (record->gender != GGP_PUBDIR_GENDER_UNSPECIFIED) {
426 purple_notify_user_info_add_pair_plaintext(info, _("Gender"),
427 record->gender == GGP_PUBDIR_GENDER_FEMALE ?
428 _("Female") : _("Male"));
430 if (record->city) {
431 purple_notify_user_info_add_pair_plaintext(info, _("City"),
432 record->city);
434 if (record->birth) {
435 purple_notify_user_info_add_pair_plaintext(info, _("Birthday"),
436 ggp_date_strftime("%Y-%m-%d", record->birth));
437 } else if (record->age) {
438 gchar *age_s = g_strdup_printf("%d", record->age);
439 purple_notify_user_info_add_pair_plaintext(info, _("Age"),
440 age_s);
441 g_free(age_s);
444 purple_notify_userinfo(gc, ggp_uin_to_str(uin), info, NULL, NULL);
445 purple_notify_user_info_destroy(info);
448 void ggp_pubdir_request_buddy_alias(PurpleConnection *gc, PurpleBuddy *buddy)
450 uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
452 purple_debug_info("gg", "ggp_pubdir_request_buddy_alias: %u\n", uin);
454 ggp_pubdir_get_info(gc, uin, ggp_pubdir_request_buddy_alias_got, NULL);
457 static void ggp_pubdir_request_buddy_alias_got(PurpleConnection *gc,
458 int records_count, const ggp_pubdir_record *records, int next_offset,
459 void *user_data)
461 uin_t uin;
462 const gchar *alias;
464 if (records_count < 0) {
465 purple_debug_error("gg", "ggp_pubdir_request_buddy_alias_got: "
466 "couldn't get info for user\n");
467 return;
469 uin = records[0].uin;
471 alias = records[0].label;
472 if (!alias) {
473 purple_debug_info("gg", "ggp_pubdir_request_buddy_alias_got: "
474 "public alias for %u is not available\n", uin);
475 return;
478 purple_debug_info("gg", "ggp_pubdir_request_buddy_alias_got: "
479 "public alias for %u is \"%s\"\n", uin, alias);
481 purple_serv_got_alias(gc, ggp_uin_to_str(uin), alias);
484 /*******************************************************************************
485 * Searching for buddies.
486 ******************************************************************************/
488 void ggp_pubdir_search_form_free(ggp_pubdir_search_form *form)
490 g_free(form->nick);
491 g_free(form->city);
492 g_free(form);
495 ggp_pubdir_search_form * ggp_pubdir_search_form_clone(
496 const ggp_pubdir_search_form *form)
498 ggp_pubdir_search_form *dup = g_new(ggp_pubdir_search_form, 1);
500 dup->nick = g_strdup(form->nick);
501 dup->city = g_strdup(form->city);
502 dup->gender = form->gender;
503 dup->offset = form->offset;
504 dup->limit = form->limit;
506 dup->display_handle = form->display_handle;
508 return dup;
511 void ggp_pubdir_search(PurpleConnection *gc,
512 const ggp_pubdir_search_form *form)
514 PurpleRequestFields *fields;
515 PurpleRequestFieldGroup *group;
516 PurpleRequestField *field;
518 purple_debug_info("gg", "ggp_pubdir_search\n");
520 fields = purple_request_fields_new();
521 group = purple_request_field_group_new(NULL);
522 purple_request_fields_add_group(fields, group);
524 field = purple_request_field_string_new("name", _("Name"),
525 form ? form->nick : NULL, FALSE);
526 purple_request_field_group_add_field(group, field);
528 field = purple_request_field_string_new("city", _("City"),
529 form ? form->city : NULL, FALSE);
530 purple_request_field_group_add_field(group, field);
532 field = purple_request_field_choice_new("gender", _("Gender"),
533 form ? GINT_TO_POINTER(form->gender) : NULL);
534 purple_request_field_choice_add(field, _("Male or female"), NULL);
535 purple_request_field_choice_add(field, _("Male"),
536 GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
537 purple_request_field_choice_add(field, _("Female"),
538 GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
539 purple_request_field_group_add_field(group, field);
541 purple_request_fields(gc, _("Find buddies"), _("Find buddies"),
542 _("Please, enter your search criteria below"), fields,
543 _("OK"), G_CALLBACK(ggp_pubdir_search_request),
544 _("Cancel"), NULL,
545 purple_request_cpar_from_connection(gc), gc);
548 static void ggp_pubdir_search_request(PurpleConnection *gc,
549 PurpleRequestFields *fields)
551 ggp_pubdir_search_form *form = g_new0(ggp_pubdir_search_form, 1);
553 purple_debug_info("gg", "ggp_pubdir_search_request\n");
555 form->nick = g_strdup(purple_request_fields_get_string(fields, "name"));
556 form->city = g_strdup(purple_request_fields_get_string(fields, "city"));
557 form->gender = GPOINTER_TO_INT(purple_request_fields_get_choice(fields,
558 "gender"));
559 form->offset = 0;
560 form->limit = GGP_PUBDIR_SEARCH_PER_PAGE;
562 ggp_pubdir_search_execute(gc, form, ggp_pubdir_search_results_display,
563 form);
566 static gchar * ggp_pubdir_search_make_query(const ggp_pubdir_search_form *form)
568 gchar *nick, *city, *gender;
569 gchar *query;
571 if (form->nick && form->nick[0] != '\0') {
572 gchar *nick_e = g_uri_escape_string(form->nick, NULL, FALSE);
573 nick = g_strdup_printf("&nick=%s", nick_e);
574 g_free(nick_e);
575 } else
576 nick = g_strdup("");
578 if (form->city && form->city[0] != '\0') {
579 gchar *city_e = g_uri_escape_string(form->city, NULL, FALSE);
580 city = g_strdup_printf("&city=%s", city_e);
581 g_free(city_e);
582 } else
583 city = g_strdup("");
585 if (form->gender != GGP_PUBDIR_GENDER_UNSPECIFIED) {
586 gender = g_strdup_printf("&gender=%d",
587 form->gender == GGP_PUBDIR_GENDER_MALE ? 2 : 1);
588 } else
589 gender = g_strdup("");
591 query = g_strdup_printf("/users.xml?offset=%d&limit=%d%s%s%s",
592 form->offset, form->limit, nick, city, gender);
594 g_free(nick);
595 g_free(city);
596 g_free(gender);
598 return query;
601 static void ggp_pubdir_search_execute(PurpleConnection *gc,
602 const ggp_pubdir_search_form *form,
603 ggp_pubdir_request_cb cb, void *user_data)
605 ggp_pubdir_request *request = g_new0(ggp_pubdir_request, 1);
606 gchar *url;
607 ggp_pubdir_search_form *local_form = ggp_pubdir_search_form_clone(form);
608 gchar *query;
610 request->type = GGP_PUBDIR_REQUEST_TYPE_SEARCH;
611 request->gc = gc;
612 request->cb = cb;
613 request->user_data = user_data;
614 request->params.search_form = local_form;
616 query = ggp_pubdir_search_make_query(form);
617 purple_debug_misc("gg", "ggp_pubdir_search_execute: %s\n", query);
618 url = g_strdup_printf("http://api.gadu-gadu.pl%s", query);
619 ggp_oauth_request(gc, ggp_pubdir_search_got_token, request,
620 "GET", url);
621 g_free(query);
622 g_free(url);
625 static void ggp_pubdir_search_got_token(PurpleConnection *gc,
626 const gchar *token, gpointer _request)
628 PurpleHttpRequest *req;
629 ggp_pubdir_request *request = _request;
630 gchar *query;
632 PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
634 if (!token) {
635 request->cb(gc, -1, NULL, 0, request->user_data);
636 ggp_pubdir_request_free(request);
637 return;
640 purple_debug_misc("gg", "ggp_pubdir_search_got_token\n");
642 query = ggp_pubdir_search_make_query(request->params.search_form);
644 req = purple_http_request_new(NULL);
645 purple_http_request_set_url_printf(req, "http://api.gadu-gadu.pl%s", query);
646 purple_http_request_header_set(req, "Authorization", token);
647 purple_http_request(gc, req, ggp_pubdir_got_data, request);
648 purple_http_request_unref(req);
650 g_free(query);
654 static void ggp_pubdir_search_results_display(PurpleConnection *gc,
655 int records_count, const ggp_pubdir_record *records, int next_offset,
656 void *_form)
658 ggp_pubdir_search_form *form = _form;
659 PurpleNotifySearchResults *results;
660 int i;
662 purple_debug_info("gg", "ggp_pubdir_search_results_display: "
663 "got %d records (next offset: %d)\n",
664 records_count, next_offset);
666 if (records_count < 0 ||
667 (records_count == 0 && form->offset != 0))
669 purple_notify_error(gc, GGP_PUBDIR_SEARCH_TITLE,
670 _("Error while searching for buddies"), NULL,
671 purple_request_cpar_from_connection(gc));
672 ggp_pubdir_search_form_free(form);
673 return;
676 if (records_count == 0) {
677 purple_notify_info(gc, GGP_PUBDIR_SEARCH_TITLE,
678 _("No matching users found"),
679 _("There are no users matching your search criteria."),
680 purple_request_cpar_from_connection(gc));
681 ggp_pubdir_search_form_free(form);
682 return;
685 form->offset = next_offset;
687 results = purple_notify_searchresults_new();
689 purple_notify_searchresults_column_add(results,
690 purple_notify_searchresults_column_new(_("GG Number")));
691 purple_notify_searchresults_column_add(results,
692 purple_notify_searchresults_column_new(_("Name")));
693 purple_notify_searchresults_column_add(results,
694 purple_notify_searchresults_column_new(_("City")));
695 purple_notify_searchresults_column_add(results,
696 purple_notify_searchresults_column_new(_("Gender")));
697 purple_notify_searchresults_column_add(results,
698 purple_notify_searchresults_column_new(_("Age")));
700 for (i = 0; i < records_count; i++) {
701 GList *row = NULL;
702 const ggp_pubdir_record *record = &records[i];
703 gchar *gender = NULL, *age = NULL;
705 if (record->gender == GGP_PUBDIR_GENDER_MALE)
706 gender = g_strdup("male");
707 else if (record->gender == GGP_PUBDIR_GENDER_FEMALE)
708 gender = g_strdup("female");
710 if (record->age)
711 age = g_strdup_printf("%d", record->age);
713 row = g_list_append(row, g_strdup(ggp_uin_to_str(record->uin)));
714 row = g_list_append(row, g_strdup(record->label));
715 row = g_list_append(row, g_strdup(record->city));
716 row = g_list_append(row, gender);
717 row = g_list_append(row, age);
718 purple_notify_searchresults_row_add(results, row);
721 purple_notify_searchresults_button_add(results,
722 PURPLE_NOTIFY_BUTTON_ADD, ggp_pubdir_search_results_add);
723 purple_notify_searchresults_button_add(results,
724 PURPLE_NOTIFY_BUTTON_IM, ggp_pubdir_search_results_im);
725 purple_notify_searchresults_button_add(results,
726 PURPLE_NOTIFY_BUTTON_INFO, ggp_pubdir_search_results_info);
727 purple_notify_searchresults_button_add_labeled(results, _("New search"),
728 ggp_pubdir_search_results_new);
729 if (next_offset != 0)
730 purple_notify_searchresults_button_add(results,
731 PURPLE_NOTIFY_BUTTON_CONTINUE,
732 ggp_pubdir_search_results_next);
734 if (!form->display_handle)
735 form->display_handle = purple_notify_searchresults(gc,
736 GGP_PUBDIR_SEARCH_TITLE, _("Search results"), NULL,
737 results, ggp_pubdir_search_results_close, form);
738 else
739 purple_notify_searchresults_new_rows(gc, results,
740 form->display_handle);
741 g_assert(form->display_handle);
744 static void ggp_pubdir_search_results_close(gpointer _form)
746 ggp_pubdir_search_form *form = _form;
747 ggp_pubdir_search_form_free(form);
750 static void ggp_pubdir_search_results_next(PurpleConnection *gc, GList *row,
751 gpointer _form)
753 ggp_pubdir_search_form *form = _form;
754 ggp_pubdir_search_execute(gc, form, ggp_pubdir_search_results_display,
755 form);
758 static void ggp_pubdir_search_results_add(PurpleConnection *gc, GList *row,
759 gpointer _form)
761 purple_blist_request_add_buddy(purple_connection_get_account(gc),
762 g_list_nth_data(row, 0), NULL, g_list_nth_data(row, 1));
765 static void ggp_pubdir_search_results_im(PurpleConnection *gc, GList *row,
766 gpointer _form)
768 purple_conversation_present(PURPLE_CONVERSATION(purple_im_conversation_new(
769 purple_connection_get_account(gc), g_list_nth_data(row, 0))));
772 static void ggp_pubdir_search_results_info(PurpleConnection *gc, GList *row,
773 gpointer _form)
775 ggp_pubdir_get_info_protocol(gc, g_list_nth_data(row, 0));
778 static void ggp_pubdir_search_results_new(PurpleConnection *gc, GList *row,
779 gpointer _form)
781 ggp_pubdir_search_form *form = _form;
782 ggp_pubdir_search(gc, form);
785 /*******************************************************************************
786 * Own profile.
787 ******************************************************************************/
789 void ggp_pubdir_set_info(PurpleConnection *gc)
791 ggp_pubdir_get_info(gc, ggp_str_to_uin(purple_account_get_username(
792 purple_connection_get_account(gc))),
793 ggp_pubdir_set_info_dialog, NULL);
796 static void ggp_pubdir_set_info_dialog(PurpleConnection *gc, int records_count,
797 const ggp_pubdir_record *records, int next_offset, void *user_data)
799 PurpleRequestFields *fields;
800 PurpleRequestFieldGroup *group;
801 PurpleRequestField *field;
802 gsize i;
803 const ggp_pubdir_record *record;
805 purple_debug_info("gg", "ggp_pubdir_set_info_dialog (record: %d)\n",
806 records_count);
808 record = (records_count == 1 ? &records[0] : NULL);
810 fields = purple_request_fields_new();
811 group = purple_request_field_group_new(NULL);
812 purple_request_fields_add_group(fields, group);
814 field = purple_request_field_string_new("first_name", _("First name"),
815 record ? record->first_name : NULL, FALSE);
816 purple_request_field_group_add_field(group, field);
818 field = purple_request_field_string_new("last_name", _("Last name"),
819 record ? record->last_name : NULL, FALSE);
820 purple_request_field_group_add_field(group, field);
822 field = purple_request_field_choice_new("gender", _("Gender"),
823 record ? GINT_TO_POINTER(record->gender) :
824 GGP_PUBDIR_GENDER_UNSPECIFIED);
825 purple_request_field_set_required(field, TRUE);
826 purple_request_field_choice_add(field, _("Male"),
827 GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
828 purple_request_field_choice_add(field, _("Female"),
829 GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
830 purple_request_field_group_add_field(group, field);
832 field = purple_request_field_string_new("birth_date", _("Birth Day"),
833 (record && record->birth) ?
834 ggp_date_strftime("%Y-%m-%d", record->birth) : NULL, FALSE);
835 purple_request_field_set_required(field, TRUE);
836 purple_request_field_group_add_field(group, field);
838 field = purple_request_field_string_new("city", _("City"),
839 record ? record->city : NULL, FALSE);
840 purple_request_field_group_add_field(group, field);
842 /* Translators: This word is basically used to describe a Polish
843 province. Gadu-Gadu users outside of Poland might choose to enter some
844 equivalent value for themselves. For example, users in the USA might
845 use their state (e.g. New York). If there is an equivalent term for
846 your language, feel free to use it. Otherwise it's probably acceptable
847 to leave it changed or transliterate it into your alphabet. */
848 field = purple_request_field_choice_new("province", _("Voivodeship"), 0);
849 purple_request_field_group_add_field(group, field);
850 for (i = 0; i < ggp_pubdir_provinces_count; i++) {
851 purple_request_field_choice_add(field, ggp_pubdir_provinces[i],
852 GINT_TO_POINTER(i));
853 if (record && i == record->province) {
854 purple_request_field_choice_set_value(field, GINT_TO_POINTER(i));
855 purple_request_field_choice_set_default_value(field, GINT_TO_POINTER(i));
859 purple_request_fields(gc, _("Set User Info"), _("Set User Info"),
860 NULL, fields,
861 _("OK"), G_CALLBACK(ggp_pubdir_set_info_request),
862 _("Cancel"), NULL,
863 purple_request_cpar_from_connection(gc), gc);
866 static void ggp_pubdir_set_info_request(PurpleConnection *gc,
867 PurpleRequestFields *fields)
869 gchar *url;
870 uin_t uin = ggp_str_to_uin(purple_account_get_username(
871 purple_connection_get_account(gc)));
872 ggp_pubdir_record *record = g_new0(ggp_pubdir_record, 1);
873 gchar *birth_s;
875 purple_debug_info("gg", "ggp_pubdir_set_info_request\n");
877 record->uin = uin;
878 record->first_name = g_strdup(purple_request_fields_get_string(fields,
879 "first_name"));
880 record->last_name = g_strdup(purple_request_fields_get_string(fields,
881 "last_name"));
882 record->gender = GPOINTER_TO_INT(
883 purple_request_fields_get_choice(fields, "gender"));
884 record->city = g_strdup(purple_request_fields_get_string(fields,
885 "city"));
886 record->province = GPOINTER_TO_INT(
887 purple_request_fields_get_choice(fields, "province"));
889 birth_s = g_strdup_printf("%sT10:00:00+00:00",
890 purple_request_fields_get_string(fields, "birth_date"));
891 record->birth = ggp_date_from_iso8601(birth_s);
892 g_free(birth_s);
893 purple_debug_info("gg", "ggp_pubdir_set_info_request: birth [%lu][%s]\n",
894 record->birth, purple_request_fields_get_string(
895 fields, "birth_date"));
897 url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u.xml", uin);
898 ggp_oauth_request(gc, ggp_pubdir_set_info_got_token, record,
899 "PUT", url);
900 g_free(url);
903 static void ggp_pubdir_set_info_got_token(PurpleConnection *gc,
904 const gchar *token, gpointer _record)
906 PurpleHttpRequest *req;
907 ggp_pubdir_record *record = _record;
908 gchar *request_data;
909 gchar *name, *surname, *city;
910 uin_t uin = record->uin;
912 PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
914 if (!token) {
915 /* TODO: notify about failure */
916 ggp_pubdir_record_free(record, 1);
917 return;
920 name = g_uri_escape_string(record->first_name, NULL, FALSE);
921 surname = g_uri_escape_string(record->last_name, NULL, FALSE);
922 city = g_uri_escape_string(record->city, NULL, FALSE);
924 request_data = g_strdup_printf(
925 "name=%s&"
926 "surname=%s&"
927 "birth=%sT10:00:00%%2B00:00&"
928 "birth_priv=2&"
929 "gender=%d&"
930 "gender_priv=2&"
931 "city=%s&"
932 "province=%d",
933 name, surname,
934 ggp_date_strftime("%Y-%m-%d", record->birth),
935 record->gender,
936 city,
937 record->province);
939 if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
940 purple_debug_misc("gg", "ggp_pubdir_set_info_got_token: "
941 "query [%s]\n", request_data);
944 req = purple_http_request_new(NULL);
945 purple_http_request_set_method(req, "PUT");
946 purple_http_request_set_url_printf(req,
947 "http://api.gadu-gadu.pl/users/%u.xml", uin);
948 purple_http_request_header_set(req, "Authorization", token);
949 purple_http_request_header_set(req, "Content-Type",
950 "application/x-www-form-urlencoded");
951 purple_http_request_set_contents(req, request_data, -1);
952 purple_http_request(gc, req, ggp_pubdir_set_info_got_response, NULL);
953 purple_http_request_unref(req);
955 g_free(request_data);
956 ggp_pubdir_record_free(record, 1);
959 static void ggp_pubdir_set_info_got_response(PurpleHttpConnection *http_conn,
960 PurpleHttpResponse *response, gpointer user_data)
962 if (!purple_http_response_is_successful(response)) {
963 purple_debug_error("gg", "ggp_pubdir_set_info_got_response: "
964 "failed\n");
965 return;
968 purple_debug_info("gg", "ggp_pubdir_set_info_got_response: [%s]\n",
969 purple_http_response_get_data(response, NULL));
970 /* <result><status>0</status></result> */
972 /* TODO: notify about failure */