Adding error handling in resource.
[akonadigoogledata.git] / googledataresource.cpp
blob75289c298f89000501ba2864ccb787984b758cc0
1 #include "googledataresource.h"
3 #include "settings.h"
4 #include "settingsadaptor.h"
6 #include <QtDBus/QDBusConnection>
7 #include <kabc/addressee.h>
8 #include <kabc/phonenumber.h>
9 #include <kabc/key.h>
10 #include <kabc/errorhandler.h>
11 #include <qstring.h>
12 #include <KWindowSystem>
14 extern "C" {
15 #include <gcalendar.h>
16 #include <gcontact.h>
17 #include <gcal_status.h>
20 using namespace Akonadi;
22 GoogleDataResource::GoogleDataResource( const QString &id )
23 : ResourceBase(id), authenticated(false), dlgConf(NULL)
25 new SettingsAdaptor( Settings::self() );
26 QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ),
27 Settings::self(), QDBusConnection::ExportAdaptors );
30 if (!(gcal = gcal_new(GCONTACT)))
31 exit(1);
32 gcal_set_store_xml(gcal, 1);
35 GoogleDataResource::~GoogleDataResource()
37 gcal_delete(gcal);
38 gcal_cleanup_contacts(&all_contacts);
39 if (dlgConf)
40 delete dlgConf;
43 void GoogleDataResource::retrieveCollections()
45 if (!authenticated) {
46 kError() << "No athentication for Google Contacts available";
47 const QString message = i18nc("@info:status",
48 "No yet authenticated for"
49 " use of Google Contacts");
50 emit error(message);
52 emit status(Broken, message);
53 return;
56 Collection c;
57 c.setParent(Collection::root());
58 c.setRemoteId("google-contacts");
59 c.setName(name());
61 QStringList mimeTypes;
62 mimeTypes << "text/directory";
63 c.setContentMimeTypes(mimeTypes);
65 Collection::List list;
66 list << c;
67 collectionsRetrieved(list);
71 void GoogleDataResource::retrieveItems( const Akonadi::Collection &collection )
73 Q_UNUSED( collection );
75 Item::List items;
76 int result;
78 if (!authenticated) {
79 kError() << "No athentication for Google Contacts available";
80 const QString message = i18nc("@info:status",
81 "No yet authenticated for"
82 " use of Google Contacts");
83 emit error(message);
85 emit status(Broken, message);
86 return;
89 /* Downloading the contacts can be slow and it is blocking. Will
90 * it mess up with akonadi?
92 if ((result = gcal_get_contacts(gcal, &all_contacts)))
93 exit(1);
95 /* Each google entry has a unique ID and edit_url */
96 for (size_t i = 0; i < all_contacts.length; ++i) {
98 Item item(QLatin1String("text/directory"));
99 gcal_contact_t contact = gcal_contact_element(&all_contacts, i);
100 item.setRemoteId(gcal_contact_get_id(contact));
102 items << item;
105 itemsRetrieved(items);
108 bool GoogleDataResource::retrieveItem( const Akonadi::Item &item, const QSet<QByteArray> &parts )
110 Q_UNUSED( parts );
111 const QString entry_id = item.remoteId();
112 QString temp;
113 Item newItem(item);
114 gcal_contact_t contact;
115 KABC::Addressee addressee;
116 KABC::PhoneNumber number;
117 KABC::Key key;
119 if (!authenticated) {
120 kError() << "No athentication for Google Contacts available";
121 const QString message = i18nc("@info:status",
122 "No yet authenticated for"
123 " use of Google Contacts");
124 emit error(message);
126 emit status(Broken, message);
127 return false;
131 * And another question, are the requests in the same sequence that
132 * I informed in 'retrieveItems'? For while, I try to locate the entry...
134 for (size_t i = 0; i < all_contacts.length; ++i) {
135 contact = gcal_contact_element(&all_contacts, i);
136 if (entry_id == gcal_contact_get_id(contact)) {
137 /* name */
138 temp = gcal_contact_get_title(contact);
139 addressee.setNameFromString(temp);
141 /* email */
142 temp = gcal_contact_get_email(contact);
143 addressee.insertEmail(temp, true);
145 /* edit url: required to do edit/delete */
146 temp = gcal_contact_get_url(contact);
147 addressee.setUid(temp);
149 /* ETag: required by Google Data protocol 2.0 */
150 temp = gcal_contact_get_etag(contact);
151 key.setId(temp);
152 addressee.insertKey(key);
154 /* TODO: telefone, address, etc */
156 newItem.setPayload<KABC::Addressee>(addressee);
157 return true;
162 return false;
165 void GoogleDataResource::aboutToQuit()
167 // TODO: any cleanup you need to do while there is still an active
168 // event loop. The resource will terminate after this method returns
171 void GoogleDataResource::configure( WId windowId )
173 Q_UNUSED( windowId );
174 char *user, *pass;
175 int result = -1;
176 QByteArray byteUser, bytePass;
178 if (!dlgConf)
179 dlgConf = new dlgGoogleDataConf;
181 if (windowId && dlgConf)
182 KWindowSystem::setMainWindow(dlgConf, windowId);
184 dlgConf->exec();
186 byteUser = dlgConf->eAccount->text().toLocal8Bit();
187 bytePass = dlgConf->ePass->text().toLocal8Bit();
188 user = const_cast<char *>(byteUser.constData());
189 pass = const_cast<char *>(bytePass.constData());
190 if (user)
191 if (pass)
192 result = gcal_get_authentication(gcal, user, pass);
194 /* TODO: in case of authentication error, display an error
195 * message.
197 if (!result)
198 authenticated = true;
200 synchronize();
203 void GoogleDataResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection )
206 Q_UNUSED(collection);
208 KABC::Addressee addressee;
209 gcal_contact_t contact;
210 QString temp;
211 int result;
213 if (!authenticated) {
214 kError() << "No athentication for Google Contacts available";
215 const QString message = i18nc("@info:status",
216 "No yet authenticated for"
217 " use of Google Contacts");
218 emit error(message);
220 emit status(Broken, message);
221 return;
224 if (item.hasPayload<KABC::Addressee>())
225 addressee = item.payload<KABC::Addressee>();
227 if (!(contact = gcal_contact_new(NULL)))
228 exit(1);
230 temp = addressee.realName();
231 gcal_contact_set_title(contact, const_cast<char *>(qPrintable(temp)));
233 temp = addressee.fullEmail();
234 gcal_contact_set_email(contact, const_cast<char *>(qPrintable(temp)));
236 /* TODO: add remaining fields */
238 if ((result = gcal_add_contact(gcal, contact)))
239 exit(1);
241 gcal_contact_delete(contact);
245 void GoogleDataResource::itemChanged( const Akonadi::Item &item, const QSet<QByteArray> &parts )
247 Q_UNUSED(parts);
249 KABC::Addressee addressee;
250 gcal_contact_t contact;
251 KABC::Key key;
252 QString temp;
253 int result;
255 if (!authenticated) {
256 kError() << "No athentication for Google Contacts available";
257 const QString message = i18nc("@info:status",
258 "No yet authenticated for"
259 " use of Google Contacts");
260 emit error(message);
262 emit status(Broken, message);
263 return;
266 if (item.hasPayload<KABC::Addressee>())
267 addressee = item.payload<KABC::Addressee>();
269 if (!(contact = gcal_contact_new(NULL)))
270 exit(1);
272 temp = addressee.realName();
273 gcal_contact_set_title(contact, const_cast<char *>(qPrintable(temp)));
275 temp = addressee.fullEmail();
276 gcal_contact_set_email(contact, const_cast<char *>(qPrintable(temp)));
278 temp = addressee.uid();
279 gcal_contact_set_id(contact, const_cast<char *>(qPrintable(temp)));
281 /* I suppose that this retrieves the first element in the key list */
282 key = addressee.keys()[0];
283 temp = key.id();
284 gcal_contact_set_etag(contact, const_cast<char *>(qPrintable(temp)));
287 /* TODO: add remaining fields */
289 if ((result = gcal_update_contact(gcal, contact)))
290 exit(1);
293 /* Updates the ETag/url: I suppose that akonadi will save this object */
294 temp = gcal_contact_get_url(contact);
295 addressee.setUid(temp);
297 temp = gcal_contact_get_etag(contact);
298 key.setId(temp);
299 addressee.insertKey(key);
302 gcal_contact_delete(contact);
306 void GoogleDataResource::itemRemoved( const Akonadi::Item &item )
308 KABC::Addressee addressee;
309 gcal_contact_t contact;
310 KABC::Key key;
311 QString temp;
312 int result;
314 if (!authenticated) {
315 kError() << "No athentication for Google Contacts available";
316 const QString message = i18nc("@info:status",
317 "No yet authenticated for"
318 " use of Google Contacts");
319 emit error(message);
321 emit status(Broken, message);
322 return;
325 if (item.hasPayload<KABC::Addressee>())
326 addressee = item.payload<KABC::Addressee>();
328 if (!(contact = gcal_contact_new(NULL)))
329 exit(1);
331 temp = addressee.uid();
332 gcal_contact_set_id(contact, const_cast<char *>(qPrintable(temp)));
334 /* I suppose that this retrieves the first element in the key list */
335 key = addressee.keys()[0];
336 temp = key.id();
337 gcal_contact_set_etag(contact, const_cast<char *>(qPrintable(temp)));
339 if ((result = gcal_erase_contact(gcal, contact)))
340 exit(1);
342 gcal_contact_delete(contact);
346 AKONADI_RESOURCE_MAIN( GoogleDataResource )
348 #include "googledataresource.moc"