diff --git a/src/core/message.cpp b/src/core/message.cpp index 0338a5477..6c8833400 100755 --- a/src/core/message.cpp +++ b/src/core/message.cpp @@ -61,7 +61,7 @@ QString Enclosures::encodeEnclosuresToString(const QList &enclosures) } Message::Message() { - m_title = m_url = m_author = m_contents = m_customId = ""; - m_feedId = 0; + m_title = m_url = m_author = m_contents = m_feedId = m_customId = ""; m_enclosures = QList(); + m_isImportant = m_isImportant = false; } diff --git a/src/core/message.h b/src/core/message.h index f0cd4ab3b..eab142d15 100755 --- a/src/core/message.h +++ b/src/core/message.h @@ -49,9 +49,12 @@ class Message { QString m_author; QString m_contents; QDateTime m_created; - int m_feedId; + QString m_feedId; QString m_customId; + bool m_isRead; + bool m_isImportant; + QList m_enclosures; // Is true if "created" date was obtained directly diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp index 62af8ae12..ba0968bbe 100755 --- a/src/core/messagesmodel.cpp +++ b/src/core/messagesmodel.cpp @@ -139,7 +139,8 @@ Message MessagesModel::messageAt(int row_index) const { message.m_enclosures = Enclosures::decodeEnclosuresFromString(rec.value(MSG_DB_ENCLOSURES_INDEX).toString()); message.m_title = rec.value(MSG_DB_TITLE_INDEX).toString(); message.m_url = rec.value(MSG_DB_URL_INDEX).toString(); - message.m_feedId = rec.value(MSG_DB_FEED_INDEX).toInt(); + message.m_feedId = rec.value(MSG_DB_FEED_INDEX).toString(); + message.m_customId = rec.value(MSG_DB_CUSTOM_ID_INDEX).toString(); message.m_created = TextFactory::parseDateTime(rec.value(MSG_DB_DCREATED_INDEX).value()).toLocalTime(); return message; diff --git a/src/services/abstract/feed.h b/src/services/abstract/feed.h index 0ab9671e5..aaed9266a 100755 --- a/src/services/abstract/feed.h +++ b/src/services/abstract/feed.h @@ -55,6 +55,7 @@ class Feed : public RootItem { ///////////////////////////////////////// // Performs synchronous update and returns number of newly updated messages. + // NOTE: This is called from worker thread, not from main UI thread. // NOTE: This should COMPLETELY download ALL messages from online source // into locale "Messages" table, INCLUDING contents (or excerpts) of those // messages. diff --git a/src/services/tt-rss/definitions.h b/src/services/tt-rss/definitions.h index 6aae31bea..391188c76 100755 --- a/src/services/tt-rss/definitions.h +++ b/src/services/tt-rss/definitions.h @@ -11,6 +11,9 @@ #define UNKNOWN_METHOD "UNKNOWN_METHOD" // Given "op" is not recognized. #define INCORRECT_USAGE "INCORRECT_USAGE" // Given "op" was used with bad parameters. +// Limitations +#define MAX_MESSAGES 200 + // General return status codes. #define API_STATUS_OK 0 #define API_STATUS_ERR 1 diff --git a/src/services/tt-rss/network/ttrssnetworkfactory.cpp b/src/services/tt-rss/network/ttrssnetworkfactory.cpp index 5dcfb7b8b..4d5c8ec03 100755 --- a/src/services/tt-rss/network/ttrssnetworkfactory.cpp +++ b/src/services/tt-rss/network/ttrssnetworkfactory.cpp @@ -24,6 +24,7 @@ #include "services/tt-rss/ttrsscategory.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" +#include "miscellaneous/textfactory.h" #include "network-web/networkfactory.h" #include @@ -133,6 +134,37 @@ TtRssGetFeedsCategoriesResponse TtRssNetworkFactory::getFeedsCategories(QNetwork return result; } +TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, bool force_update, int limit, int skip, + bool show_content, bool include_attachments, + bool sanitize, QNetworkReply::NetworkError &error) { + QtJson::JsonObject json; + json["op"] = "getHeadlines"; + json["sid"] = m_sessionId; + json["feed_id"] = feed_id; + json["force_update"] = force_update; + json["limit"] = limit; + json["skip"] = skip; + json["show_content"] = show_content; + json["include_attachments"] = include_attachments; + json["sanitize"] = sanitize; + + QByteArray result_raw; + NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw); + TtRssGetHeadlinesResponse result(QString::fromUtf8(result_raw)); + + if (result.isNotLoggedIn()) { + // We are not logged in. + login(error); + json["sid"] = m_sessionId; + + network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw); + result = TtRssGetHeadlinesResponse(QString::fromUtf8(result_raw)); + } + + error = network_reply.first; + return result; +} + TtRssResponse::TtRssResponse(const QString &raw_content) { m_rawContent = QtJson::parse(raw_content).toMap(); } @@ -296,3 +328,46 @@ RootItem *TtRssGetFeedsCategoriesResponse::feedsCategories(bool obtain_icons, QS return parent; } + + +TtRssGetHeadlinesResponse::TtRssGetHeadlinesResponse(const QString &raw_content) : TtRssResponse(raw_content) { +} + +TtRssGetHeadlinesResponse::~TtRssGetHeadlinesResponse() { +} + +QList TtRssGetHeadlinesResponse::messages() { + QList messages; + + foreach (QVariant item, m_rawContent["content"].toList()) { + QMap mapped = item.toMap(); + Message message; + + message.m_author = mapped["author"].toString(); + message.m_isRead = !mapped["unread"].toBool(); + message.m_isImportant = mapped["marked"].toBool(); + message.m_contents = mapped["content"].toString(); + message.m_created = TextFactory::parseDateTime(mapped["updated"].value()); + message.m_createdFromFeed = true; + message.m_customId = mapped["id"].toString(); + message.m_feedId = mapped["feed_id"].toString(); + message.m_title = mapped["title"].toString(); + message.m_url = mapped["link"].toString(); + + if (mapped.contains(QSL("attachments"))) { + // Process enclosures. + foreach (QVariant attachment, mapped["attachments"].toList()) { + QMap mapped_attachemnt = attachment.toMap(); + Enclosure enclosure; + + enclosure.m_mimeType = mapped_attachemnt["content_type"].toString(); + enclosure.m_url = mapped_attachemnt["content_url"].toString(); + message.m_enclosures.append(enclosure); + } + } + + messages.append(message); + } + + return messages; +} diff --git a/src/services/tt-rss/network/ttrssnetworkfactory.h b/src/services/tt-rss/network/ttrssnetworkfactory.h index 8e76f3b09..8d9374f20 100755 --- a/src/services/tt-rss/network/ttrssnetworkfactory.h +++ b/src/services/tt-rss/network/ttrssnetworkfactory.h @@ -20,6 +20,8 @@ #include "qt-json/json.h" +#include "core/message.h" + #include #include #include @@ -64,6 +66,14 @@ class TtRssGetFeedsCategoriesResponse : public TtRssResponse { RootItem *feedsCategories(bool obtain_icons, QString base_address = QString()); }; +class TtRssGetHeadlinesResponse : public TtRssResponse { + public: + explicit TtRssGetHeadlinesResponse(const QString &raw_content = QString()); + virtual ~TtRssGetHeadlinesResponse(); + + QList messages(); +}; + class TtRssNetworkFactory { public: explicit TtRssNetworkFactory(); @@ -89,6 +99,11 @@ class TtRssNetworkFactory { // Gets feeds from the server. TtRssGetFeedsCategoriesResponse getFeedsCategories(QNetworkReply::NetworkError &error); + // Gets headlines (messages) from the server. + TtRssGetHeadlinesResponse getHeadlines(int feed_id, bool force_update, int limit, int skip, + bool show_content, bool include_attachments, + bool sanitize, QNetworkReply::NetworkError &error); + private: QString m_url; QString m_username; diff --git a/src/services/tt-rss/ttrssfeed.cpp b/src/services/tt-rss/ttrssfeed.cpp index 849b67ace..7a8c64383 100755 --- a/src/services/tt-rss/ttrssfeed.cpp +++ b/src/services/tt-rss/ttrssfeed.cpp @@ -22,7 +22,9 @@ #include "miscellaneous/databasefactory.h" #include "miscellaneous/iconfactory.h" #include "miscellaneous/textfactory.h" +#include "services/tt-rss/definitions.h" #include "services/tt-rss/ttrssserviceroot.h" +#include "services/tt-rss/network/ttrssnetworkfactory.h" #include @@ -83,7 +85,30 @@ int TtRssFeed::countOfUnreadMessages() { int TtRssFeed::update() { // TODO: přes getHeadlines provede stažení kompletnich zprav. - return 0; + QNetworkReply::NetworkError error; + QList messages; + int newly_added_messages = 0; + int limit = MAX_MESSAGES; + int skip = 0; + + do { + TtRssGetHeadlinesResponse headlines = serviceRoot()->network()->getHeadlines(customId(), true, limit, skip, + true, true, false, error); + + if (error != QNetworkReply::NoError) { + setStatus(Feed::NetworkError); + return 0; + } + else { + QList new_messages = headlines.messages(); + + messages.append(new_messages); + skip += new_messages.size(); + } + } + while (newly_added_messages > 0); + + return updateMessages(messages); } QList TtRssFeed::undeletedMessages() const { @@ -92,7 +117,7 @@ QList TtRssFeed::undeletedMessages() const { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); QSqlQuery query_read_msg(database); query_read_msg.setForwardOnly(true); - query_read_msg.prepare("SELECT title, url, author, date_created, contents, enclosures " + query_read_msg.prepare("SELECT title, url, author, date_created, contents, enclosures, custom_id " "FROM Messages " "WHERE is_deleted = 0 AND feed = :feed AND account_id = :account_id;"); @@ -105,13 +130,14 @@ QList TtRssFeed::undeletedMessages() const { while (query_read_msg.next()) { Message message; - message.m_feedId = account_id; + message.m_feedId = QString::number(account_id); message.m_title = query_read_msg.value(0).toString(); message.m_url = query_read_msg.value(1).toString(); message.m_author = query_read_msg.value(2).toString(); message.m_created = TextFactory::parseDateTime(query_read_msg.value(3).value()); message.m_contents = query_read_msg.value(4).toString(); message.m_enclosures = Enclosures::decodeEnclosuresFromString(query_read_msg.value(5).toString()); + message.m_customId = query_read_msg.value(6).toString(); messages.append(message); } @@ -127,3 +153,7 @@ int TtRssFeed::customId() const { void TtRssFeed::setCustomId(int custom_id) { m_customId = custom_id; } + +int TtRssFeed::updateMessages(const QList &messages) { + return 0; +} diff --git a/src/services/tt-rss/ttrssfeed.h b/src/services/tt-rss/ttrssfeed.h index a934f9743..92fae6ef2 100755 --- a/src/services/tt-rss/ttrssfeed.h +++ b/src/services/tt-rss/ttrssfeed.h @@ -45,6 +45,8 @@ class TtRssFeed : public Feed { void setCustomId(int custom_id); private: + int updateMessages(const QList &messages); + int m_customId; int m_totalCount; int m_unreadCount;