source: SMSSender/src/business/contactimporters/googlecontactimporter.cpp @ 243:33e017a65e67

3.0.beta1
Last change on this file since 243:33e017a65e67 was 243:33e017a65e67, checked in by Sämy Zehnder <saemy.zehnder@…>, 7 years ago
  • Sorting the contact importers now.
  • Translation updates.
File size: 6.6 KB
Line 
1/*
2 smssender - A frontend for fast and easy SMS sending over different gateways.
3 Copyright (C) 2007-2012, gorrión. See http://smssender.gorrion.ch
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "googlecontactimporter.h"
20
21#include <QRegExp>
22
23#include <scontact.h>
24#include <snetworkreply.h>
25#include <snumber.h>
26
27#include <exceptions/eexception.h>
28
29GoogleContactImporter::GoogleContactImporter(QObject* parent)
30    : IContactImporter(parent)
31    , configPage_(NULL)
32    , networkHelper_(new SNetworkHelper(this))
33{
34    networkHelper_->addTrustedCA(":/certs/VerisignClass3PublicPrimaryCertificationAuthority.crt");
35}
36
37QString GoogleContactImporter::describingName() const {
38    return tr("Import contacts from google contacts.");
39}
40
41bool GoogleContactImporter::isApplicable() const {
42    return true;
43}
44
45
46void GoogleContactImporter::init() {
47}
48
49QList<QWizardPage*> GoogleContactImporter::createPreImportPages(QWidget* parent) {
50    configPage_ = new GCI::PageConfig(parent);
51
52    QList<QWizardPage*> pages;
53    pages.append(configPage_);
54    return pages;
55}
56
57QSet<SContact> GoogleContactImporter::importContacts() {
58    QSet<SContact> contacts;
59
60    requestAuthToken();
61    networkHelper_->defaultHeaders().insert("GData-Version", "3.0");
62
63    QString nextUrl = "http://www.google.com/m8/feeds/contacts/default/thin?max-results=10000";
64    do {
65        QString contactsFeed = networkHelper_->syncGet(nextUrl)->readAll();
66        contactsFeed = SNetworkHelper::urldecodeString(contactsFeed);
67        parseContactsFeed(contactsFeed, contacts);
68
69        QRegExp rx("<link rel='next' type='application/atom\\+xml' href='([^']+)'/>");
70        if (rx.indexIn(contactsFeed) != -1) {
71            nextUrl = rx.cap(1);
72        } else {
73            break;
74        }
75    } while (true);
76
77    return contacts;
78}
79
80void GoogleContactImporter::parseContactsFeed(const QString& feed, QSet<SContact>& contacts) {
81    /*<entry gd:etag=""SXszeTVSLyt7ImA9WxFbFk8ORQU."">
82        <id>http://www.google.com/m8/feeds/contacts/saemy.zehnder%40gmail.com/base/59ea8d658e87e360</id>
83        <updated>2010-07-08T21:23:38.581Z</updated>
84        <app:edited>2010-07-08T21:23:38.581Z</app:edited>
85        <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
86        <title>test2</title>
87        <link rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/%avoidwarninghere%*" href="http://www.google.com/m8/feeds/photos/media/saemy.zehnder%40gmail.com/59ea8d658e87e360" gd:etag=""VxFIFH0fSit7ImA0G0AqEU8PIQEjJkMyazA.""/>
88        <link rel="self" type="application/atom+xml" href="http://www.google.com/m8/feeds/contacts/saemy.zehnder%40gmail.com/thin/59ea8d658e87e360"/>
89        <link rel="edit" type="application/atom+xml" href="http://www.google.com/m8/feeds/contacts/saemy.zehnder%40gmail.com/thin/59ea8d658e87e360"/>
90        <gd:name>
91            <gd:fullName>test2</gd:fullName>
92            <gd:givenName>test2</gd:givenName>
93        </gd:name>
94        <gContact:nickname>nick1</gContact:nickname>
95        <gd:phoneNumber rel="http://schemas.google.com/g/2005#mobile">+41 079 12345 67</gd:phoneNumber>
96        <gd:phoneNumber rel="http://schemas.google.com/g/2005#mobile">+41 079 12345 68</gd:phoneNumber>
97        <gContact:groupMembershipInfo deleted="false" href="http://www.google.com/m8/feeds/groups/saemy.zehnder%40gmail.com/base/6"/>
98      </entry> */
99    QRegExp rx("<entry.*>(.*)</entry>");
100    rx.setMinimal(true);
101
102    int pos = 0;
103    while ((pos = rx.indexIn(feed, pos)) != -1) {
104        pos += rx.matchedLength();
105
106        try {
107            QString entry = rx.cap(1);
108
109            QRegExp rx2;
110            rx2.setMinimal(true);
111
112            rx2.setPattern("<gd:name>.*<gd:givenName>(.*)</gd:givenName>.*</gd:name>");
113            if (rx2.indexIn(entry) == -1) continue;
114            QString name = rx2.cap(1);
115
116            rx2.setPattern("<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>(.*)</gd:phoneNumber>");
117            if (rx2.indexIn(entry) == -1) continue;
118            SNumber number(rx2.cap(1));
119
120            if (!name.isEmpty() && number.isValid()) {
121                SContact contact;
122                contact.setName(name);
123                contact.setNumber(number);
124
125                rx2.setPattern("<gContact:nickname>(.*)</gContact:nickname>");
126                if ((rx2.indexIn(entry) != -1) && !rx2.cap(1).isEmpty()) {
127                    //qDebug() << rx2.cap(1);
128                    QStringList aliases;
129                    aliases.append(rx2.cap(1));
130                    contact.setAliases(aliases);
131                }
132
133                rx2.setPattern("<link rel='http://schemas.google.com/contacts/2008/rel#photo' type='image/\\*' href='([^']+)' gd:etag='([^']+)'/>");
134                if (rx2.indexIn(entry) != -1) {
135                    QImage img = QImage::fromData(networkHelper_->syncGet(rx2.cap(1))->readAll());
136                    if (!img.isNull()) {
137                        contact.setImage(img);
138                    }
139                }
140
141                contacts.insert(contact);
142            }
143        } catch (...) {
144            // don't fail to import all contacts because of one...
145        }
146    }
147}
148
149void GoogleContactImporter::requestAuthToken() {
150    Q_ASSERT(configPage_);
151
152    QList<IParam*> posts;
153    posts.append(new SKeyValueParam("accountType", "GOOGLE"));
154    posts.append(new SKeyValueParam("Email",       configPage_->username().toUtf8()));
155    posts.append(new SKeyValueParam("Passwd",      configPage_->password().toUtf8()));
156    posts.append(new SKeyValueParam("service",     "cp"));
157    posts.append(new SKeyValueParam("source",      "gorrion-smssender-3"));
158
159    QString result;
160    try {
161        result = networkHelper_->syncPost(QUrl::fromEncoded("https://www.google.com/accounts/ClientLogin"), posts)->readAll();
162    } catch (EException& e) {
163        result = "";
164    }
165
166    QRegExp rx("Auth=(\\S+)");
167    if (rx.indexIn(result) != -1) {
168        networkHelper_->defaultHeaders().insert("Authorization", QString("GoogleLogin auth=" + rx.cap(1)).toUtf8());
169    } else {
170        EException("Login failed. You have probably entered incorrect userdata.")
171                .raise();
172    }
173}
Note: See TracBrowser for help on using the repository browser.