From 149c4b1b1b4f8f022640b6b38e2c8c745be8dc70 Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Sun, 4 Dec 2011 00:30:02 +0200 Subject: [PATCH] core cleanup: separate contact search code --- po/POTFILES.in | 2 + src/api/core-depurple.h | 2 - src/api/sipe-backend.h | 16 +++++ src/api/sipe-core.h | 8 +++ src/core/Makefile.mingw | 1 + src/core/sipe-buddy.c | 139 +++++++++++++++++++++++++++++++++++++ src/core/sipe.c | 169 +-------------------------------------------- src/purple/Makefile.am | 1 + src/purple/purple-plugin.c | 46 ++++++++++-- src/purple/purple-search.c | 137 ++++++++++++++++++++++++++++++++++++ 10 files changed, 348 insertions(+), 173 deletions(-) create mode 100644 src/purple/purple-search.c diff --git a/po/POTFILES.in b/po/POTFILES.in index 555420bf..30e733a0 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -3,6 +3,7 @@ src/core/sip-transport.c src/core/sipe.c +src/core/sipe-buddy.c src/core/sipe-cal.c src/core/sipe-certificate.c src/core/sipe-chat.c @@ -24,4 +25,5 @@ src/purple/purple-chat.c src/purple/purple-groupchat.c src/purple/purple-im.c src/purple/purple-plugin.c +src/purple/purple-search.c src/purple/purple-transport.c diff --git a/src/api/core-depurple.h b/src/api/core-depurple.h index c95646c6..312e50cd 100644 --- a/src/api/core-depurple.h +++ b/src/api/core-depurple.h @@ -25,8 +25,6 @@ */ struct sipe_core_public; -void sipe_search_contact_with_cb(PurpleConnection *gc, - PurpleRequestFields *fields); GList *sipe_buddy_menu(PurpleBuddy *buddy); void sipe_purple_setup(struct sipe_core_public *sipe_public, PurpleConnection *gc); diff --git a/src/api/sipe-backend.h b/src/api/sipe-backend.h index 4af2d8eb..3cc2dbcd 100644 --- a/src/api/sipe-backend.h +++ b/src/api/sipe-backend.h @@ -527,6 +527,22 @@ gpointer sipe_backend_schedule_mseconds(struct sipe_core_public *sipe_public, void sipe_backend_schedule_cancel(struct sipe_core_public *sipe_public, gpointer data); +/** SEARCH *******************************************************************/ + +struct sipe_backend_search_results; + +struct sipe_backend_search_results *sipe_backend_search_results_start(struct sipe_core_public *sipe_public); +void sipe_backend_search_results_add(struct sipe_core_public *sipe_public, + struct sipe_backend_search_results *results, + const gchar *uri, + const gchar *name, + const gchar *company, + const gchar *country, + const gchar *email); +void sipe_backend_search_results_finalize(struct sipe_core_public *sipe_public, + struct sipe_backend_search_results *results, + const gchar *description); + /** SETTINGS *****************************************************************/ typedef enum { diff --git a/src/api/sipe-core.h b/src/api/sipe-core.h index 2203f278..679dea7b 100644 --- a/src/api/sipe-core.h +++ b/src/api/sipe-core.h @@ -171,6 +171,8 @@ sipe_utils_nameval_free(GSList *list); gboolean sipe_utils_is_avconf_uri(const gchar *uri); +gchar *sip_uri_from_name(const gchar *name); + /*****************************************************************************/ /** @@ -379,6 +381,12 @@ void sipe_core_buddy_group(struct sipe_core_public *sipe_public, const gchar *old_group_name, const gchar *new_group_name); +void sipe_core_buddy_search(struct sipe_core_public *sipe_public, + const gchar *given_name, + const gchar *surname, + const gchar *company, + const gchar *country); + #ifdef __cplusplus } #endif diff --git a/src/core/Makefile.mingw b/src/core/Makefile.mingw index 9e67fdaf..45f6148b 100644 --- a/src/core/Makefile.mingw +++ b/src/core/Makefile.mingw @@ -134,6 +134,7 @@ PURPLE_C_SRC = ../purple/purple-buddy.c \ ../purple/purple-notify.c \ ../purple/purple-plugin.c \ ../purple/purple-schedule.c \ + ../purple/purple-search.c \ ../purple/purple-setting.c \ ../purple/purple-transport.c \ ../purple/purple-user.c \ diff --git a/src/core/sipe-buddy.c b/src/core/sipe-buddy.c index 113f0836..e6fe2f6a 100644 --- a/src/core/sipe-buddy.c +++ b/src/core/sipe-buddy.c @@ -20,16 +20,25 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include +#include "sipe-common.h" +#include "sipmsg.h" +#include "sip-soap.h" #include "sipe-backend.h" #include "sipe-buddy.h" #include "sipe-core.h" #include "sipe-core-private.h" #include "sipe-group.h" +#include "sipe-nls.h" #include "sipe-utils.h" +#include "sipe-xml.h" gchar *sipe_core_buddy_status(struct sipe_core_public *sipe_public, const gchar *name, @@ -155,6 +164,136 @@ void sipe_buddy_update_property(struct sipe_core_private *sipe_private, g_slist_free(buddies); } +static gboolean process_search_contact_response(struct sipe_core_private *sipe_private, + struct sipmsg *msg, + SIPE_UNUSED_PARAMETER struct transaction *trans) +{ + struct sipe_backend_search_results *results; + sipe_xml *searchResults; + const sipe_xml *mrow; + guint match_count = 0; + gboolean more = FALSE; + gchar *secondary; + + /* valid response? */ + if (msg->response != 200) { + SIPE_DEBUG_ERROR("process_search_contact_response: request failed (%d)", + msg->response); + sipe_backend_notify_error(SIPE_CORE_PUBLIC, + _("Contact search failed"), + NULL); + return(FALSE); + } + + SIPE_DEBUG_INFO("process_search_contact_response: body:\n%s", msg->body ? msg->body : ""); + + /* valid XML? */ + searchResults = sipe_xml_parse(msg->body, msg->bodylen); + if (!searchResults) { + SIPE_DEBUG_INFO_NOFORMAT("process_search_contact_response: no parseable searchResults"); + sipe_backend_notify_error(SIPE_CORE_PUBLIC, + _("Contact search failed"), + NULL); + return(FALSE); + } + + /* any matches? */ + mrow = sipe_xml_child(searchResults, "Body/Array/row"); + if (!mrow) { + SIPE_DEBUG_ERROR_NOFORMAT("process_search_contact_response: no matches"); + sipe_backend_notify_error(SIPE_CORE_PUBLIC, + _("No contacts found"), + NULL); + + sipe_xml_free(searchResults); + return(FALSE); + } + + /* OK, we found something - show the results to the user */ + results = sipe_backend_search_results_start(SIPE_CORE_PUBLIC); + if (!results) { + SIPE_DEBUG_ERROR_NOFORMAT("process_search_contact_response: Unable to display the search results."); + sipe_backend_notify_error(SIPE_CORE_PUBLIC, + _("Unable to display the search results"), + NULL); + + sipe_xml_free(searchResults); + return FALSE; + } + + for (/* initialized above */ ; mrow; mrow = sipe_xml_twin(mrow)) { + gchar **uri_parts = g_strsplit(sipe_xml_attribute(mrow, "uri"), ":", 2); + sipe_backend_search_results_add(SIPE_CORE_PUBLIC, + results, + uri_parts[1], + sipe_xml_attribute(mrow, "displayName"), + sipe_xml_attribute(mrow, "company"), + sipe_xml_attribute(mrow, "country"), + sipe_xml_attribute(mrow, "email")); + g_strfreev(uri_parts); + match_count++; + } + + if ((mrow = sipe_xml_child(searchResults, "Body/directorySearch/moreAvailable")) != NULL) { + char *data = sipe_xml_data(mrow); + more = (g_strcasecmp(data, "true") == 0); + g_free(data); + } + + secondary = g_strdup_printf( + dngettext(PACKAGE_NAME, + "Found %d contact%s:", + "Found %d contacts%s:", match_count), + match_count, more ? _(" (more matched your query)") : ""); + + sipe_backend_search_results_finalize(SIPE_CORE_PUBLIC, + results, + secondary); + g_free(secondary); + sipe_xml_free(searchResults); + + return(TRUE); +} + +#define SIPE_SOAP_SEARCH_ROW "" + +void sipe_core_buddy_search(struct sipe_core_public *sipe_public, + const gchar *given_name, + const gchar *surname, + const gchar *company, + const gchar *country) +{ + gchar **attrs = g_new(gchar *, 5); + guint i = 0; + + if (!attrs) return; + +#define ADD_QUERY_ROW(a, v) \ + if (v) attrs[i++] = g_markup_printf_escaped(SIPE_SOAP_SEARCH_ROW, a, v) + + ADD_QUERY_ROW("givenName", given_name); + ADD_QUERY_ROW("sn", surname); + ADD_QUERY_ROW("company", company); + ADD_QUERY_ROW("c", country); + + if (i) { + gchar *query; + + attrs[i] = NULL; + query = g_strjoinv(NULL, attrs); + SIPE_DEBUG_INFO("sipe_core_buddy_search: rows:\n%s", + query ? query : ""); + sip_soap_directory_search(SIPE_CORE_PRIVATE, + 100, + query, + process_search_contact_response, + NULL); + g_free(query); + } + + g_strfreev(attrs); +} + /* Local Variables: mode: c diff --git a/src/core/sipe.c b/src/core/sipe.c index 5fbd4087..a11c69f8 100644 --- a/src/core/sipe.c +++ b/src/core/sipe.c @@ -1055,173 +1055,6 @@ void sipe_buddy_free_all(struct sipe_core_private *sipe_private) g_hash_table_foreach_steal(sipe_private->buddies, sipe_buddy_remove, NULL); } -static void sipe_searchresults_im_buddy(PurpleConnection *gc, GList *row, - SIPE_UNUSED_PARAMETER void *user_data) -{ - PurpleAccount *acct = purple_connection_get_account(gc); - char *id = sip_uri_from_name((gchar *)g_list_nth_data(row, 0)); - PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, id, acct); - if (conv == NULL) - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, id); - purple_conversation_present(conv); - g_free(id); -} - -static void sipe_searchresults_add_buddy(PurpleConnection *gc, GList *row, - SIPE_UNUSED_PARAMETER void *user_data) -{ - - purple_blist_request_add_buddy(purple_connection_get_account(gc), - g_list_nth_data(row, 0), _("Other Contacts"), g_list_nth_data(row, 1)); -} - -static gboolean process_search_contact_response(struct sipe_core_private *sipe_private, - struct sipmsg *msg, - SIPE_UNUSED_PARAMETER struct transaction *trans) -{ - struct sipe_account_data *sip = SIPE_ACCOUNT_DATA_PRIVATE; - PurpleNotifySearchResults *results; - PurpleNotifySearchColumn *column; - sipe_xml *searchResults; - const sipe_xml *mrow; - int match_count = 0; - gboolean more = FALSE; - gchar *secondary; - - /* valid response? */ - if (msg->response != 200) { - SIPE_DEBUG_ERROR("process_search_contact_response: request failed (%d)", - msg->response); - sipe_backend_notify_error(SIPE_CORE_PUBLIC, - _("Contact search failed"), - NULL); - return(FALSE); - } - - SIPE_DEBUG_INFO("process_search_contact_response: body:\n%s", msg->body ? msg->body : ""); - - /* valid XML? */ - searchResults = sipe_xml_parse(msg->body, msg->bodylen); - if (!searchResults) { - SIPE_DEBUG_INFO_NOFORMAT("process_search_contact_response: no parseable searchResults"); - sipe_backend_notify_error(SIPE_CORE_PUBLIC, - _("Contact search failed"), - NULL); - return FALSE; - } - - /* any matches? */ - mrow = sipe_xml_child(searchResults, "Body/Array/row"); - if (!mrow) { - SIPE_DEBUG_ERROR_NOFORMAT("process_search_contact_response: no matches"); - sipe_backend_notify_error(SIPE_CORE_PUBLIC, - _("No contacts found"), - NULL); - - sipe_xml_free(searchResults); - return(FALSE); - } - - /* OK, we found something - show the results to the user */ - results = purple_notify_searchresults_new(); - if (!results) { - SIPE_DEBUG_ERROR_NOFORMAT("process_search_contact_response: Unable to display the search results."); - sipe_backend_notify_error(SIPE_CORE_PUBLIC, - _("Unable to display the search results"), - NULL); - - sipe_xml_free(searchResults); - return FALSE; - } - - column = purple_notify_searchresults_column_new(_("User name")); - purple_notify_searchresults_column_add(results, column); - - column = purple_notify_searchresults_column_new(_("Name")); - purple_notify_searchresults_column_add(results, column); - - column = purple_notify_searchresults_column_new(_("Company")); - purple_notify_searchresults_column_add(results, column); - - column = purple_notify_searchresults_column_new(_("Country")); - purple_notify_searchresults_column_add(results, column); - - column = purple_notify_searchresults_column_new(_("Email")); - purple_notify_searchresults_column_add(results, column); - - for (/* initialized above */ ; mrow; mrow = sipe_xml_twin(mrow)) { - GList *row = NULL; - - gchar **uri_parts = g_strsplit(sipe_xml_attribute(mrow, "uri"), ":", 2); - row = g_list_append(row, g_strdup(uri_parts[1])); - g_strfreev(uri_parts); - - row = g_list_append(row, g_strdup(sipe_xml_attribute(mrow, "displayName"))); - row = g_list_append(row, g_strdup(sipe_xml_attribute(mrow, "company"))); - row = g_list_append(row, g_strdup(sipe_xml_attribute(mrow, "country"))); - row = g_list_append(row, g_strdup(sipe_xml_attribute(mrow, "email"))); - - purple_notify_searchresults_row_add(results, row); - match_count++; - } - - if ((mrow = sipe_xml_child(searchResults, "Body/directorySearch/moreAvailable")) != NULL) { - char *data = sipe_xml_data(mrow); - more = (g_strcasecmp(data, "true") == 0); - g_free(data); - } - - secondary = g_strdup_printf( - dngettext(PACKAGE_NAME, - "Found %d contact%s:", - "Found %d contacts%s:", match_count), - match_count, more ? _(" (more matched your query)") : ""); - - purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_IM, sipe_searchresults_im_buddy); - purple_notify_searchresults_button_add(results, PURPLE_NOTIFY_BUTTON_ADD, sipe_searchresults_add_buddy); - purple_notify_searchresults(sip->gc, NULL, NULL, secondary, results, NULL, NULL); - - g_free(secondary); - sipe_xml_free(searchResults); - return TRUE; -} - -#define SIPE_SOAP_SEARCH_ROW "" - -void sipe_search_contact_with_cb(PurpleConnection *gc, PurpleRequestFields *fields) -{ - GList *entries = purple_request_field_group_get_fields(purple_request_fields_get_groups(fields)->data); - gchar **attrs = g_new(gchar *, g_list_length(entries) + 1); - unsigned i = 0; - - if (!attrs) return; - - do { - PurpleRequestField *field = entries->data; - const char *id = purple_request_field_get_id(field); - const char *value = purple_request_field_string_get_value(field); - - SIPE_DEBUG_INFO("sipe_search_contact_with_cb: %s = '%s'", id, value ? value : ""); - - if (value != NULL) attrs[i++] = g_markup_printf_escaped(SIPE_SOAP_SEARCH_ROW, id, value); - } while ((entries = g_list_next(entries)) != NULL); - attrs[i] = NULL; - - if (i > 0) { - struct sipe_core_private *sipe_private = PURPLE_GC_TO_SIPE_CORE_PRIVATE; - gchar *query = g_strjoinv(NULL, attrs); - SIPE_DEBUG_INFO("sipe_search_contact_with_cb: rows:\n%s", query ? query : ""); - sip_soap_directory_search(sipe_private, - 100, - query, - process_search_contact_response, - NULL); - g_free(query); - } - - g_strfreev(attrs); -} - void sipe_core_reset_status(struct sipe_core_public *sipe_public) { struct sipe_core_private *sipe_private = SIPE_CORE_PRIVATE; @@ -2188,6 +2021,8 @@ process_get_info_response(struct sipe_core_private *sipe_private, return TRUE; } +#define SIPE_SOAP_SEARCH_ROW "" + /** * AD search first, LDAP based */ diff --git a/src/purple/Makefile.am b/src/purple/Makefile.am index 40477933..bdc40376 100644 --- a/src/purple/Makefile.am +++ b/src/purple/Makefile.am @@ -21,6 +21,7 @@ libsipe_backend_la_SOURCES = \ purple-network.c \ purple-notify.c \ purple-schedule.c \ + purple-search.c \ purple-setting.c \ purple-transport.c \ purple-user.c diff --git a/src/purple/purple-plugin.c b/src/purple/purple-plugin.c index d071fded..41130f38 100644 --- a/src/purple/purple-plugin.c +++ b/src/purple/purple-plugin.c @@ -646,6 +646,44 @@ static void sipe_purple_show_about_plugin(PurplePluginAction *action) g_free(tmp); } +static void sipe_purple_find_contact_cb(PurpleConnection *gc, + PurpleRequestFields *fields) +{ + GList *entries = purple_request_field_group_get_fields(purple_request_fields_get_groups(fields)->data); + const gchar *given_name = NULL; + const gchar *surname = NULL; + const gchar *company = NULL; + const gchar *country = NULL; + + while (entries) { + PurpleRequestField *field = entries->data; + const char *id = purple_request_field_get_id(field); + const char *value = purple_request_field_string_get_value(field); + + SIPE_DEBUG_INFO("sipe_purple_find_contact_cb: %s = '%s'", id, value ? value : ""); + + if (value) { + if (strcmp(id, "given") == 0) { + given_name = value; + } else if (strcmp(id, "surname") == 0) { + surname = value; + } else if (strcmp(id, "company") == 0) { + company = value; + } else if (strcmp(id, "country") == 0) { + country = value; + } + } + + entries = g_list_next(entries); + }; + + sipe_core_buddy_search(PURPLE_GC_TO_SIPE_CORE_PUBLIC, + given_name, + surname, + company, + country); +} + static void sipe_purple_show_find_contact(PurplePluginAction *action) { PurpleConnection *gc = (PurpleConnection *) action->context; @@ -657,13 +695,13 @@ static void sipe_purple_show_find_contact(PurplePluginAction *action) group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); - field = purple_request_field_string_new("givenName", _("First name"), NULL, FALSE); + field = purple_request_field_string_new("given", _("First name"), NULL, FALSE); purple_request_field_group_add_field(group, field); - field = purple_request_field_string_new("sn", _("Last name"), NULL, FALSE); + field = purple_request_field_string_new("surname", _("Last name"), NULL, FALSE); purple_request_field_group_add_field(group, field); field = purple_request_field_string_new("company", _("Company"), NULL, FALSE); purple_request_field_group_add_field(group, field); - field = purple_request_field_string_new("c", _("Country"), NULL, FALSE); + field = purple_request_field_string_new("country", _("Country"), NULL, FALSE); purple_request_field_group_add_field(group, field); purple_request_fields(gc, @@ -671,7 +709,7 @@ static void sipe_purple_show_find_contact(PurplePluginAction *action) _("Search for a contact"), _("Enter the information for the person you wish to find. Empty fields will be ignored."), fields, - _("_Search"), G_CALLBACK(sipe_search_contact_with_cb), + _("_Search"), G_CALLBACK(sipe_purple_find_contact_cb), _("_Cancel"), NULL, purple_connection_get_account(gc), NULL, NULL, gc); } diff --git a/src/purple/purple-search.c b/src/purple/purple-search.c new file mode 100644 index 00000000..39ed9119 --- /dev/null +++ b/src/purple/purple-search.c @@ -0,0 +1,137 @@ +/** + * @file purple-search.c + * + * pidgin-sipe + * + * Copyright (C) 2011 SIPE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "notify.h" + +#include "sipe-common.h" +#include "sipe-backend.h" +#include "sipe-core.h" +#include "sipe-nls.h" + +#include "purple-private.h" + +struct sipe_backend_search_results *sipe_backend_search_results_start(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public) +{ + PurpleNotifySearchResults *results = purple_notify_searchresults_new(); + + if (results) { + PurpleNotifySearchColumn *column; + column = purple_notify_searchresults_column_new(_("User name")); + purple_notify_searchresults_column_add(results, column); + + column = purple_notify_searchresults_column_new(_("Name")); + purple_notify_searchresults_column_add(results, column); + + column = purple_notify_searchresults_column_new(_("Company")); + purple_notify_searchresults_column_add(results, column); + + column = purple_notify_searchresults_column_new(_("Country")); + purple_notify_searchresults_column_add(results, column); + + column = purple_notify_searchresults_column_new(_("Email")); + purple_notify_searchresults_column_add(results, column); + } + + return((struct sipe_backend_search_results *)results); +} + +void sipe_backend_search_results_add(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public, + struct sipe_backend_search_results *results, + const gchar *uri, + const gchar *name, + const gchar *company, + const gchar *country, + const gchar *email) +{ + GList *row = NULL; + row = g_list_append(row, g_strdup(uri)); + row = g_list_append(row, g_strdup(name)); + row = g_list_append(row, g_strdup(company)); + row = g_list_append(row, g_strdup(country)); + row = g_list_append(row, g_strdup(email)); + purple_notify_searchresults_row_add((PurpleNotifySearchResults *) results, + row); +} + +static void searchresults_im_buddy(PurpleConnection *gc, + GList *row, + SIPE_UNUSED_PARAMETER void *user_data) +{ + PurpleAccount *acct = purple_connection_get_account(gc); + gchar *id = sip_uri_from_name(g_list_nth_data(row, 0)); + PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, + id, + acct); + if (conv == NULL) + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, id); + g_free(id); + purple_conversation_present(conv); +} + +static void searchresults_add_buddy(PurpleConnection *gc, + GList *row, + SIPE_UNUSED_PARAMETER void *user_data) +{ + purple_blist_request_add_buddy(purple_connection_get_account(gc), + g_list_nth_data(row, 0), + _("Other Contacts"), + g_list_nth_data(row, 1)); +} + + +void sipe_backend_search_results_finalize(struct sipe_core_public *sipe_public, + struct sipe_backend_search_results *results, + const gchar *description) +{ + struct sipe_backend_private *purple_private = sipe_public->backend_private; + PurpleNotifySearchResults *r = (PurpleNotifySearchResults *) results; + + purple_notify_searchresults_button_add(r, + PURPLE_NOTIFY_BUTTON_IM, + searchresults_im_buddy); + purple_notify_searchresults_button_add(r, + PURPLE_NOTIFY_BUTTON_ADD, + searchresults_add_buddy); + purple_notify_searchresults(purple_private->gc, + NULL, + NULL, + description, + r, + NULL, + NULL); + +} + +/* + Local Variables: + mode: c + c-file-style: "bsd" + indent-tabs-mode: t + tab-width: 8 + End: +*/ -- 2.11.4.GIT