1 // For license of this file, see <project-root-folder>/LICENSE.md.
2 
3 #ifndef GREADERNETWORK_H
4 #define GREADERNETWORK_H
5 
6 #include <QObject>
7 
8 #include "network-web/networkfactory.h"
9 #include "services/abstract/feed.h"
10 #include "services/greader/greaderserviceroot.h"
11 
12 class OAuth2Service;
13 
14 class GreaderNetwork : public QObject {
15   Q_OBJECT
16 
17   public:
18     enum class Operations {
19       ClientLogin,
20       TagList,
21       SubscriptionList,
22       StreamContents,
23       EditTag,
24       Token,
25       UserInfo,
26       ItemIds,
27       ItemContents
28     };
29 
30     explicit GreaderNetwork(QObject* parent = nullptr);
31 
32     // Convenience methods.
33     QNetworkReply::NetworkError markMessagesRead(RootItem::ReadStatus status,
34                                                  const QStringList& msg_custom_ids,
35                                                  const QNetworkProxy& proxy);
36     QNetworkReply::NetworkError markMessagesStarred(RootItem::Importance importance,
37                                                     const QStringList& msg_custom_ids,
38                                                     const QNetworkProxy& proxy);
39 
40     void prepareFeedFetching(GreaderServiceRoot* root,
41                              const QList<Feed*>& feeds,
42                              const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
43                              const QHash<QString, QStringList>& tagged_messages,
44                              const QNetworkProxy& proxy);
45 
46     QList<Message> getMessagesIntelligently(ServiceRoot* root,
47                                             const QString& stream_id,
48                                             const QHash<ServiceRoot::BagOfMessages, QStringList>& stated_messages,
49                                             const QHash<QString, QStringList>& tagged_messages,
50                                             Feed::Status& error,
51                                             const QNetworkProxy& proxy);
52 
53     RootItem* categoriesFeedsLabelsTree(bool obtain_icons, const QNetworkProxy& proxy);
54 
55     void clearCredentials();
56 
57     void clearPrefetchedMessages();
58 
59     GreaderServiceRoot::Service service() const;
60     void setService(GreaderServiceRoot::Service service);
61 
62     QString username() const;
63     void setUsername(const QString& username);
64 
65     QString password() const;
66     void setPassword(const QString& password);
67 
68     QString baseUrl() const;
69     void setBaseUrl(const QString& base_url);
70 
71     int batchSize() const;
72     void setBatchSize(int batch_size);
73 
74     bool downloadOnlyUnreadMessages() const;
75     void setDownloadOnlyUnreadMessages(bool download_only_unread);
76 
77     bool intelligentSynchronization() const;
78     void setIntelligentSynchronization(bool intelligent_synchronization);
79 
80     void setRoot(GreaderServiceRoot* root);
81 
82     OAuth2Service* oauth() const;
83     void setOauth(OAuth2Service* oauth);
84 
85     // API methods.
86     QNetworkReply::NetworkError editLabels(const QString& state, bool assign,
87                                            const QStringList& msg_custom_ids, const QNetworkProxy& proxy);
88     QVariantHash userInfo(const QNetworkProxy& proxy);
89     QStringList itemIds(const QString& stream_id, bool unread_only, const QNetworkProxy& proxy, int max_count = -1,
90                         QDate newer_than = {});
91     QList<Message> itemContents(ServiceRoot* root, const QList<QString>& stream_ids,
92                                 Feed::Status& error, const QNetworkProxy& proxy);
93     QList<Message> streamContents(ServiceRoot* root, const QString& stream_id,
94                                   Feed::Status& error, const QNetworkProxy& proxy);
95     QNetworkReply::NetworkError clientLogin(const QNetworkProxy& proxy);
96 
97     QDate newerThanFilter() const;
98     void setNewerThanFilter(const QDate& newer_than);
99 
100   private slots:
101     void onTokensError(const QString& error, const QString& error_description);
102     void onAuthFailed();
103 
104   private:
105     QPair<QByteArray, QByteArray> authHeader() const;
106 
107     // Make sure we are logged in and if we are not, return error.
108     bool ensureLogin(const QNetworkProxy& proxy, QNetworkReply::NetworkError* output = nullptr);
109 
110     QString convertLongStreamIdToShortStreamId(const QString& stream_id) const;
111     QString convertShortStreamIdToLongStreamId(const QString& stream_id) const;
112     QString simplifyStreamId(const QString& stream_id) const;
113 
114     QStringList decodeItemIds(const QString& stream_json_data, QString& continuation);
115     QList<Message> decodeStreamContents(ServiceRoot* root, const QString& stream_json_data, const QString& stream_id, QString& continuation);
116     RootItem* decodeTagsSubscriptions(const QString& categories, const QString& feeds, bool obtain_icons, const QNetworkProxy& proxy);
117 
118     QString sanitizedBaseUrl() const;
119     QString generateFullUrl(Operations operation) const;
120 
121     void initializeOauth();
122 
123   private:
124     GreaderServiceRoot* m_root;
125     GreaderServiceRoot::Service m_service;
126     QString m_username;
127     QString m_password;
128     QString m_baseUrl;
129     int m_batchSize;
130     bool m_downloadOnlyUnreadMessages;
131     QString m_authSid;
132     QString m_authAuth;
133     QString m_authToken;
134     QList<Message> m_prefetchedMessages;
135     Feed::Status m_prefetchedStatus;
136     bool m_performGlobalFetching;
137     bool m_intelligentSynchronization;
138     QDate m_newerThanFilter;
139     OAuth2Service* m_oauth;
140 };
141 
142 #endif // GREADERNETWORK_H
143