/* * Copyright (C) 2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #include "edsf-view.h" #include SE_GOBJECT_TYPE(EdsfPersona); SE_BEGIN_CXX EDSFView::EDSFView(const ESourceRegistryCXX ®istry, const std::string &uuid, const std::string &query) : m_registry(registry), m_uuid(uuid), m_query(query) { } void EDSFView::init(const boost::shared_ptr &self) { m_self = self; } boost::shared_ptr EDSFView::create(const ESourceRegistryCXX ®istry, const std::string &uuid, const std::string &query) { boost::shared_ptr view(new EDSFView(registry, uuid, query)); view->init(view); return view; } void EDSFView::doStart() { // This function may get entered again, see retry code in opened() below. ESourceCXX source(e_source_registry_ref_source(m_registry, m_uuid.c_str()), TRANSFER_REF); if (!source) { SE_LOG_DEBUG(NULL, "edsf %s: address book not found", m_uuid.c_str()); return; } m_store = EdsfPersonaStoreCXX::steal(edsf_persona_store_new_with_source_registry(m_registry, source)); GErrorCXX gerror; #ifdef HAVE_E_BOOK_CLIENT_CONNECT_DIRECT_SYNC // TODO: use asynchronous version, once there is one in EDS if (!getenv("SYNCEVOLUTION_NO_PIM_EDS_DIRECT")) { while (!m_ebook) { SE_LOG_DEBUG(NULL, "edsf %s: synchronously connecting direct", m_uuid.c_str()); m_ebook = EBookClientCXX::steal(E_BOOK_CLIENT(e_book_client_connect_direct_sync(m_registry, source, NULL, gerror))); if (!m_ebook) { SE_LOG_DEBUG(NULL, "edsf %s: no DRA client for address book: %s", m_uuid.c_str(), gerror ? gerror->message : "???"); if (gerror && g_error_matches(gerror, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { SE_LOG_DEBUG(NULL, "edsf %s: try again", m_uuid.c_str()); gerror.clear(); } else { return; } } } // Already opened by call above, proceed immediately. opened(true, NULL); return; } #endif SE_LOG_DEBUG(NULL, "edsf %s: new client", m_uuid.c_str()); m_ebook = EBookClientCXX::steal(e_book_client_new(source, gerror)); if (!m_ebook) { SE_LOG_DEBUG(NULL, "edsf %s: no normal client for address book: %s", m_uuid.c_str(), gerror ? gerror->message : "???"); return; } SE_LOG_DEBUG(NULL, "edsf %s: asynchronous open", m_uuid.c_str()); SYNCEVO_GLIB_CALL_ASYNC(e_client_open, boost::bind(&EDSFView::opened, m_self, _1, _2), E_CLIENT(m_ebook.get()), false, NULL); } void EDSFView::opened(gboolean success, const GError *gerror) throw() { try { if (!success) { SE_LOG_DEBUG(NULL, "edsf %s: opening failed: %s", m_uuid.c_str(), gerror ? gerror->message : "???"); if (gerror && g_error_matches(gerror, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { SE_LOG_DEBUG(NULL, "edsf %s: try again", m_uuid.c_str()); doStart(); return; } } SE_LOG_DEBUG(NULL, "edsf %s: opened successfully, reading contacts asynchronously: %s", m_uuid.c_str(), m_query.c_str()); SYNCEVO_GLIB_CALL_ASYNC(e_book_client_get_contacts, boost::bind(&EDSFView::read, m_self, _1, _2, _3), m_ebook.get(), m_query.c_str(), NULL); } catch (...) { Exception::handle(HANDLE_EXCEPTION_NO_ERROR); } } void EDSFView::read(gboolean success, GSList *contactslist, const GError *gerror) throw() { try { SE_LOG_DEBUG(NULL, "edsf %s: reading contacts completed: %s", m_uuid.c_str(), success ? "success" : gerror ? gerror->message : "failed without error"); GListCXX contacts(contactslist); if (!success) { SE_LOG_DEBUG(NULL, "edsf %s: reading failed: %s", m_uuid.c_str(), gerror->message); return; } BOOST_FOREACH (EContact *contact, contacts) { EdsfPersonaCXX persona(edsf_persona_new(m_store, contact), TRANSFER_REF); GeeHashSetCXX personas(gee_hash_set_new(G_TYPE_OBJECT, g_object_ref, g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL), TRANSFER_REF); gee_collection_add(GEE_COLLECTION(personas.get()), persona.get()); FolksIndividualCXX individual(folks_individual_new(GEE_SET(personas.get())), TRANSFER_REF); m_addedSignal(individual); } m_isQuiescent = true; m_quiescenceSignal(); } catch (...) { Exception::handle(HANDLE_EXCEPTION_NO_ERROR); } } SE_END_CXX