Replace functions which called once with their bodies
[pidgin-git.git] / libpurple / protocols / gg / pubdir-prpl.c
blob5243aaa39b6b9f58f31c79e5c564f52088334966
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"
31 #include "gg.h"
33 #include <debug.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 /* Searching for buddies. */
63 #define GGP_PUBDIR_SEARCH_TITLE _("Gadu-Gadu Public Directory")
64 #define GGP_PUBDIR_SEARCH_PER_PAGE 20
66 struct _ggp_pubdir_search_form
68 gchar *nick, *city;
69 ggp_pubdir_gender gender;
70 int offset;
71 int limit;
73 void *display_handle;
76 /* For ggp_pubdir_search_results_next, which is called by this. */
77 static void ggp_pubdir_search_results_display(PurpleConnection *gc,
78 int records_count, const ggp_pubdir_record *records, int next_offset,
79 void *user_data);
81 /******************************************************************************/
83 static const gchar *ggp_pubdir_provinces[] =
85 N_("Not specified"),
86 "dolnośląskie",
87 "kujawsko-pomorskie",
88 "lubelskie",
89 "lubuskie",
90 "łódzkie",
91 "małopolskie",
92 "mazowieckie",
93 "opolskie",
94 "podkarpackie",
95 "podlaskie",
96 "pomorskie",
97 "śląskie",
98 "świętokrzyskie",
99 "warmińsko-mazurskie",
100 "wielkopolskie",
101 "zachodniopomorskie",
104 static gsize ggp_pubdir_provinces_count = sizeof(ggp_pubdir_provinces)/sizeof(gchar*);
106 /******************************************************************************/
108 static void
109 ggp_pubdir_record_free(ggp_pubdir_record *records, int count)
111 int i;
112 for (i = 0; i < count; i++) {
113 g_free(records[i].label);
114 g_free(records[i].nickname);
115 g_free(records[i].first_name);
116 g_free(records[i].last_name);
117 g_free(records[i].city);
119 g_free(records);
122 static void
123 ggp_pubdir_search_form_free(ggp_pubdir_search_form *form)
125 g_free(form->nick);
126 g_free(form->city);
127 g_free(form);
130 static void
131 ggp_pubdir_request_free(ggp_pubdir_request *request)
133 if (request->type == GGP_PUBDIR_REQUEST_TYPE_SEARCH)
134 ggp_pubdir_search_form_free(request->params.search_form);
135 g_free(request);
138 static void
139 ggp_pubdir_got_data(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg,
140 gpointer _request)
142 ggp_pubdir_request *request = _request;
143 PurpleConnection *gc = request->gc;
144 gboolean succ = TRUE;
145 PurpleXmlNode *xml;
146 const gchar *xml_raw;
147 unsigned int status, next_offset;
148 int record_count, i;
149 ggp_pubdir_record *records;
151 xml_raw = msg->response_body->data;
153 if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
154 purple_debug_misc("gg", "ggp_pubdir_got_data: xml=[%s]\n",
155 xml_raw);
158 xml = purple_xmlnode_from_str(xml_raw, -1);
159 if (xml == NULL) {
160 purple_debug_error("gg", "ggp_pubdir_got_data: "
161 "invalid xml\n");
162 request->cb(gc, -1, NULL, 0, request->user_data);
163 ggp_pubdir_request_free(request);
164 return;
167 succ &= ggp_xml_get_uint(xml, "status", &status);
168 if (!ggp_xml_get_uint(xml, "nextOffset", &next_offset))
169 next_offset = 0;
170 xml = purple_xmlnode_get_child(xml, "users");
171 if (!succ || status != 0 || !xml) {
172 purple_debug_error("gg", "ggp_pubdir_got_data: "
173 "invalid reply\n");
174 request->cb(gc, -1, NULL, 0, request->user_data);
175 ggp_pubdir_request_free(request);
176 return;
179 record_count = ggp_xml_child_count(xml, "user");
180 records = g_new0(ggp_pubdir_record, record_count);
182 xml = purple_xmlnode_get_child(xml, "user");
183 i = 0;
184 while (xml) {
185 ggp_pubdir_record *record = &records[i++];
186 gchar *city = NULL, *birth_s = NULL;
187 unsigned int gender = 0;
188 const gchar *uin_s;
190 g_assert(i <= record_count);
192 record->uin = ggp_str_to_uin(purple_xmlnode_get_attrib(xml, "uin"));
193 if (record->uin == 0)
194 ggp_xml_get_uint(xml, "uin", &record->uin);
195 if (record->uin == 0)
196 purple_debug_error("gg", "ggp_pubdir_got_data:"
197 " invalid uin\n");
198 uin_s = ggp_uin_to_str(record->uin);
200 ggp_xml_get_string(xml, "label", &record->label);
201 ggp_xml_get_string(xml, "nick", &record->nickname);
202 ggp_xml_get_string(xml, "name", &record->first_name);
203 ggp_xml_get_string(xml, "surname", &record->last_name);
204 ggp_xml_get_string(xml, "city", &city);
205 ggp_xml_get_string(xml, "birth", &birth_s);
206 ggp_xml_get_uint(xml, "gender", &gender);
207 ggp_xml_get_uint(xml, "age", &record->age);
208 ggp_xml_get_uint(xml, "province", &record->province);
210 record->label = ggp_free_if_equal(record->label, uin_s);
211 record->label = ggp_free_if_equal(record->label, "");
212 record->nickname = ggp_free_if_equal(record->nickname, uin_s);
213 record->nickname = ggp_free_if_equal(record->nickname, "");
214 record->first_name = ggp_free_if_equal(record->first_name, "");
215 record->last_name = ggp_free_if_equal(record->last_name, "");
217 if (record->label) {}
218 else if (record->nickname)
219 record->label = g_strdup(record->nickname);
220 else if (record->first_name && record->last_name)
221 record->label = g_strdup_printf("%s %s",
222 record->first_name, record->last_name);
223 else if (record->first_name)
224 record->label = g_strdup(record->first_name);
225 else if (record->last_name)
226 record->label = g_strdup(record->last_name);
227 if (record->label)
228 g_strstrip(record->label);
229 if (record->nickname)
230 g_strstrip(record->nickname);
232 if (gender == 1)
233 record->gender = GGP_PUBDIR_GENDER_FEMALE;
234 else if (gender == 2)
235 record->gender = GGP_PUBDIR_GENDER_MALE;
236 else
237 record->gender = GGP_PUBDIR_GENDER_UNSPECIFIED;
239 if (city && city[0] != '\0')
240 record->city = g_strdup(city);
241 if (record->city)
242 g_strstrip(record->city);
243 if (!record->city) {
244 g_free(record->city);
245 record->city = NULL;
248 record->birth = ggp_date_from_iso8601(birth_s);
249 /*TODO: calculate age from birth */
251 if (purple_debug_is_verbose()) {
252 purple_debug_misc("gg", "ggp_pubdir_got_data: [uin:%d] "
253 "[label:%s] [nick:%s] [first name:%s] "
254 "[last name:%s] [city:%s] [gender:%d] [age:%d] "
255 "[birth:%lu]\n", record->uin, record->label,
256 record->nickname, record->first_name,
257 record->last_name, record->city, record->gender,
258 record->age, record->birth);
261 g_free(city);
263 xml = purple_xmlnode_get_next_twin(xml);
266 request->cb(gc, record_count, records, next_offset, request->user_data);
268 ggp_pubdir_request_free(request);
269 ggp_pubdir_record_free(records, record_count);
272 static void
273 ggp_pubdir_get_info_got_token(PurpleConnection *gc, const gchar *token,
274 gpointer _request)
276 GGPInfo *info = NULL;
277 gchar *url;
278 SoupMessage *msg;
279 ggp_pubdir_request *request = _request;
281 PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
283 if (!token) {
284 request->cb(gc, -1, NULL, 0, request->user_data);
285 ggp_pubdir_request_free(request);
286 return;
289 info = purple_connection_get_protocol_data(gc);
291 url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u",
292 request->params.user_info.uin);
293 msg = soup_message_new("GET", url);
294 g_free(url);
295 soup_message_headers_replace(msg->request_headers, "Authorization", token);
296 soup_session_queue_message(info->http, msg, ggp_pubdir_got_data, request);
299 void
300 ggp_pubdir_get_info(PurpleConnection *gc, uin_t uin, ggp_pubdir_request_cb cb,
301 void *user_data)
303 ggp_pubdir_request *request = g_new0(ggp_pubdir_request, 1);
304 gchar *url;
306 request->type = GGP_PUBDIR_REQUEST_TYPE_INFO;
307 request->gc = gc;
308 request->cb = cb;
309 request->user_data = user_data;
310 request->params.user_info.uin = uin;
312 url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u", uin);
313 ggp_oauth_request(gc, ggp_pubdir_get_info_got_token, request, "GET", url);
314 g_free(url);
317 static void ggp_pubdir_get_info_protocol_got(PurpleConnection *gc,
318 int records_count, const ggp_pubdir_record *records, int next_offset,
319 void *_uin_p)
321 uin_t uin = *((uin_t*)_uin_p);
322 PurpleNotifyUserInfo *info = purple_notify_user_info_new();
323 const ggp_pubdir_record *record = &records[0];
324 PurpleBuddy *buddy;
326 g_free(_uin_p);
328 if (records_count < 1) {
329 purple_debug_error("gg", "ggp_pubdir_get_info_protocol_got: "
330 "couldn't get info for %u\n", uin);
331 purple_notify_user_info_add_pair_plaintext(info, NULL,
332 _("Cannot get user information"));
333 purple_notify_userinfo(gc, ggp_uin_to_str(uin), info,
334 NULL, NULL);
335 purple_notify_user_info_destroy(info);
336 return;
339 purple_debug_info("gg", "ggp_pubdir_get_info_protocol_got: %u\n", uin);
340 g_assert(uin == record->uin);
341 g_assert(records_count == 1);
343 buddy = purple_blist_find_buddy(purple_connection_get_account(gc),
344 ggp_uin_to_str(uin));
345 if (buddy) {
346 const char *alias;
347 PurpleStatus *status;
348 gchar *status_message;
350 alias = purple_buddy_get_alias_only(buddy);
351 if (alias)
352 purple_notify_user_info_add_pair_plaintext(info,
353 _("Alias"), alias);
355 status = purple_presence_get_active_status(
356 purple_buddy_get_presence(buddy));
357 ggp_status_from_purplestatus(status, &status_message);
358 purple_notify_user_info_add_pair_plaintext(info, _("Status"),
359 purple_status_get_name(status));
360 if (status_message) {
361 purple_notify_user_info_add_pair_plaintext(info,
362 _("Message"), status_message);
366 if (record->nickname) {
367 purple_notify_user_info_add_pair_plaintext(info,
368 _("Nickname"), record->nickname);
370 if (record->first_name) {
371 purple_notify_user_info_add_pair_plaintext(info,
372 _("First name"), record->first_name);
374 if (record->last_name) {
375 purple_notify_user_info_add_pair_plaintext(info,
376 _("Last name"), record->last_name);
378 if (record->gender != GGP_PUBDIR_GENDER_UNSPECIFIED) {
379 purple_notify_user_info_add_pair_plaintext(info, _("Gender"),
380 record->gender == GGP_PUBDIR_GENDER_FEMALE ?
381 _("Female") : _("Male"));
383 if (record->city) {
384 purple_notify_user_info_add_pair_plaintext(info, _("City"),
385 record->city);
387 if (record->birth) {
388 purple_notify_user_info_add_pair_plaintext(info, _("Birthday"),
389 ggp_date_strftime("%Y-%m-%d", record->birth));
390 } else if (record->age) {
391 gchar *age_s = g_strdup_printf("%d", record->age);
392 purple_notify_user_info_add_pair_plaintext(info, _("Age"),
393 age_s);
394 g_free(age_s);
397 purple_notify_userinfo(gc, ggp_uin_to_str(uin), info, NULL, NULL);
398 purple_notify_user_info_destroy(info);
401 void
402 ggp_pubdir_get_info_protocol(PurpleConnection *gc, const char *name)
404 uin_t uin = ggp_str_to_uin(name);
405 uin_t *uin_p = g_new0(uin_t, 1);
407 *uin_p = uin;
409 purple_debug_info("gg", "ggp_pubdir_get_info_protocol: %u", uin);
411 ggp_pubdir_get_info(gc, uin, ggp_pubdir_get_info_protocol_got, uin_p);
414 static void ggp_pubdir_request_buddy_alias_got(PurpleConnection *gc,
415 int records_count, const ggp_pubdir_record *records, int next_offset,
416 void *user_data)
418 uin_t uin;
419 const gchar *alias;
421 if (records_count < 0) {
422 purple_debug_error("gg", "ggp_pubdir_request_buddy_alias_got: "
423 "couldn't get info for user\n");
424 return;
426 uin = records[0].uin;
428 alias = records[0].label;
429 if (!alias) {
430 purple_debug_info("gg", "ggp_pubdir_request_buddy_alias_got: "
431 "public alias for %u is not available\n", uin);
432 return;
435 purple_debug_info("gg", "ggp_pubdir_request_buddy_alias_got: "
436 "public alias for %u is \"%s\"\n", uin, alias);
438 purple_serv_got_alias(gc, ggp_uin_to_str(uin), alias);
441 void
442 ggp_pubdir_request_buddy_alias(PurpleConnection *gc, PurpleBuddy *buddy)
444 uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
446 purple_debug_info("gg", "ggp_pubdir_request_buddy_alias: %u", uin);
448 ggp_pubdir_get_info(gc, uin, ggp_pubdir_request_buddy_alias_got, NULL);
451 /*******************************************************************************
452 * Searching for buddies.
453 ******************************************************************************/
455 static ggp_pubdir_search_form *
456 ggp_pubdir_search_form_clone(const ggp_pubdir_search_form *form)
458 ggp_pubdir_search_form *dup = g_new(ggp_pubdir_search_form, 1);
460 dup->nick = g_strdup(form->nick);
461 dup->city = g_strdup(form->city);
462 dup->gender = form->gender;
463 dup->offset = form->offset;
464 dup->limit = form->limit;
466 dup->display_handle = form->display_handle;
468 return dup;
471 static gchar * ggp_pubdir_search_make_query(const ggp_pubdir_search_form *form)
473 gchar *nick, *city, *gender;
474 gchar *query;
476 if (form->nick && form->nick[0] != '\0') {
477 gchar *nick_e = g_uri_escape_string(form->nick, NULL, FALSE);
478 nick = g_strdup_printf("&nick=%s", nick_e);
479 g_free(nick_e);
480 } else
481 nick = g_strdup("");
483 if (form->city && form->city[0] != '\0') {
484 gchar *city_e = g_uri_escape_string(form->city, NULL, FALSE);
485 city = g_strdup_printf("&city=%s", city_e);
486 g_free(city_e);
487 } else
488 city = g_strdup("");
490 if (form->gender != GGP_PUBDIR_GENDER_UNSPECIFIED) {
491 gender = g_strdup_printf("&gender=%d",
492 form->gender == GGP_PUBDIR_GENDER_MALE ? 2 : 1);
493 } else
494 gender = g_strdup("");
496 query = g_strdup_printf("/users.xml?offset=%d&limit=%d%s%s%s",
497 form->offset, form->limit, nick, city, gender);
499 g_free(nick);
500 g_free(city);
501 g_free(gender);
503 return query;
506 static void ggp_pubdir_search_got_token(PurpleConnection *gc,
507 const gchar *token, gpointer _request)
509 GGPInfo *info = NULL;
510 gchar *url;
511 SoupMessage *msg;
512 ggp_pubdir_request *request = _request;
513 gchar *query;
515 PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
517 if (!token) {
518 request->cb(gc, -1, NULL, 0, request->user_data);
519 ggp_pubdir_request_free(request);
520 return;
523 purple_debug_misc("gg", "ggp_pubdir_search_got_token\n");
525 query = ggp_pubdir_search_make_query(request->params.search_form);
527 info = purple_connection_get_protocol_data(gc);
529 url = g_strdup_printf("http://api.gadu-gadu.pl%s", query);
530 msg = soup_message_new("GET", url);
531 soup_message_headers_replace(msg->request_headers, "Authorization", token);
532 soup_session_queue_message(info->http, msg, ggp_pubdir_got_data, request);
534 g_free(url);
535 g_free(query);
538 static void
539 ggp_pubdir_search_execute(PurpleConnection *gc,
540 const ggp_pubdir_search_form *form,
541 ggp_pubdir_request_cb cb, void *user_data)
543 ggp_pubdir_request *request = g_new0(ggp_pubdir_request, 1);
544 gchar *url;
545 ggp_pubdir_search_form *local_form = ggp_pubdir_search_form_clone(form);
546 gchar *query;
548 request->type = GGP_PUBDIR_REQUEST_TYPE_SEARCH;
549 request->gc = gc;
550 request->cb = cb;
551 request->user_data = user_data;
552 request->params.search_form = local_form;
554 query = ggp_pubdir_search_make_query(form);
555 purple_debug_misc("gg", "ggp_pubdir_search_execute: %s", query);
556 url = g_strdup_printf("http://api.gadu-gadu.pl%s", query);
557 ggp_oauth_request(gc, ggp_pubdir_search_got_token, request, "GET", url);
558 g_free(query);
559 g_free(url);
562 static void
563 ggp_pubdir_search_results_new(PurpleConnection *gc, GList *row, gpointer _form)
565 ggp_pubdir_search_form *form = _form;
566 ggp_pubdir_search(gc, form);
569 static void
570 ggp_pubdir_search_results_close(gpointer _form)
572 ggp_pubdir_search_form *form = _form;
573 ggp_pubdir_search_form_free(form);
576 static void
577 ggp_pubdir_search_results_next(PurpleConnection *gc, GList *row, gpointer _form)
579 ggp_pubdir_search_form *form = _form;
580 ggp_pubdir_search_execute(gc, form, ggp_pubdir_search_results_display,
581 form);
584 static void
585 ggp_pubdir_search_results_add(PurpleConnection *gc, GList *row, gpointer _form)
587 purple_blist_request_add_buddy(purple_connection_get_account(gc),
588 g_list_nth_data(row, 0), NULL,
589 g_list_nth_data(row, 1));
592 static void
593 ggp_pubdir_search_results_im(PurpleConnection *gc, GList *row, gpointer _form)
595 purple_conversation_present(PURPLE_CONVERSATION(purple_im_conversation_new(
596 purple_connection_get_account(gc), g_list_nth_data(row, 0))));
599 static void
600 ggp_pubdir_search_results_info(PurpleConnection *gc, GList *row, gpointer _form)
602 ggp_pubdir_get_info_protocol(gc, g_list_nth_data(row, 0));
605 static void
606 ggp_pubdir_search_results_display(PurpleConnection *gc, int records_count,
607 const ggp_pubdir_record *records,
608 int next_offset, void *_form)
610 ggp_pubdir_search_form *form = _form;
611 PurpleNotifySearchResults *results;
612 int i;
614 purple_debug_info("gg", "ggp_pubdir_search_results_display: "
615 "got %d records (next offset: %d)\n",
616 records_count, next_offset);
618 if (records_count < 0 ||
619 (records_count == 0 && form->offset != 0))
621 purple_notify_error(gc, GGP_PUBDIR_SEARCH_TITLE,
622 _("Error while searching for buddies"), NULL,
623 purple_request_cpar_from_connection(gc));
624 ggp_pubdir_search_form_free(form);
625 return;
628 if (records_count == 0) {
629 purple_notify_info(gc, GGP_PUBDIR_SEARCH_TITLE,
630 _("No matching users found"),
631 _("There are no users matching your search criteria."),
632 purple_request_cpar_from_connection(gc));
633 ggp_pubdir_search_form_free(form);
634 return;
637 form->offset = next_offset;
639 results = purple_notify_searchresults_new();
641 purple_notify_searchresults_column_add(results,
642 purple_notify_searchresults_column_new(_("GG Number")));
643 purple_notify_searchresults_column_add(results,
644 purple_notify_searchresults_column_new(_("Name")));
645 purple_notify_searchresults_column_add(results,
646 purple_notify_searchresults_column_new(_("City")));
647 purple_notify_searchresults_column_add(results,
648 purple_notify_searchresults_column_new(_("Gender")));
649 purple_notify_searchresults_column_add(results,
650 purple_notify_searchresults_column_new(_("Age")));
652 for (i = 0; i < records_count; i++) {
653 GList *row = NULL;
654 const ggp_pubdir_record *record = &records[i];
655 gchar *gender = NULL, *age = NULL;
657 if (record->gender == GGP_PUBDIR_GENDER_MALE)
658 gender = g_strdup("male");
659 else if (record->gender == GGP_PUBDIR_GENDER_FEMALE)
660 gender = g_strdup("female");
662 if (record->age)
663 age = g_strdup_printf("%d", record->age);
665 row = g_list_append(row, g_strdup(ggp_uin_to_str(record->uin)));
666 row = g_list_append(row, g_strdup(record->label));
667 row = g_list_append(row, g_strdup(record->city));
668 row = g_list_append(row, gender);
669 row = g_list_append(row, age);
670 purple_notify_searchresults_row_add(results, row);
673 purple_notify_searchresults_button_add(results,
674 PURPLE_NOTIFY_BUTTON_ADD, ggp_pubdir_search_results_add);
675 purple_notify_searchresults_button_add(results,
676 PURPLE_NOTIFY_BUTTON_IM, ggp_pubdir_search_results_im);
677 purple_notify_searchresults_button_add(results,
678 PURPLE_NOTIFY_BUTTON_INFO, ggp_pubdir_search_results_info);
679 purple_notify_searchresults_button_add_labeled(results, _("New search"),
680 ggp_pubdir_search_results_new);
681 if (next_offset != 0)
682 purple_notify_searchresults_button_add(results,
683 PURPLE_NOTIFY_BUTTON_CONTINUE,
684 ggp_pubdir_search_results_next);
686 if (!form->display_handle)
687 form->display_handle = purple_notify_searchresults(gc,
688 GGP_PUBDIR_SEARCH_TITLE, _("Search results"), NULL,
689 results, ggp_pubdir_search_results_close, form);
690 else
691 purple_notify_searchresults_new_rows(gc, results,
692 form->display_handle);
693 g_assert(form->display_handle);
696 static void
697 ggp_pubdir_search_request(PurpleConnection *gc, PurpleRequestFields *fields)
699 ggp_pubdir_search_form *form = g_new0(ggp_pubdir_search_form, 1);
701 purple_debug_info("gg", "ggp_pubdir_search_request");
703 form->nick = g_strdup(purple_request_fields_get_string(fields, "name"));
704 form->city = g_strdup(purple_request_fields_get_string(fields, "city"));
705 form->gender =
706 GPOINTER_TO_INT(purple_request_fields_get_choice(fields, "gender"));
707 form->offset = 0;
708 form->limit = GGP_PUBDIR_SEARCH_PER_PAGE;
710 ggp_pubdir_search_execute(gc, form, ggp_pubdir_search_results_display,
711 form);
714 void
715 ggp_pubdir_search(PurpleConnection *gc, const ggp_pubdir_search_form *form)
717 PurpleRequestFields *fields;
718 PurpleRequestFieldGroup *group;
719 PurpleRequestField *field;
721 purple_debug_info("gg", "ggp_pubdir_search");
723 fields = purple_request_fields_new();
724 group = purple_request_field_group_new(NULL);
725 purple_request_fields_add_group(fields, group);
727 field = purple_request_field_string_new("name", _("Name"),
728 form ? form->nick : NULL, FALSE);
729 purple_request_field_group_add_field(group, field);
731 field = purple_request_field_string_new("city", _("City"),
732 form ? form->city : NULL, FALSE);
733 purple_request_field_group_add_field(group, field);
735 field = purple_request_field_choice_new(
736 "gender", _("Gender"), form ? GINT_TO_POINTER(form->gender) : NULL);
737 purple_request_field_choice_add(field, _("Male or female"), NULL);
738 purple_request_field_choice_add(field, _("Male"),
739 GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
740 purple_request_field_choice_add(field, _("Female"),
741 GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
742 purple_request_field_group_add_field(group, field);
744 purple_request_fields(gc, _("Find buddies"), _("Find buddies"),
745 _("Please, enter your search criteria below"), fields,
746 _("OK"), G_CALLBACK(ggp_pubdir_search_request),
747 _("Cancel"), NULL,
748 purple_request_cpar_from_connection(gc), gc);
751 /*******************************************************************************
752 * Own profile.
753 ******************************************************************************/
755 static void
756 ggp_pubdir_set_info_got_response(G_GNUC_UNUSED SoupSession *session,
757 SoupMessage *msg, gpointer user_data)
759 if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) {
760 purple_debug_error("gg", "ggp_pubdir_set_info_got_response: failed");
761 return;
764 purple_debug_info("gg", "ggp_pubdir_set_info_got_response: [%s]",
765 msg->response_body->data);
766 /* <result><status>0</status></result> */
768 /* TODO: notify about failure */
771 static void ggp_pubdir_set_info_got_token(PurpleConnection *gc,
772 const gchar *token, gpointer _record)
774 ggp_pubdir_record *record = _record;
775 GGPInfo *info = NULL;
776 SoupMessage *msg;
777 gchar *url;
778 gchar *request_data;
779 gchar *name, *surname, *city;
780 uin_t uin = record->uin;
782 PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
784 if (!token) {
785 /* TODO: notify about failure */
786 ggp_pubdir_record_free(record, 1);
787 return;
790 info = purple_connection_get_protocol_data(gc);
792 name = g_uri_escape_string(record->first_name, NULL, FALSE);
793 surname = g_uri_escape_string(record->last_name, NULL, FALSE);
794 city = g_uri_escape_string(record->city, NULL, FALSE);
796 request_data = g_strdup_printf(
797 "name=%s&"
798 "surname=%s&"
799 "birth=%sT10:00:00%%2B00:00&"
800 "birth_priv=2&"
801 "gender=%d&"
802 "gender_priv=2&"
803 "city=%s&"
804 "province=%d",
805 name, surname,
806 ggp_date_strftime("%Y-%m-%d", record->birth),
807 record->gender,
808 city,
809 record->province);
811 if (purple_debug_is_verbose() && purple_debug_is_unsafe()) {
812 purple_debug_misc("gg", "ggp_pubdir_set_info_got_token: "
813 "query [%s]\n", request_data);
816 url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u.xml", uin);
817 msg = soup_message_new("PUT", url);
818 soup_message_headers_replace(msg->request_headers, "Authorization", token);
819 soup_message_set_request(msg, "application/x-www-form-urlencoded",
820 SOUP_MEMORY_TAKE, request_data, -1);
821 soup_session_queue_message(info->http, msg,
822 ggp_pubdir_set_info_got_response, NULL);
824 g_free(url);
825 ggp_pubdir_record_free(record, 1);
828 static void
829 ggp_pubdir_set_info_request(PurpleConnection *gc, PurpleRequestFields *fields)
831 gchar *url;
832 uin_t uin = ggp_str_to_uin(
833 purple_account_get_username(purple_connection_get_account(gc)));
834 ggp_pubdir_record *record = g_new0(ggp_pubdir_record, 1);
835 gchar *birth_s;
837 purple_debug_info("gg", "ggp_pubdir_set_info_request");
839 record->uin = uin;
840 record->first_name =
841 g_strdup(purple_request_fields_get_string(fields, "first_name"));
842 record->last_name =
843 g_strdup(purple_request_fields_get_string(fields, "last_name"));
844 record->gender =
845 GPOINTER_TO_INT(purple_request_fields_get_choice(fields, "gender"));
846 record->city = g_strdup(purple_request_fields_get_string(fields, "city"));
847 record->province = GPOINTER_TO_INT(
848 purple_request_fields_get_choice(fields, "province"));
850 birth_s = g_strdup_printf(
851 "%sT10:00:00+00:00",
852 purple_request_fields_get_string(fields, "birth_date"));
853 record->birth = ggp_date_from_iso8601(birth_s);
854 g_free(birth_s);
855 purple_debug_info("gg", "ggp_pubdir_set_info_request: birth [%lu][%s]",
856 record->birth,
857 purple_request_fields_get_string(fields, "birth_date"));
859 url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u.xml", uin);
860 ggp_oauth_request(gc, ggp_pubdir_set_info_got_token, record, "PUT", url);
861 g_free(url);
864 static void
865 ggp_pubdir_set_info_dialog(PurpleConnection *gc, int records_count,
866 const ggp_pubdir_record *records, int next_offset,
867 void *user_data)
869 PurpleRequestFields *fields;
870 PurpleRequestFieldGroup *group;
871 PurpleRequestField *field;
872 gsize i;
873 const ggp_pubdir_record *record;
875 purple_debug_info("gg", "ggp_pubdir_set_info_dialog (record: %d)",
876 records_count);
878 record = (records_count == 1 ? &records[0] : NULL);
880 fields = purple_request_fields_new();
881 group = purple_request_field_group_new(NULL);
882 purple_request_fields_add_group(fields, group);
884 field = purple_request_field_string_new("first_name", _("First name"),
885 record ? record->first_name : NULL,
886 FALSE);
887 purple_request_field_group_add_field(group, field);
889 field = purple_request_field_string_new("last_name", _("Last name"),
890 record ? record->last_name : NULL,
891 FALSE);
892 purple_request_field_group_add_field(group, field);
894 field = purple_request_field_choice_new(
895 "gender", _("Gender"),
896 record ? GINT_TO_POINTER(record->gender)
897 : GGP_PUBDIR_GENDER_UNSPECIFIED);
898 purple_request_field_set_required(field, TRUE);
899 purple_request_field_choice_add(field, _("Male"),
900 GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
901 purple_request_field_choice_add(field, _("Female"),
902 GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
903 purple_request_field_group_add_field(group, field);
905 field = purple_request_field_string_new(
906 "birth_date", _("Birth Day"),
907 (record && record->birth)
908 ? ggp_date_strftime("%Y-%m-%d", record->birth)
909 : NULL,
910 FALSE);
911 purple_request_field_set_required(field, TRUE);
912 purple_request_field_group_add_field(group, field);
914 field = purple_request_field_string_new(
915 "city", _("City"), record ? record->city : NULL, FALSE);
916 purple_request_field_group_add_field(group, field);
918 /* Translators: This word is basically used to describe a Polish
919 province. Gadu-Gadu users outside of Poland might choose to enter some
920 equivalent value for themselves. For example, users in the USA might
921 use their state (e.g. New York). If there is an equivalent term for
922 your language, feel free to use it. Otherwise it's probably acceptable
923 to leave it changed or transliterate it into your alphabet. */
924 field = purple_request_field_choice_new("province", _("Voivodeship"), 0);
925 purple_request_field_group_add_field(group, field);
926 for (i = 0; i < ggp_pubdir_provinces_count; i++) {
927 purple_request_field_choice_add(field, ggp_pubdir_provinces[i],
928 GINT_TO_POINTER(i));
929 if (record && i == record->province) {
930 purple_request_field_choice_set_value(field, GINT_TO_POINTER(i));
931 purple_request_field_choice_set_default_value(field,
932 GINT_TO_POINTER(i));
936 purple_request_fields(gc, _("Set User Info"), _("Set User Info"), NULL,
937 fields, _("OK"),
938 G_CALLBACK(ggp_pubdir_set_info_request), _("Cancel"),
939 NULL, purple_request_cpar_from_connection(gc), gc);
942 void
943 ggp_pubdir_set_info(PurpleConnection *gc)
945 ggp_pubdir_get_info(gc,
946 ggp_str_to_uin(purple_account_get_username(
947 purple_connection_get_account(gc))),
948 ggp_pubdir_set_info_dialog, NULL);