File indexing completed on 2024-11-17 04:44:59
0001 /* 0002 SPDX-FileCopyrightText: 2015-2020 Krzysztof Nowicki <krissn@op.pl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <QQueue> 0010 #include <QScopedPointer> 0011 0012 #include <Akonadi/ResourceBase> 0013 #include <Akonadi/TransportResourceBase> 0014 0015 #include "ewsclient.h" 0016 #include "ewsfetchitemsjob.h" 0017 #include "ewsid.h" 0018 0019 #include <ewsconfig.h> 0020 0021 class FetchItemState; 0022 class EwsAbstractAuth; 0023 class EwsSubscriptionManager; 0024 class EwsTagStore; 0025 class EwsSettings; 0026 class KNotification; 0027 0028 class EwsResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::ObserverV4, public Akonadi::TransportResourceBase 0029 { 0030 Q_OBJECT 0031 Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.Ews.Resource") 0032 public: 0033 static const QString akonadiEwsPropsetUuid; 0034 static const EwsPropertyField globalTagsProperty; 0035 static const EwsPropertyField globalTagsVersionProperty; 0036 static const EwsPropertyField tagsProperty; 0037 static const EwsPropertyField flagsProperty; 0038 0039 explicit EwsResource(const QString &id); 0040 ~EwsResource() override; 0041 0042 void itemsTagsChanged(const Akonadi::Item::List &items, const QSet<Akonadi::Tag> &addedTags, const QSet<Akonadi::Tag> &removedTags) override; 0043 void tagAdded(const Akonadi::Tag &tag) override; 0044 void tagChanged(const Akonadi::Tag &tag) override; 0045 void tagRemoved(const Akonadi::Tag &tag) override; 0046 0047 void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) override; 0048 void collectionMoved(const Akonadi::Collection &collection, 0049 const Akonadi::Collection &collectionSource, 0050 const Akonadi::Collection &collectionDestination) override; 0051 void collectionChanged(const Akonadi::Collection &collection, const QSet<QByteArray> &changedAttributes) override; 0052 void collectionChanged(const Akonadi::Collection &collection) override; 0053 void collectionRemoved(const Akonadi::Collection &collection) override; 0054 void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) override; 0055 void itemChanged(const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers) override; 0056 void itemsFlagsChanged(const Akonadi::Item::List &items, const QSet<QByteArray> &addedFlags, const QSet<QByteArray> &removedFlags) override; 0057 void itemsMoved(const Akonadi::Item::List &items, const Akonadi::Collection &sourceCollection, const Akonadi::Collection &destinationCollection) override; 0058 void itemsRemoved(const Akonadi::Item::List &items) override; 0059 0060 void sendItem(const Akonadi::Item &item) override; 0061 0062 const Akonadi::Collection &rootCollection() const 0063 { 0064 return mRootCollection; 0065 } 0066 0067 EwsSettings *settings() 0068 { 0069 return mSettings.data(); 0070 } 0071 0072 protected: 0073 void doSetOnline(bool online) override; 0074 public Q_SLOTS: 0075 void configure(WId windowId) override; 0076 Q_SCRIPTABLE void clearCollectionSyncState(int collectionId); 0077 Q_SCRIPTABLE void clearFolderTreeSyncState(); 0078 Q_SCRIPTABLE void setInitialReconnectTimeout(int timeout); 0079 protected Q_SLOTS: 0080 void retrieveCollections() override; 0081 void retrieveItems(const Akonadi::Collection &collection) override; 0082 bool retrieveItems(const Akonadi::Item::List &items, const QSet<QByteArray> &parts) override; 0083 void retrieveTags() override; 0084 QString dumpResourceToString() const override; 0085 private Q_SLOTS: 0086 void fetchFoldersJobFinished(KJob *job); 0087 void fetchFoldersIncrJobFinished(KJob *job); 0088 void itemFetchJobFinished(KJob *job); 0089 void getItemsRequestFinished(KJob *job); 0090 void itemChangeRequestFinished(KJob *job); 0091 void itemModifyFlagsRequestFinished(KJob *job); 0092 void itemMoveRequestFinished(KJob *job); 0093 void itemDeleteRequestFinished(KJob *job); 0094 void itemCreateRequestFinished(KJob *job); 0095 void itemSendRequestFinished(KJob *job); 0096 void folderCreateRequestFinished(KJob *job); 0097 void folderMoveRequestFinished(KJob *job); 0098 void folderUpdateRequestFinished(KJob *job); 0099 void folderDeleteRequestFinished(KJob *job); 0100 void delayedInit(); 0101 void foldersModifiedEvent(const EwsId::List &folders); 0102 void foldersModifiedCollectionSyncFinished(KJob *job); 0103 void folderTreeModifiedEvent(); 0104 void fullSyncRequestedEvent(); 0105 void rootFolderFetchFinished(KJob *job); 0106 void specialFoldersFetchFinished(KJob *job); 0107 void itemsTagChangeFinished(KJob *job); 0108 void globalTagChangeFinished(KJob *job); 0109 void globalTagsRetrievalFinished(KJob *job); 0110 void adjustInboxRemoteIdFetchFinished(KJob *job); 0111 void rootCollectionFetched(KJob *job); 0112 void connectionError(); 0113 void reloadConfig(); 0114 void authSucceeded(); 0115 void authFailed(const QString &error); 0116 void requestAuthFailed(); 0117 void emitReadyStatus(); 0118 void adjustRootCollectionName(const QString &newName); 0119 public Q_SLOTS: 0120 Q_SCRIPTABLE void sendMessage(const QString &id, const QByteArray &content); 0121 Q_SIGNALS: 0122 Q_SCRIPTABLE void messageSent(const QString &id, const QString &error); 0123 #if HAVE_SEPARATE_MTA_RESOURCE 0124 private Q_SLOTS: 0125 void messageSendRequestFinished(KJob *job); 0126 #endif 0127 0128 private: 0129 enum AuthStage { AuthIdle, AuthRefreshToken, AuthAccessToken, AuthFailure }; 0130 0131 enum QueuedFetchItemsJobType { RetrieveItems, SubscriptionSync }; 0132 0133 void finishItemsFetch(FetchItemState *state); 0134 void fetchSpecialFolders(); 0135 void specialFoldersCollectionsRetrieved(const Akonadi::Collection::List &folders); 0136 0137 void saveState(); 0138 void resetUrl(); 0139 0140 void doRetrieveCollections(); 0141 0142 int reconnectTimeout(); 0143 void setUpAuth(); 0144 void reauthNotificationDismissed(bool accepted); 0145 void reauthenticate(); 0146 0147 static QString getCollectionSyncState(const Akonadi::Collection &col); 0148 static void saveCollectionSyncState(Akonadi::Collection &col, const QString &state); 0149 0150 void queueFetchItemsJob(const Akonadi::Collection &col, QueuedFetchItemsJobType type, const std::function<void(EwsFetchItemsJob *)> &startFn); 0151 void startFetchItemsJob(const Akonadi::Collection &col, std::function<void(EwsFetchItemsJob *)> startFn); 0152 void dequeueFetchItemsJob(); 0153 0154 template<class Job> 0155 void connectStatusSignals(Job *job); 0156 0157 EwsClient mEwsClient; 0158 Akonadi::Collection mRootCollection; 0159 QScopedPointer<EwsSubscriptionManager> mSubManager; 0160 QString mFolderSyncState; 0161 QHash<QString, EwsId::List> mItemsToCheck; 0162 QString mPassword; 0163 QScopedPointer<EwsAbstractAuth> mAuth; 0164 AuthStage mAuthStage; 0165 QPointer<KNotification> mReauthNotification; 0166 0167 bool mTagsRetrieved = false; 0168 int mReconnectTimeout; 0169 int mInitialReconnectTimeout; 0170 EwsTagStore *mTagStore = nullptr; 0171 QScopedPointer<EwsSettings> mSettings; 0172 0173 struct QueuedFetchItemsJob { 0174 Akonadi::Collection col; 0175 QueuedFetchItemsJobType type; 0176 std::function<void(EwsFetchItemsJob *)> startFn; 0177 }; 0178 QQueue<QueuedFetchItemsJob> mFetchItemsJobQueue; 0179 };