Updated packaging for new 0.0.2 release.
[qwerkisync] / NumberToNameLookup.cpp
1 /*
2  * Copyright (C) 2011, Jamie Thompson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License as published by the Free Software Foundation; either
7  * version 3 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; If not, see
16  * <http://www.gnu.org/licenses/>.
17  */
18
19 #include <glib.h>
20 #include <glib/glist.h>
21 #include <libosso.h>
22 #include <libosso-abook/osso-abook.h>
23 #include <libebook/e-book.h>
24 #include <evolution-data-server-1.4/libebook/e-vcard.h>
25 #include <evolution-data-server-1.4/libebook/e-contact.h>
26
27 #include "NumberToNameLookup.h"
28
29 #include <stdexcept>
30
31 #include <QDebug>
32
33 NumberToNameLookup::NumberToNameLookup()
34 {
35         GError *gError(NULL);
36
37         // Initialize osso
38         osso_context_t *osso_context(osso_initialize ("qwerkisync", "0.1", true, NULL));
39         if (NULL == osso_context)
40                 throw std::runtime_error("Error initializing osso");
41
42         try
43         {
44                 // Init abook
45                 if (!osso_abook_init_with_name("qwerkisync", osso_context))
46                         throw std::runtime_error("Error initializing libosso-abook");
47
48                 EBook *ebook(e_book_new_system_addressbook (&gError));
49                 if (NULL == ebook)
50                 {
51                         QString error(QString("Error opening system address book: %1").arg(gError->message));
52                         g_error_free(gError);
53                         throw std::runtime_error(error.toStdString());
54                 }
55
56                 if (!e_book_open (ebook, true, &gError))
57                 {
58                         QString error(QString("Error opening system address book: %1").arg(gError->message));
59                         g_error_free(gError);
60                         throw std::runtime_error(error.toStdString());
61                 }
62
63                 EBookQuery *query(e_book_query_any_field_contains (""));
64
65                 try
66                 {
67                         GList *contacts(NULL);
68                         if (!e_book_get_contacts (ebook, query, &contacts, &gError))
69                         {
70                                 QString error(QString("Error getting contacts: %1").arg(gError->message));
71                                 g_error_free(gError);
72                                 throw std::runtime_error(error.toStdString());
73                         }
74
75                         m_ContactDetails.reserve(g_list_length(contacts));
76
77                         qDebug() << g_list_length(contacts) << " contacts.";
78
79                         // Loop over each contact...
80                         for (GList *currentContact(contacts); NULL != currentContact; currentContact = currentContact->next)
81                         {
82                                 // Now work out the current name for the contact and add it to the lookup
83                                 EContactName *contactName = (EContactName*)e_contact_get((EContact*)currentContact->data, E_CONTACT_NAME);
84                                 char *completeName(e_contact_name_to_string(contactName));
85                                 //qDebug() << completeName;
86
87                                 // Looking at each number they have...
88                                 GList * attrs(e_contact_get_attributes(E_CONTACT(currentContact->data), E_CONTACT_FIRST_PHONE_ID));
89                                 for (GList *attr(attrs); NULL != attr; attr = attr->next)
90                                 {
91                                         for(GList *val(e_vcard_attribute_get_values((EVCardAttribute *)attr->data)); NULL != val; val = val->next)
92                                         {
93                                                 const gchar *number((char*)val->data);
94                                                 if (NULL == number)
95                                                         continue; // Ignore missing numbers
96
97                                                 const char *remote_ebook_uid_string((const char *)e_contact_get_const (E_CONTACT (currentContact->data), E_CONTACT_UID));
98                                                 if (NULL != remote_ebook_uid_string)
99                                                 {
100                                                         // This is what we really need for new events
101                                                         uint remote_ebook_uid(QString(remote_ebook_uid_string).toUInt());
102
103                                                         m_ContactDetails.insert(QString(number), QPair<uint, QString>(remote_ebook_uid, QString(completeName)));
104
105                                                         //qDebug() << "Number: " << number << ", ID: " << remote_ebook_uid << ", completeName: " << completeName;
106                                                 }
107                                         }
108                                 }
109                                 g_list_free(attrs);
110
111                                 g_free(completeName);
112                                 e_contact_name_free(contactName);
113
114                                 // I hate C-style APIs.
115                                 g_object_unref(currentContact->data);
116                         }
117
118                         // I *really* hate C-style APIs.
119                         g_list_free(contacts);
120                 }
121                 catch(...)
122                 {
123                         e_book_query_unref(query);
124                         throw;
125                 }
126
127                 // Will wrap e_book_* in a class some other time (oh for 'finally' in C++).
128                 e_book_query_unref(query);
129         }
130         catch(...)
131         {
132                 osso_deinitialize (osso_context);
133                 throw;
134         }
135
136         // Will wrap osso_* in a class some other time (oh for 'finally' in C++).
137         osso_deinitialize (osso_context);
138
139 //      foreach(QString key, ContactDetails.keys())
140 //      {
141 //              qDebug() << key << ", " << ContactDetails.value(key).first << ", " << ContactDetails.value(key).second << endl;
142 //      }
143 }