linuxinterface.cpp 8.93 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

/*
 * Copyright 2019  Linus Jahn <lnj@kaidan.im>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License or (at your option) version 3 or any later version
 * accepted by the membership of KDE e.V. (or its successor approved
 * by the membership of KDE e.V.), which shall act as a proxy
 * defined in Section 14 of version 3 of the license.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
21
#include "linuxinterface.h"
22 23 24

#include <KContacts/Addressee>
#include <KContacts/VCardConverter>
25 26
#include <KPeople/KPeople/PersonsModel>
#include <KPeople/KPeopleBackend/AbstractContact>
Anupam Basak's avatar
Anupam Basak committed
27 28 29
#include <KPeople/PersonData>
#include <QCryptographicHash>
#include <QDebug>
30
#include <QDirIterator>
Anupam Basak's avatar
Anupam Basak committed
31 32
#include <QFile>
#include <QStandardPaths>
33
#include <algorithm>
34 35

using namespace KContacts;
Anupam Basak's avatar
Anupam Basak committed
36 37 38 39
LinuxInterface::LinuxInterface(QObject *parent)
    : AbstractInterface(parent)
{
}
40 41 42

static FMH::MODEL vCardData(const QString &url)
{
43
    FMH::MODEL res;
44
    QFile file(url);
Anupam Basak's avatar
Anupam Basak committed
45
    if (!(file.exists())) {
46 47 48 49
        qWarning() << "Can't read vcard, file doesn't exist";
        return res;
    }

Anupam Basak's avatar
Anupam Basak committed
50
    if (!file.open(QIODevice::ReadOnly)) {
51 52 53 54 55
        qWarning() << "Couldn't update vCard: Couldn't open file for reading / writing.";
        return res;
    }

    VCardConverter converter;
56

57 58
    Addressee adr = converter.parseVCard(file.readAll());

Anupam Basak's avatar
Anupam Basak committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    qDebug() << adr.url().toString() << adr.customs() << adr.formattedName() << adr.fullEmail();
    res = {//        {FMH::MODEL_KEY::ID, QStringLiteral("vcard:/")+url},
           //            {FMH::MODEL_KEY::N, adr.name()},
           {FMH::MODEL_KEY::ORG, adr.organization()},
           {FMH::MODEL_KEY::GENDER, adr.gender().gender()},
           {FMH::MODEL_KEY::TITLE, adr.title()},
           {FMH::MODEL_KEY::NOTE, adr.note()},
           {FMH::MODEL_KEY::URL, adr.url().toString()},
           {FMH::MODEL_KEY::FAV, adr.custom("fav", "fav")},
           //            {FMH::MODEL_KEY::EMAIL, adr.emails().join(",")},
           //            {FMH::MODEL_KEY::TEL, [phones = adr.phoneNumbers(PhoneNumber::Cell)]()
           //             {
           //                 return std::accumulate(phones.begin(), phones.end(), QStringList(), [](QStringList &value, const PhoneNumber &number) -> QStringList
           //                 {
           //                     return value << number.number();
           //                 });
           //             }().join(",")
           //            },
           {FMH::MODEL_KEY::PHOTO, adr.photo().url()}};
78 79

    file.close();
80
    return res;
81 82
}

83
void LinuxInterface::getContacts()
Anupam Basak's avatar
Anupam Basak committed
84 85
{
    //    QDirIterator it(this->path, {"*.vcf"}, QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
86

Anupam Basak's avatar
Anupam Basak committed
87
    //    while(it.hasNext())
88 89 90
    //        this->m_contacts <<

    KPeople::PersonsModel model;
Anupam Basak's avatar
Anupam Basak committed
91
    for (auto i = 0; i < model.rowCount(); i++) {
92 93 94
        const auto uri = model.get(i, KPeople::PersonsModel::PersonUriRole).toString();

        KPeople::PersonData person(uri);
Anupam Basak's avatar
Anupam Basak committed
95
        QMultiHash contact = FMH::MODEL {
Anupam Basak's avatar
Anupam Basak committed
96 97 98
            {FMH::MODEL_KEY::ID, person.personUri()}, {FMH::MODEL_KEY::N, person.name()}, {FMH::MODEL_KEY::EMAIL, person.email()}, {FMH::MODEL_KEY::TEL, person.contactCustomProperty("phoneNumber").toString()},
            //        {FMH::MODEL_KEY::PHOTO, person.pictureUrl().toString()}
        };
99 100
        this->m_contacts << contact.unite(vCardData(QString(uri).replace("vcard:/", "")));
    }
101 102

    emit this->contactsReady(this->m_contacts);
103
}
104

105 106
FMH::MODEL LinuxInterface::getContact(const QString &id)
{
camilo higuita's avatar
camilo higuita committed
107 108 109 110
    FMH::MODEL res;
    auto personUri = id;

    if (!(QUrl(personUri).scheme() == "vcard")) {
111
        qWarning() << "uri of contact is not a vcard, cannot get contact.";
camilo higuita's avatar
camilo higuita committed
112 113
        return res;
    }
114
    return vCardData(personUri.remove("vcard:/"));
Camilo higuita's avatar
Camilo higuita committed
115 116
}

117
bool LinuxInterface::insertContact(const FMH::MODEL &contact)
118
{
Anupam Basak's avatar
Anupam Basak committed
119
    qDebug() << "TRYIN TO INSERT VACRD CONTACT" << contact;
120 121
    // addresses
    Addressee adr;
122
    adr.setName(contact[FMH::MODEL_KEY::N]);
123
    //    adr.setUid(contact[FMH::MODEL_KEY::ID]);
124 125
    adr.setUrl(contact[FMH::MODEL_KEY::URL]);
    adr.setNote(contact[FMH::MODEL_KEY::NOTE]);
camilo higuita's avatar
camilo higuita committed
126 127 128
    adr.setTitle(contact[FMH::MODEL_KEY::TITLE]);
    adr.setOrganization(contact[FMH::MODEL_KEY::ORG]);
    adr.setGender(contact[FMH::MODEL_KEY::GENDER]);
129

camilo higuita's avatar
camilo higuita committed
130
    adr.setCustoms({QString("%1:%2").arg(FMH::MODEL_NAME[FMH::MODEL_KEY::FAV], contact[FMH::MODEL_KEY::FAV])});
131

132 133
    Email email;
    email.setEmail(contact[FMH::MODEL_KEY::EMAIL]);
camilo higuita's avatar
camilo higuita committed
134
    adr.setEmailList({email});
135

136 137 138
    Picture photo;
    photo.setUrl(contact[FMH::MODEL_KEY::PHOTO]);
    adr.setPhoto(photo);
139

140
    PhoneNumber phoneNum;
141
    phoneNum.setNumber(contact[FMH::MODEL_KEY::TEL]);
142
    phoneNum.setType(PhoneNumber::Cell);
camilo higuita's avatar
camilo higuita committed
143
    adr.setPhoneNumbers({phoneNum});
144 145 146 147 148 149 150 151

    // create vcard
    VCardConverter converter;
    QByteArray vcard = converter.createVCard(adr);
    qDebug() << vcard;

    // save vcard
    QCryptographicHash hash(QCryptographicHash::Sha1);
152
    hash.addData(adr.name().toUtf8());
153
    QFile file(this->path + "/" + hash.result().toHex() + ".vcf");
154

Anupam Basak's avatar
Anupam Basak committed
155
    if (!file.open(QFile::WriteOnly)) {
156
        qWarning() << "Couldn't save vCard: Couldn't open file for writing.";
157
        return false;
158
    }
159

160 161
    file.write(vcard.data(), vcard.length());
    file.close();
162 163 164 165 166 167

    return true;
}

bool LinuxInterface::updateContact(const QString &id, const FMH::MODEL &contact)
{
camilo higuita's avatar
camilo higuita committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
    auto personUri = id;

    if (!(QUrl(personUri).scheme() == "vcard")) {
        qWarning() << "uri of contact to update is not a vcard, cannot update.";
        return false;
    }

    QFile file(personUri.remove("vcard:/"));
    if (!(file.exists())) {
        qWarning() << "Can't read vcard, file doesn't exist";
        return false;
    }
    if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
        qWarning() << "Couldn't update vCard: Couldn't open file for reading / writing.";
        return false;
    }

    VCardConverter converter;
    Addressee adr = converter.parseVCard(file.readAll());

Anupam Basak's avatar
Anupam Basak committed
188
    for (const auto &key : contact.keys()) {
camilo higuita's avatar
camilo higuita committed
189
        const auto data = contact[key];
Anupam Basak's avatar
Anupam Basak committed
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
        qDebug() << "updating filed:" << key << data;
        switch (key) {
        case FMH::MODEL_KEY::N: {
            if (!data.isEmpty())
                adr.setName(data);
            break;
        }

        case FMH::MODEL_KEY::TEL: {
            PhoneNumber::List phoneNums;
            PhoneNumber phoneNum;
            phoneNum.setNumber(data);
            phoneNum.setType(PhoneNumber::Cell);
            phoneNums.append(phoneNum);
            adr.setPhoneNumbers(phoneNums);
            break;
        }

        case FMH::MODEL_KEY::ORG: {
            adr.setOrganization(data);
            break;
        }

        case FMH::MODEL_KEY::TITLE: {
            adr.setTitle(data);
            break;
        }

        case FMH::MODEL_KEY::FAV: {
            adr.setCustoms({QString("%1:%2").arg(FMH::MODEL_NAME[FMH::MODEL_KEY::FAV], data)});
            break;
        }

        case FMH::MODEL_KEY::EMAIL: {
            Email email;
            email.setEmail(data);
            adr.setEmailList({email});
            break;
        }

        case FMH::MODEL_KEY::NOTE: {
            adr.setNote(data);
            break;
        }

        case FMH::MODEL_KEY::GENDER: {
            adr.setGender(data);
            break;
        }

        case FMH::MODEL_KEY::PHOTO: {
            Picture photo;
            photo.setUrl(data);
            adr.setPhoto(photo);
            break;
        }

        case FMH::MODEL_KEY::URL: {
            adr.setUrl(data);
            break;
        }

        default:
            break;
camilo higuita's avatar
camilo higuita committed
254 255 256 257 258 259 260 261 262
        }
    }

    QByteArray vcard = converter.createVCard(adr);
    qDebug() << vcard;

    file.write(vcard);
    file.close();
    return true;
263 264 265 266
}

bool LinuxInterface::removeContact(const QString &id)
{
Anupam Basak's avatar
Anupam Basak committed
267
    if (!(QUrl(id).scheme() == "vcard")) {
camilo higuita's avatar
camilo higuita committed
268 269 270
        qWarning() << "uri of contact to remove is not a vcard, cannot remove.";
        return false;
    }
271

camilo higuita's avatar
camilo higuita committed
272
    return QFile::remove(QString(id).remove("vcard:/"));
273
}
274 275 276 277 278

QImage LinuxInterface::contactPhoto(const QString &id)
{
    auto personUri = id;

Anupam Basak's avatar
Anupam Basak committed
279
    if (!(QUrl(personUri).scheme() == "vcard")) {
280 281 282 283 284
        qWarning() << "uri of contact is not a vcard, cannot get photo.";
        return QImage();
    }

    QFileInfo file(personUri.remove("vcard:/"));
Anupam Basak's avatar
Anupam Basak committed
285
    if (!(file.exists())) {
286 287 288 289
        qWarning() << "Can't read vcard, file doesn't exist";
        return QImage();
    }

Anupam Basak's avatar
Anupam Basak committed
290
    qDebug() << "IMAGE FILE REQUESTED" << vCardData(personUri)[FMH::MODEL_KEY::PHOTO];
291
    return QImage(vCardData(personUri)[FMH::MODEL_KEY::PHOTO].replace("file://", ""));
292
}