source: SMSSender/src/business/contactimporters/contactfilesimporter.cpp @ 305:4c9cc14b5fc3

Last change on this file since 305:4c9cc14b5fc3 was 305:4c9cc14b5fc3, checked in by Sämy Zehnder <saemy.zehnder@…>, 7 years ago
  • Fixed duplicate usage of variable.
File size: 8.4 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 "contactfilesimporter.h"
20#include "contactfilesimporter_datamanager.h"
21
22#include <QDebug>
23#include <QDesktopServices>
24#include <QFileInfo>
25
26#include <scontact.h>
27#include <snumber.h>
28
29#include "ui/contactimporterpages/contactfilesimporter/cfi_page_config.h"
30
31ContactFilesImporter::ContactFilesImporter(QObject* parent)
32    : IContactImporter(parent)
33    , dataManager_(new ContactFilesImporterDataManager(this))
34{
35}
36
37QString ContactFilesImporter::describingName() const {
38    return tr("Import contacts from contact files (Old smssender contact files, CSV).");
39}
40
41bool ContactFilesImporter::isApplicable() const {
42    return true;
43}
44
45
46void ContactFilesImporter::init() {
47    dataManager_->setContactFiles(defaultContactsFiles().toSet());
48    dataManager_->setSelectedContactFiles(defaultContactsFiles().toSet());
49}
50
51QList<QWizardPage*> ContactFilesImporter::createPreImportPages(QWidget* parent) {
52    QList<QWizardPage*> pages;
53    pages.append(new CFI::PageConfig(parent, dataManager_));
54
55    return pages;
56}
57
58QSet<SContact> ContactFilesImporter::importContacts() {
59    QSet<SContact> contacts;
60
61    foreach (QString contactsFile, dataManager_->selectedContactFiles()) {
62        if (!QFile::exists(contactsFile)) continue;
63
64        QFileInfo fi(contactsFile);
65        if (fi.completeSuffix().toLower() == "ini") {
66            QSettings ini(contactsFile, QSettings::IniFormat);
67            if (ini.childGroups().contains("contacts")) {
68                // V1 contacts file
69                contacts.unite(readV1ContactsFile(ini));
70            } else {
71                // V2 contacts file
72                contacts.unite(readV2ContactsFile(ini));
73            }
74
75        } else if (fi.completeSuffix().toLower() == "db") {
76            // V3 contacts file
77            // TODO: Import V3 contacts file
78
79        } else if (fi.completeSuffix().toLower() == "csv") {
80            CSVFile csv = parseCSV(contactsFile);
81            contacts.unite(readCSV(csv));
82        }
83    }
84
85    return contacts;
86}
87
88
89void _addDefaultFile(QStringList& files, QString filename) {
90    QFileInfo fi(filename);
91    if (fi.exists()) {
92        files.append(fi.absoluteFilePath());
93    }
94}
95QStringList ContactFilesImporter::defaultContactsFiles() const {
96    QStringList r;
97
98    _addDefaultFile(r, QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/gorrion/SMSSender/contacts.ini");
99    _addDefaultFile(r, QDesktopServices::storageLocation(QDesktopServices::ApplicationsLocation) + "/gorrion/SMSSender/contacts.ini");
100
101    return r;
102}
103
104QSet<SContact> ContactFilesImporter::readV1ContactsFile(const QSettings& ini) const {
105    QSet<SContact> result;
106
107    int i = 0;
108    while (ini.contains("contacts/contact_" + QString::number(i) + "_nr")) {
109        QString name = ini.value("contacts/contact_" + QString::number(i) + "_name").toString();
110        SNumber number(ini.value("contacts/contact_" + QString::number(i) + "_nr").toString());
111        if (!name.trimmed().isEmpty() && number.isValid()) {
112            SContact contact;
113            contact.setName(name);
114            contact.setNumber(number);
115
116            result.insert(contact);
117        }
118
119        ++i;
120    }
121
122    return result;
123}
124
125QSet<SContact> ContactFilesImporter::readV2ContactsFile(const QSettings& ini) const {
126    QSet<SContact> result;
127
128    foreach (QString name, ini.childGroups()) {
129        SNumber number(ini.value(name + "/" + "number").toString());
130        if (!name.trimmed().isEmpty() && number.isValid()) {
131            SContact contact;
132            contact.setName(name);
133            contact.setNumber(number);
134
135            result.insert(contact);
136        }
137    }
138
139    return result;
140}
141
142
143QStringList parseLine(const QString& line) {
144    QStringList s;
145    QRegExp rx("(\"([^\"]*)\"|)(,|$)");
146
147    int pos = 0;
148    while ((pos = rx.indexIn(line, pos)) != -1) {
149        if (pos == line.length()) break;
150
151        pos += rx.matchedLength();
152
153        qDebug() << rx.capturedTexts();
154        s.append(rx.cap(2));
155    }
156    return s;
157}
158
159ContactFilesImporter::CSVFile ContactFilesImporter::parseCSV(const QString& filename) const {
160    CSVFile csv;
161
162    QFile file(filename);
163    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
164        return csv;
165
166    QTextStream in(&file);
167
168    if (!in.atEnd()) {
169        QString line = in.readLine();
170        csv.keys = parseLine(line);
171    }
172
173    while (!in.atEnd()) {
174        QString line = in.readLine();
175
176        QMap<QString, QString> valuesLine;
177        QStringList values = parseLine(line);
178        for (int i = 0; i < values.size(); ++i) {
179            if (i >= csv.keys.size()) break;
180
181            QString value = values.at(i).trimmed();
182            valuesLine.insert(csv.keys.at(i), value);
183        }
184        csv.values.append(valuesLine);
185    }
186
187    return csv;
188}
189
190QSet<SContact> ContactFilesImporter::readCSV(const CSVFile& csv) const {
191    QSet<SContact> result;
192
193    QStringList nameKeys;
194    nameKeys.append("[Name]");      // Google CSV
195    nameKeys.append("[Yomi Name]"); // Google CSV
196    nameKeys.append("[Title][First Name][Middle Name][Last Name]"); // Outlook CSV
197    nameKeys.append("[Nickname]");  // Google CSV
198
199    for (int i = 0; i < csv.values.count(); ++i) {
200        QMap<QString, QString> csvLine = csv.values.at(i);
201
202        QStringList names;
203        foreach(QString nameKey, nameKeys) {
204            QRegExp rx("\\[([^\\]]+)\\]");
205            QStringList keys;
206            int pos = 0;
207            while ((pos = rx.indexIn(nameKey, pos)) != -1) {
208                pos += rx.matchedLength();
209
210                keys.append(rx.cap(1));
211            }
212
213            QString name = "";
214            foreach (QString key, keys) {
215                if (!csvLine.value(key).isEmpty()) {
216                    name += csvLine.value(key) + ' ';
217                }
218            }
219
220            if (!name.trimmed().isEmpty()) {
221                names.append(name);
222            }
223        }
224        names.removeAll("");
225        names.removeDuplicates();
226
227
228        SNumber number;
229        if (csv.keys.contains("Mobile Phone")) {
230            number.fromString(csvLine.value("Mobile Phone"));
231        }
232
233        int j = 1;
234        while (csv.keys.contains(QString("Phone %1 - Type").arg(j)) && !number.isValid()) {
235            if (csvLine.value(QString("Phone %1 - Type").arg(j)) != "Mobile") continue;
236
237            QStringList numberStrings = csvLine.value(QString("Phone %1 - Value").arg(j)).split(":::");
238            int k = 0;
239            while (!number.isValid() && (k < numberStrings.count())) {
240                number.fromString(numberStrings.at(k).trimmed());
241                ++k;
242            }
243
244            ++j;
245        }
246
247
248        if ((names.count() > 0) && number.isValid()) {
249            SContact contact;
250            contact.setName(names.takeFirst());
251            contact.setNumber(number);
252            contact.setAliases(names);
253
254            result.insert(contact);
255        }
256    }
257
258    return result;
259}
260
261
262/**********************************************************************************************/
263
264ContactFilesImporterDataManager::ContactFilesImporterDataManager(QObject* parent)
265    : QObject(parent)
266{
267}
268
269QSet<QString> ContactFilesImporterDataManager::contactFiles() const {
270    return contactFiles_;
271}
272void ContactFilesImporterDataManager::setContactFiles(const QSet<QString>& contactFiles) {
273    contactFiles_ = contactFiles;
274    emit contactFilesChanged();
275}
276
277QSet<QString> ContactFilesImporterDataManager::selectedContactFiles() const {
278    return selectedContactFiles_;
279}
280void ContactFilesImporterDataManager::setSelectedContactFiles(const QSet<QString>& contactFiles) {
281    selectedContactFiles_.clear();
282    foreach (QString selected, contactFiles) {
283        if (contactFiles_.contains(selected)) {
284            selectedContactFiles_.insert(selected);
285        }
286    }
287    emit selectedContactFilesChanged();
288}
Note: See TracBrowser for help on using the repository browser.