File indexing completed on 2025-01-05 04:29:54

0001 /**
0002  * SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #pragma once
0008 
0009 #include <utility>
0010 
0011 #include <QHash>
0012 #include <QObject>
0013 #include <QStringList>
0014 
0015 #include <KJob>
0016 
0017 #include "error.h"
0018 #include "sync/syncutils.h"
0019 
0020 class GPodder;
0021 
0022 class SyncJob : public KJob
0023 {
0024     Q_OBJECT
0025 
0026 public:
0027     enum SyncJobError {
0028         SubscriptionDownloadError = KJob::UserDefinedError,
0029         SubscriptionUploadError,
0030         EpisodeDownloadError,
0031         EpisodeUploadError,
0032         InternalDataError,
0033     };
0034 
0035     enum SyncJobStatus {
0036         Started = 0,
0037         SubscriptionDownload,
0038         SubscriptionUpload,
0039         EpisodeDownload,
0040         ApplyEpisodeActions,
0041         EpisodeUpload,
0042         SubscriptionFetch,
0043         Finished,
0044         Aborted,
0045         Error,
0046     };
0047 
0048     SyncJob(SyncUtils::SyncStatus syncStatus, GPodder *gpodder, const QString &device, bool forceFetchAll, QObject *parent);
0049 
0050     void start() override;
0051     void abort();
0052 
0053     bool aborted();
0054     QString errorString() const override;
0055 
0056 Q_SIGNALS:
0057     void aborting();
0058 
0059 private:
0060     void doSync();
0061 
0062     void doRegularSync(); // regular sync; can be forced to update all feeds
0063     void doForceSync(); // force a full re-sync with the server; discarding local eposide acions
0064     void doQuickSync(); // only upload pending local episode actions; intended to be run directly after an episode action has been created
0065 
0066     void syncSubscriptions();
0067     void uploadSubscriptions(const QStringList &localAddFeedUrlList, const QStringList &localRemoveFeedUrlList);
0068     void fetchModifiedSubscriptions();
0069     void fetchRemoteEpisodeActions();
0070     void syncEpisodeStates();
0071     void uploadEpisodeActions(const QVector<SyncUtils::EpisodeAction> &episodeActions);
0072     void uploadEpisodeActionsPartial(const QVector<SyncUtils::EpisodeAction> &episodeActionList, const int startIndex);
0073     void updateDBTimestamp(const qulonglong &timestamp, const QString &timestampLabel);
0074 
0075     void removeAppliedSubscriptionChangesFromDB();
0076     void removeAppliedEpisodeActionsFromDB();
0077 
0078     std::pair<QStringList, QStringList> getLocalSubscriptionChanges() const; // First list are additions, second are removals
0079     QVector<SyncUtils::EpisodeAction> getLocalEpisodeActions() const;
0080 
0081     void removeSubscriptionChangeConflicts(QStringList &addList, QStringList &removeList);
0082     QVector<SyncUtils::EpisodeAction> createListFromHash(const QHash<QString, QHash<QString, SyncUtils::EpisodeAction>> &episodeActionHash);
0083     void addToHashIfNewer(QHash<QString, QHash<QString, SyncUtils::EpisodeAction>> &episodeActionHash, const SyncUtils::EpisodeAction &episodeAction);
0084     void removeEpisodeActionConflicts(QHash<QString, QHash<QString, SyncUtils::EpisodeAction>> &local,
0085                                       QHash<QString, QHash<QString, SyncUtils::EpisodeAction>> &remote);
0086     QStringList getFeedsFromHash(const QHash<QString, QHash<QString, SyncUtils::EpisodeAction>> &hash);
0087     void debugEpisodeActionHash(const QHash<QString, QHash<QString, SyncUtils::EpisodeAction>> &hash);
0088 
0089     SyncUtils::SyncStatus m_syncStatus = SyncUtils::SyncStatus::NoSync;
0090     GPodder *m_gpodder = nullptr;
0091     QString m_device;
0092     bool m_forceFetchAll = false;
0093     bool m_abort = false;
0094 
0095     // internal variables used while syncing
0096     QStringList m_feedsToBeUpdatedSubs;
0097     QStringList m_feedsToBeUpdatedEps;
0098     int m_feedUpdateProgress = 0;
0099     int m_feedUpdateTotal = 0;
0100     std::pair<QStringList, QStringList> m_localSubscriptionChanges;
0101     QVector<SyncUtils::EpisodeAction> m_localEpisodeActions;
0102     QHash<QString, QHash<QString, SyncUtils::EpisodeAction>> m_remoteEpisodeActionHash;
0103 
0104     // needed for UI notifications
0105     QString getProgressMessage(SyncJobStatus status) const;
0106 };