File indexing completed on 2024-05-12 04:45:59
0001 0002 /* 0003 * Copyright 2019 Linus Jahn <lnj@kaidan.im> 0004 * 0005 * This program is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU General Public License as 0007 * published by the Free Software Foundation; either version 2 of 0008 * the License or (at your option) version 3 or any later version 0009 * accepted by the membership of KDE e.V. (or its successor approved 0010 * by the membership of KDE e.V.), which shall act as a proxy 0011 * defined in Section 14 of version 3 of the license. 0012 * 0013 * This program is distributed in the hope that it will be useful, 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0016 * GNU General Public License for more details. 0017 * 0018 * You should have received a copy of the GNU General Public License 0019 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0020 */ 0021 #include "linuxinterface.h" 0022 0023 #include <KContacts/Addressee> 0024 #include <KContacts/VCardConverter> 0025 #include <KPeople/KPeople/PersonsModel> 0026 #include <KPeople/KPeopleBackend/AbstractContact> 0027 #include <KPeople/PersonData> 0028 #include <QCryptographicHash> 0029 #include <QDebug> 0030 #include <QDirIterator> 0031 #include <QFile> 0032 #include <QStandardPaths> 0033 #include <algorithm> 0034 0035 using namespace KContacts; 0036 LinuxInterface::LinuxInterface(QObject *parent) 0037 : AbstractInterface(parent) 0038 { 0039 } 0040 0041 static FMH::MODEL vCardData(const QString &url) 0042 { 0043 FMH::MODEL res; 0044 QFile file(url); 0045 if (!(file.exists())) { 0046 qWarning() << "Can't read vcard, file doesn't exist"; 0047 return res; 0048 } 0049 0050 if (!file.open(QIODevice::ReadOnly)) { 0051 qWarning() << "Couldn't update vCard: Couldn't open file for reading / writing."; 0052 return res; 0053 } 0054 0055 VCardConverter converter; 0056 0057 Addressee adr = converter.parseVCard(file.readAll()); 0058 0059 qDebug() << adr.url().toString() << adr.customs() << adr.formattedName() << adr.fullEmail(); 0060 res = {// {FMH::MODEL_KEY::ID, QStringLiteral("vcard:/")+url}, 0061 // {FMH::MODEL_KEY::N, adr.name()}, 0062 {FMH::MODEL_KEY::ORG, adr.organization()}, 0063 {FMH::MODEL_KEY::GENDER, adr.gender().gender()}, 0064 {FMH::MODEL_KEY::TITLE, adr.title()}, 0065 {FMH::MODEL_KEY::NOTE, adr.note()}, 0066 {FMH::MODEL_KEY::URL, adr.url().toString()}, 0067 {FMH::MODEL_KEY::FAV, adr.custom("fav", "fav")}, 0068 // {FMH::MODEL_KEY::EMAIL, adr.emails().join(",")}, 0069 // {FMH::MODEL_KEY::TEL, [phones = adr.phoneNumbers(PhoneNumber::Cell)]() 0070 // { 0071 // return std::accumulate(phones.begin(), phones.end(), QStringList(), [](QStringList &value, const PhoneNumber &number) -> QStringList 0072 // { 0073 // return value << number.number(); 0074 // }); 0075 // }().join(",") 0076 // }, 0077 {FMH::MODEL_KEY::PHOTO, adr.photo().url()}}; 0078 0079 file.close(); 0080 return res; 0081 } 0082 0083 void LinuxInterface::getContacts() 0084 { 0085 // QDirIterator it(this->path, {"*.vcf"}, QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); 0086 0087 // while(it.hasNext()) 0088 // this->m_contacts << 0089 0090 KPeople::PersonsModel model; 0091 for (auto i = 0; i < model.rowCount(); i++) { 0092 const auto uri = model.get(i, KPeople::PersonsModel::PersonUriRole).toString(); 0093 0094 KPeople::PersonData person(uri); 0095 QMultiHash contact = FMH::MODEL { 0096 {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()}, 0097 // {FMH::MODEL_KEY::PHOTO, person.pictureUrl().toString()} 0098 }; 0099 this->m_contacts << contact.unite(vCardData(QString(uri).replace("vcard:/", ""))); 0100 } 0101 0102 emit this->contactsReady(this->m_contacts); 0103 } 0104 0105 FMH::MODEL LinuxInterface::getContact(const QString &id) 0106 { 0107 FMH::MODEL res; 0108 auto personUri = id; 0109 0110 if (!(QUrl(personUri).scheme() == "vcard")) { 0111 qWarning() << "uri of contact is not a vcard, cannot get contact."; 0112 return res; 0113 } 0114 return vCardData(personUri.remove("vcard:/")); 0115 } 0116 0117 bool LinuxInterface::insertContact(const FMH::MODEL &contact) 0118 { 0119 qDebug() << "TRYIN TO INSERT VACRD CONTACT" << contact; 0120 // addresses 0121 Addressee adr; 0122 adr.setName(contact[FMH::MODEL_KEY::N]); 0123 // adr.setUid(contact[FMH::MODEL_KEY::ID]); 0124 adr.setUrl(contact[FMH::MODEL_KEY::URL]); 0125 adr.setNote(contact[FMH::MODEL_KEY::NOTE]); 0126 adr.setTitle(contact[FMH::MODEL_KEY::TITLE]); 0127 adr.setOrganization(contact[FMH::MODEL_KEY::ORG]); 0128 adr.setGender(contact[FMH::MODEL_KEY::GENDER]); 0129 0130 adr.setCustoms({QString("%1:%2").arg(FMH::MODEL_NAME[FMH::MODEL_KEY::FAV], contact[FMH::MODEL_KEY::FAV])}); 0131 0132 Email email; 0133 email.setEmail(contact[FMH::MODEL_KEY::EMAIL]); 0134 adr.setEmailList({email}); 0135 0136 Picture photo; 0137 photo.setUrl(contact[FMH::MODEL_KEY::PHOTO]); 0138 adr.setPhoto(photo); 0139 0140 PhoneNumber phoneNum; 0141 phoneNum.setNumber(contact[FMH::MODEL_KEY::TEL]); 0142 phoneNum.setType(PhoneNumber::Cell); 0143 adr.setPhoneNumbers({phoneNum}); 0144 0145 // create vcard 0146 VCardConverter converter; 0147 QByteArray vcard = converter.createVCard(adr); 0148 qDebug() << vcard; 0149 0150 // save vcard 0151 QCryptographicHash hash(QCryptographicHash::Sha1); 0152 hash.addData(adr.name().toUtf8()); 0153 QFile file(this->path + "/" + hash.result().toHex() + ".vcf"); 0154 0155 if (!file.open(QFile::WriteOnly)) { 0156 qWarning() << "Couldn't save vCard: Couldn't open file for writing."; 0157 return false; 0158 } 0159 0160 file.write(vcard.data(), vcard.length()); 0161 file.close(); 0162 0163 return true; 0164 } 0165 0166 bool LinuxInterface::updateContact(const QString &id, const FMH::MODEL &contact) 0167 { 0168 auto personUri = id; 0169 0170 if (!(QUrl(personUri).scheme() == "vcard")) { 0171 qWarning() << "uri of contact to update is not a vcard, cannot update."; 0172 return false; 0173 } 0174 0175 QFile file(personUri.remove("vcard:/")); 0176 if (!(file.exists())) { 0177 qWarning() << "Can't read vcard, file doesn't exist"; 0178 return false; 0179 } 0180 if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) { 0181 qWarning() << "Couldn't update vCard: Couldn't open file for reading / writing."; 0182 return false; 0183 } 0184 0185 VCardConverter converter; 0186 Addressee adr = converter.parseVCard(file.readAll()); 0187 0188 for (const auto &key : contact.keys()) { 0189 const auto data = contact[key]; 0190 qDebug() << "updating filed:" << key << data; 0191 switch (key) { 0192 case FMH::MODEL_KEY::N: { 0193 if (!data.isEmpty()) 0194 adr.setName(data); 0195 break; 0196 } 0197 0198 case FMH::MODEL_KEY::TEL: { 0199 PhoneNumber::List phoneNums; 0200 PhoneNumber phoneNum; 0201 phoneNum.setNumber(data); 0202 phoneNum.setType(PhoneNumber::Cell); 0203 phoneNums.append(phoneNum); 0204 adr.setPhoneNumbers(phoneNums); 0205 break; 0206 } 0207 0208 case FMH::MODEL_KEY::ORG: { 0209 adr.setOrganization(data); 0210 break; 0211 } 0212 0213 case FMH::MODEL_KEY::TITLE: { 0214 adr.setTitle(data); 0215 break; 0216 } 0217 0218 case FMH::MODEL_KEY::FAV: { 0219 adr.setCustoms({QString("%1:%2").arg(FMH::MODEL_NAME[FMH::MODEL_KEY::FAV], data)}); 0220 break; 0221 } 0222 0223 case FMH::MODEL_KEY::EMAIL: { 0224 Email email; 0225 email.setEmail(data); 0226 adr.setEmailList({email}); 0227 break; 0228 } 0229 0230 case FMH::MODEL_KEY::NOTE: { 0231 adr.setNote(data); 0232 break; 0233 } 0234 0235 case FMH::MODEL_KEY::GENDER: { 0236 adr.setGender(data); 0237 break; 0238 } 0239 0240 case FMH::MODEL_KEY::PHOTO: { 0241 Picture photo; 0242 photo.setUrl(data); 0243 adr.setPhoto(photo); 0244 break; 0245 } 0246 0247 case FMH::MODEL_KEY::URL: { 0248 adr.setUrl(data); 0249 break; 0250 } 0251 0252 default: 0253 break; 0254 } 0255 } 0256 0257 QByteArray vcard = converter.createVCard(adr); 0258 qDebug() << vcard; 0259 0260 file.write(vcard); 0261 file.close(); 0262 return true; 0263 } 0264 0265 bool LinuxInterface::removeContact(const QString &id) 0266 { 0267 if (!(QUrl(id).scheme() == "vcard")) { 0268 qWarning() << "uri of contact to remove is not a vcard, cannot remove."; 0269 return false; 0270 } 0271 0272 return QFile::remove(QString(id).remove("vcard:/")); 0273 } 0274 0275 QImage LinuxInterface::contactPhoto(const QString &id) 0276 { 0277 auto personUri = id; 0278 0279 if (!(QUrl(personUri).scheme() == "vcard")) { 0280 qWarning() << "uri of contact is not a vcard, cannot get photo."; 0281 return QImage(); 0282 } 0283 0284 QFileInfo file(personUri.remove("vcard:/")); 0285 if (!(file.exists())) { 0286 qWarning() << "Can't read vcard, file doesn't exist"; 0287 return QImage(); 0288 } 0289 0290 qDebug() << "IMAGE FILE REQUESTED" << vCardData(personUri)[FMH::MODEL_KEY::PHOTO]; 0291 return QImage(vCardData(personUri)[FMH::MODEL_KEY::PHOTO].replace("file://", "")); 0292 }