diff --git a/resources/scripts/.travis-before-install.sh b/resources/scripts/.travis-before-install.sh index ef9d4a1d8..69cc68582 100755 --- a/resources/scripts/.travis-before-install.sh +++ b/resources/scripts/.travis-before-install.sh @@ -11,7 +11,7 @@ if test "$TRAVIS_OS_NAME" = "osx"; then brew link --force curl else # Linux. - sudo add-apt-repository ppa:beineri/opt-qt59-trusty -y + sudo add-apt-repository ppa:beineri/opt-qt591-trusty -y sudo apt-get update - sudo apt-get -y install qt59tools qt59base qt59webengine qt59networkauth-no-lgpl + sudo apt-get -y install qt59tools qt59base qt59webengine fi \ No newline at end of file diff --git a/src/network-web/oauth2service.cpp b/src/network-web/oauth2service.cpp index 77999630b..8494dbf12 100755 --- a/src/network-web/oauth2service.cpp +++ b/src/network-web/oauth2service.cpp @@ -68,12 +68,13 @@ OAuth2Service::OAuth2Service(QString authUrl, QString tokenUrl, QString clientId connect(this, &OAuth2Service::authCodeObtained, this, &OAuth2Service::retrieveAccessToken); } -QString OAuth2Service::bearer() const { - return QString("Bearer %1").arg(m_accessToken); -} - -void OAuth2Service::attachBearerHeader(QNetworkRequest& req) { - req.setRawHeader(QString("Authorization").toLocal8Bit(), bearer().toLocal8Bit()); +QString OAuth2Service::bearer() { + if (login()) { + return QString("Bearer %1").arg(m_accessToken); + } + else { + return QString(); + } } void OAuth2Service::setOAuthTokenGrantType(QString grant_type) { diff --git a/src/network-web/oauth2service.h b/src/network-web/oauth2service.h index 8bd0e8936..cd27ce41d 100755 --- a/src/network-web/oauth2service.h +++ b/src/network-web/oauth2service.h @@ -52,9 +52,7 @@ class OAuth2Service : public QObject { explicit OAuth2Service(QString authUrl, QString tokenUrl, QString clientId, QString clientSecret, QString scope, QObject* parent = 0); - QString bearer() const; - - void attachBearerHeader(QNetworkRequest& req); + QString bearer(); void setOAuthTokenGrantType(QString grant_type); QString oAuthTokenGrantType(); diff --git a/src/services/abstract/cacheforserviceroot.cpp b/src/services/abstract/cacheforserviceroot.cpp index 8320f3703..5b0dc4ffb 100755 --- a/src/services/abstract/cacheforserviceroot.cpp +++ b/src/services/abstract/cacheforserviceroot.cpp @@ -74,11 +74,11 @@ void CacheForServiceRoot::addMessageStatesToCache(const QStringList& ids_of_mess m_cacheSaveMutex->unlock(); } -void CacheForServiceRoot::saveCacheToFile(int accId) { +void CacheForServiceRoot::saveCacheToFile(int acc_id) { m_cacheSaveMutex->lock(); // Save to file. - const QString file_cache = qApp->userDataFolder() + QDir::separator() + QString::number(accId) + "-cached-msgs.dat"; + const QString file_cache = qApp->userDataFolder() + QDir::separator() + QString::number(acc_id) + "-cached-msgs.dat"; if (isEmpty()) { QFile::remove(file_cache); @@ -105,12 +105,12 @@ void CacheForServiceRoot::clearCache() { m_cachedStatesImportant.clear(); } -void CacheForServiceRoot::loadCacheFromFile(int accId) { +void CacheForServiceRoot::loadCacheFromFile(int acc_id) { m_cacheSaveMutex->lock(); clearCache(); // Load from file. - const QString file_cache = qApp->userDataFolder() + QDir::separator() + QString::number(accId) + "-cached-msgs.dat"; + const QString file_cache = qApp->userDataFolder() + QDir::separator() + QString::number(acc_id) + "-cached-msgs.dat"; QFile file(file_cache); if (file.exists()) { diff --git a/src/services/abstract/cacheforserviceroot.h b/src/services/abstract/cacheforserviceroot.h index 96bc7d502..148027ff8 100755 --- a/src/services/abstract/cacheforserviceroot.h +++ b/src/services/abstract/cacheforserviceroot.h @@ -37,8 +37,10 @@ class CacheForServiceRoot { // Persistently saves/loads cached changes to/from file. // NOTE: The whole cache is cleared after save is done and before load is done. - void saveCacheToFile(int accId); - void loadCacheFromFile(int accId); + void saveCacheToFile(int acc_id); + void loadCacheFromFile(int acc_id); + + virtual void saveAllCachedData() = 0; protected: QPair, QMap>> takeMessageCache(); diff --git a/src/services/inoreader/definitions.h b/src/services/inoreader/definitions.h index ec4753935..1056fa7c1 100755 --- a/src/services/inoreader/definitions.h +++ b/src/services/inoreader/definitions.h @@ -41,5 +41,6 @@ #define INOREADER_API_FEED_CONTENTS "https://www.inoreader.com/reader/api/0/stream/contents" #define INOREADER_API_LIST_LABELS "https://www.inoreader.com/reader/api/0/tag/list" #define INOREADER_API_LIST_FEEDS "https://www.inoreader.com/reader/api/0/subscription/list" +#define INOREADER_API_EDIT_TAG "https://www.inoreader.com/reader/api/0/edit-tag" #endif // INOREADER_DEFINITIONS_H diff --git a/src/services/inoreader/inoreaderserviceroot.cpp b/src/services/inoreader/inoreaderserviceroot.cpp index f27798f35..ce671783e 100755 --- a/src/services/inoreader/inoreaderserviceroot.cpp +++ b/src/services/inoreader/inoreaderserviceroot.cpp @@ -30,7 +30,7 @@ #include "services/inoreader/network/inoreadernetworkfactory.h" InoreaderServiceRoot::InoreaderServiceRoot(InoreaderNetworkFactory* network, RootItem* parent) : ServiceRoot(parent), - m_serviceMenu(QList()), m_network(network) { + CacheForServiceRoot(), m_serviceMenu(QList()), m_network(network) { if (network == nullptr) { m_network = new InoreaderNetworkFactory(this); } @@ -121,6 +121,11 @@ void InoreaderServiceRoot::start(bool freshly_activated) { loadFromDatabase(); m_network->oauth()->login(); + loadCacheFromFile(accountId()); + + if (childCount() <= 1) { + syncIn(); + } } void InoreaderServiceRoot::stop() {} @@ -149,3 +154,39 @@ void InoreaderServiceRoot::addNewFeed(const QString& url) { } void InoreaderServiceRoot::addNewCategory() {} + +void InoreaderServiceRoot::saveAllCachedData() { + QPair, QMap>> msgCache = takeMessageCache(); + QMapIterator i(msgCache.first); + + // Save the actual data read/unread. + while (i.hasNext()) { + i.next(); + auto key = i.key(); + QStringList ids = i.value(); + + if (!ids.isEmpty()) { + network()->markMessagesRead(key, ids); + } + } + + QMapIterator> j(msgCache.second); + + // Save the actual data important/not important. + while (j.hasNext()) { + j.next(); + auto key = j.key(); + + QList messages = j.value(); + + if (!messages.isEmpty()) { + QStringList custom_ids; + + foreach (const Message& msg, messages) { + custom_ids.append(msg.m_customId); + } + + network()->markMessagesStarred(key, custom_ids); + } + } +} diff --git a/src/services/inoreader/inoreaderserviceroot.h b/src/services/inoreader/inoreaderserviceroot.h index 7b56ca9f9..d4be22cc1 100755 --- a/src/services/inoreader/inoreaderserviceroot.h +++ b/src/services/inoreader/inoreaderserviceroot.h @@ -20,11 +20,12 @@ #ifndef INOREADERSERVICEROOT_H #define INOREADERSERVICEROOT_H +#include "services/abstract/cacheforserviceroot.h" #include "services/abstract/serviceroot.h" class InoreaderNetworkFactory; -class InoreaderServiceRoot : public ServiceRoot { +class InoreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot { Q_OBJECT public: @@ -46,6 +47,8 @@ class InoreaderServiceRoot : public ServiceRoot { RootItem* obtainNewTreeForSyncIn() const; + void saveAllCachedData(); + public slots: void addNewFeed(const QString& url); void addNewCategory(); diff --git a/src/services/inoreader/network/inoreadernetworkfactory.cpp b/src/services/inoreader/network/inoreadernetworkfactory.cpp index 9f9a009d1..5c4c5d2da 100755 --- a/src/services/inoreader/network/inoreadernetworkfactory.cpp +++ b/src/services/inoreader/network/inoreadernetworkfactory.cpp @@ -89,8 +89,13 @@ void InoreaderNetworkFactory::setUsername(const QString& username) { RootItem* InoreaderNetworkFactory::feedsCategories(bool obtain_icons) { Downloader downloader; QEventLoop loop; + QString bearer = m_oauth2->bearer().toLocal8Bit(); - downloader.appendRawHeader(QString("Authorization").toLocal8Bit(), m_oauth2->bearer().toLocal8Bit()); + if (bearer.isEmpty()) { + return nullptr; + } + + downloader.appendRawHeader(QString("Authorization").toLocal8Bit(), bearer.toLocal8Bit()); // We need to quit event loop when the download finishes. connect(&downloader, &Downloader::completed, &loop, &QEventLoop::quit); @@ -119,9 +124,14 @@ QList InoreaderNetworkFactory::messages(const QString& stream_id, bool* Downloader downloader; QEventLoop loop; QString target_url = INOREADER_API_FEED_CONTENTS; + QString bearer = m_oauth2->bearer().toLocal8Bit(); + + if (bearer.isEmpty()) { + return QList(); + } target_url += QSL("/") + QUrl::toPercentEncoding(stream_id) + QString("?n=%1").arg(batchSize()); - downloader.appendRawHeader(QString("Authorization").toLocal8Bit(), m_oauth2->bearer().toLocal8Bit()); + downloader.appendRawHeader(QString("Authorization").toLocal8Bit(), bearer.toLocal8Bit()); IOFactory::writeTextFile("aa.bb", target_url.toUtf8()); @@ -141,6 +151,10 @@ QList InoreaderNetworkFactory::messages(const QString& stream_id, bool* } } +void InoreaderNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids) {} + +void InoreaderNetworkFactory::markMessagesStarred(RootItem::Importance importance, const QStringList& custom_ids) {} + QList InoreaderNetworkFactory::decodeMessages(const QString& messages_json_data, const QString& stream_id) { QList messages; QJsonArray json = QJsonDocument::fromJson(messages_json_data.toUtf8()).object()["items"].toArray(); diff --git a/src/services/inoreader/network/inoreadernetworkfactory.h b/src/services/inoreader/network/inoreadernetworkfactory.h index 929a23a09..38f7971ad 100755 --- a/src/services/inoreader/network/inoreadernetworkfactory.h +++ b/src/services/inoreader/network/inoreadernetworkfactory.h @@ -23,6 +23,8 @@ #include "core/message.h" +#include "services/abstract/rootitem.h" + #include class RootItem; @@ -52,6 +54,8 @@ class InoreaderNetworkFactory : public QObject { RootItem* feedsCategories(bool obtain_icons); QList messages(const QString& stream_id, bool* is_error); + void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids); + void markMessagesStarred(RootItem::Importance importance, const QStringList& custom_ids); private: QList decodeMessages(const QString& messages_json_data, const QString& stream_id);