File indexing completed on 2025-02-16 04:50:13
0001 /* 0002 SPDX-FileCopyrightText: 2023 Claudio Cambra <claudio.cambra@kde.org> 0003 SPDX-License-Identifier: GPL-3.0-or-later 0004 */ 0005 0006 #include "peopleconversionjob.h" 0007 0008 #include <Akonadi/CollectionFetchJob> 0009 0010 #include <KContacts/Addressee> 0011 0012 #include <KGAPI/People/ContactGroupMembership> 0013 #include <KGAPI/People/Membership> 0014 0015 #include "googlepeople_debug.h" 0016 0017 using namespace Akonadi; 0018 using namespace KGAPI2; 0019 0020 PeopleConversionJob::PeopleConversionJob(const Item::List &peopleItems, QObject *parent) 0021 : QObject(parent) 0022 , m_items(peopleItems) 0023 { 0024 } 0025 0026 People::PersonList PeopleConversionJob::people() const 0027 { 0028 return m_processedPeople; 0029 } 0030 0031 QString PeopleConversionJob::reparentCollectionRemoteId() const 0032 { 0033 return m_reparentCollectionRemoteId; 0034 } 0035 0036 void PeopleConversionJob::setReparentCollectionRemoteId(const QString &reparentCollectionRemoteId) 0037 { 0038 if (reparentCollectionRemoteId == m_reparentCollectionRemoteId) { 0039 return; 0040 } 0041 0042 m_reparentCollectionRemoteId = reparentCollectionRemoteId; 0043 Q_EMIT reparentCollectionRemoteIdChanged(); 0044 } 0045 0046 QString PeopleConversionJob::newLinkedCollectionRemoteId() const 0047 { 0048 return m_newLinkedCollectionRemoteId; 0049 } 0050 0051 void PeopleConversionJob::setNewLinkedCollectionRemoteId(const QString &newLinkedCollectionRemoteId) 0052 { 0053 if (newLinkedCollectionRemoteId == m_newLinkedCollectionRemoteId) { 0054 return; 0055 } 0056 0057 m_newLinkedCollectionRemoteId = newLinkedCollectionRemoteId; 0058 Q_EMIT newLinkedCollectionRemoteIdChanged(); 0059 } 0060 0061 QString PeopleConversionJob::linkedCollectionToRemoveRemoteId() const 0062 { 0063 return m_linkedCollectionToRemoveRemoteId; 0064 } 0065 0066 void PeopleConversionJob::setLinkedCollectionToRemoveRemoteId(const QString &linkedCollectionToRemoveRemoteId) 0067 { 0068 if (linkedCollectionToRemoveRemoteId == m_linkedCollectionToRemoveRemoteId) { 0069 return; 0070 } 0071 0072 m_linkedCollectionToRemoveRemoteId = linkedCollectionToRemoveRemoteId; 0073 Q_EMIT linkedCollectionToRemoveRemoteIdChanged(); 0074 } 0075 0076 void PeopleConversionJob::start() 0077 { 0078 if (m_items.isEmpty()) { 0079 qCDebug(GOOGLE_PEOPLE_LOG) << "No person items to process, finishing."; 0080 Q_EMIT finished(); 0081 return; 0082 } 0083 0084 m_processedPeople.clear(); 0085 0086 QSet<Collection::Id> collectionsToFetch; 0087 for (const auto &item : std::as_const(m_items)) { 0088 const auto itemVirtualReferences = item.virtualReferences(); 0089 for (const auto &collection : itemVirtualReferences) { 0090 const auto collectionId = collection.id(); 0091 qCDebug(GOOGLE_PEOPLE_LOG) << "Going to fetch data for virtual collection:" << collectionId; 0092 collectionsToFetch.insert(collectionId); 0093 }; 0094 } 0095 0096 if (collectionsToFetch.isEmpty()) { 0097 qCDebug(GOOGLE_PEOPLE_LOG) << "No virtual collections to fetch, processing people now."; 0098 processItems(); 0099 return; 0100 } 0101 0102 qCDebug(GOOGLE_PEOPLE_LOG) << "Going to fetch data for virtual collections now."; 0103 const QList<Collection::Id> idList(collectionsToFetch.cbegin(), collectionsToFetch.cend()); 0104 auto collectionRetrievalJob = new CollectionFetchJob(idList); 0105 connect(collectionRetrievalJob, &CollectionFetchJob::finished, this, &PeopleConversionJob::jobFinished); 0106 } 0107 0108 void PeopleConversionJob::jobFinished(KJob *job) 0109 { 0110 if (job->error()) { 0111 qCWarning(GOOGLE_PEOPLE_LOG) << "Virtual collections data fetch ended in error."; 0112 processItems(); 0113 return; 0114 } 0115 0116 qCDebug(GOOGLE_PEOPLE_LOG) << "Processing fetched collections"; 0117 0118 const auto fetchJob = qobject_cast<CollectionFetchJob *>(job); 0119 const auto collections = fetchJob->collections(); 0120 0121 for (const auto &collection : collections) { 0122 qCDebug(GOOGLE_PEOPLE_LOG) << "Fetched data for virtual collection:" << collection.displayName(); 0123 m_localToRemoteIdHash.insert(collection.id(), collection.remoteId()); 0124 } 0125 0126 processItems(); 0127 } 0128 0129 People::Membership PeopleConversionJob::resourceNameToMembership(const QString &resourceName) 0130 { 0131 People::ContactGroupMembership contactGroupMembership; 0132 contactGroupMembership.setContactGroupResourceName(resourceName); 0133 0134 People::Membership membership; 0135 membership.setContactGroupMembership(contactGroupMembership); 0136 0137 return membership; 0138 } 0139 0140 void PeopleConversionJob::processItems() 0141 { 0142 for (const auto &item : std::as_const(m_items)) { 0143 const auto addressee = item.payload<KContacts::Addressee>(); 0144 const auto person = People::Person::fromKContactsAddressee(addressee); 0145 QList<People::Membership> memberships; 0146 0147 person->setResourceName(item.remoteId()); 0148 person->setEtag(item.remoteRevision()); 0149 0150 // TODO: Domain membership? 0151 const auto parentCollectionRemoteId = m_reparentCollectionRemoteId.isEmpty() ? 0152 item.parentCollection().remoteId() : m_reparentCollectionRemoteId; 0153 People::ContactGroupMembership contactGroupMembership; 0154 contactGroupMembership.setContactGroupResourceName(parentCollectionRemoteId); 0155 0156 People::Membership membership; 0157 membership.setContactGroupMembership(contactGroupMembership); 0158 memberships.append(membership); 0159 0160 for (const auto &virtualCollection : item.virtualReferences()) { 0161 0162 const auto virtualCollectionId = virtualCollection.id(); 0163 if (!m_localToRemoteIdHash.contains(virtualCollectionId)) { 0164 qCWarning(GOOGLE_PEOPLE_LOG) << "Fetched virtual collections do not contain collection with ID:" << virtualCollectionId; 0165 continue; 0166 } 0167 0168 const auto retrievedCollectionRemoteId = m_localToRemoteIdHash.value(virtualCollectionId); 0169 if (retrievedCollectionRemoteId == m_linkedCollectionToRemoveRemoteId) { 0170 // Skip adding this membership so it will be removed serverside 0171 continue; 0172 } 0173 0174 const auto existingLinkedMembership = resourceNameToMembership(retrievedCollectionRemoteId); 0175 memberships.append(existingLinkedMembership); 0176 } 0177 0178 if (!m_newLinkedCollectionRemoteId.isEmpty()) { 0179 const auto newLinkedMembership = resourceNameToMembership(m_newLinkedCollectionRemoteId); 0180 memberships.append(newLinkedMembership); 0181 } 0182 0183 person->setMemberships(memberships); 0184 0185 qCDebug(GOOGLE_PEOPLE_LOG) << "Processed person:" << person->resourceName(); 0186 m_processedPeople.append(person); 0187 } 0188 0189 Q_EMIT peopleChanged(); 0190 Q_EMIT finished(); 0191 } 0192 0193 #include "moc_peopleconversionjob.cpp"