diff --git a/src/services/standard/standardfeed.cpp b/src/services/standard/standardfeed.cpp index c7ea6fecc..2e33f9f57 100755 --- a/src/services/standard/standardfeed.cpp +++ b/src/services/standard/standardfeed.cpp @@ -651,7 +651,7 @@ int StandardFeed::updateMessages(const QList &messages) { if (remove_duplicates) { query_update.setForwardOnly(true); - query_update.prepare(QSL("UPDATE Messages SET contents = :contents enclosures = :enclosures WHERE id = :id;")); + query_update.prepare(QSL("UPDATE Messages SET contents = :contents, enclosures = :enclosures WHERE id = :id;")); } if (!database.transaction()) { @@ -703,7 +703,6 @@ int StandardFeed::updateMessages(const QList &messages) { query_insert.bindValue(QSL(":account_id"), account_id); if (query_insert.exec() && query_insert.numRowsAffected() == 1) { - setStatus(NewMessages); updated_messages++; } @@ -735,7 +734,6 @@ int StandardFeed::updateMessages(const QList &messages) { query_insert.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures)); if (query_insert.exec() && query_insert.numRowsAffected() == 1) { - setStatus(NewMessages); updated_messages++; } @@ -746,6 +744,10 @@ int StandardFeed::updateMessages(const QList &messages) { } } + if (updated_messages > 0) { + setStatus(NewMessages); + } + if (!database.commit()) { database.rollback(); diff --git a/src/services/tt-rss/network/ttrssnetworkfactory.cpp b/src/services/tt-rss/network/ttrssnetworkfactory.cpp index 4d5c8ec03..04b3f02b2 100755 --- a/src/services/tt-rss/network/ttrssnetworkfactory.cpp +++ b/src/services/tt-rss/network/ttrssnetworkfactory.cpp @@ -347,7 +347,10 @@ QList TtRssGetHeadlinesResponse::messages() { 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()); + + // Multiply by 1000 because Tiny Tiny RSS API does not include miliseconds in Unix + // date/time number. + message.m_created = TextFactory::parseDateTime(mapped["updated"].value() * 1000); message.m_createdFromFeed = true; message.m_customId = mapped["id"].toString(); message.m_feedId = mapped["feed_id"].toString(); diff --git a/src/services/tt-rss/ttrssfeed.cpp b/src/services/tt-rss/ttrssfeed.cpp index 8d0b0541b..ef2aa4c91 100755 --- a/src/services/tt-rss/ttrssfeed.cpp +++ b/src/services/tt-rss/ttrssfeed.cpp @@ -75,11 +75,11 @@ void TtRssFeed::updateCounts(bool including_total_count) { } } -int TtRssFeed::countOfAllMessages() { +int TtRssFeed::countOfAllMessages() const { return m_totalCount; } -int TtRssFeed::countOfUnreadMessages() { +int TtRssFeed::countOfUnreadMessages() const { return m_unreadCount; } @@ -155,7 +155,114 @@ void TtRssFeed::setCustomId(int custom_id) { } int TtRssFeed::updateMessages(const QList &messages) { - // TODO: pokračovat tady + if (messages.isEmpty()) { + return 0; + } - return 0; + int feed_id = customId(); + int updated_messages = 0; + QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); + int account_id = serviceRoot()->accountId(); + + // Prepare queries. + QSqlQuery query_insert(database); + QSqlQuery query_select(database); + QSqlQuery query_update(database); + + query_update.setForwardOnly(true); + query_update.prepare("UPDATE Messages " + "SET title = :title, is_read = :is_read, is_important = :is_important, url = :url, author = :author, date_created = :date_created, contents = :contents, enclosures = :enclosures " + "WHERE id = :id;"); + + query_select.setForwardOnly(true); + query_select.prepare("SELECT id, date_created FROM Messages " + "WHERE account_id = :account_id AND custom_id = :custom_id;"); + + // Used to insert new messages. + query_insert.setForwardOnly(true); + query_insert.prepare("INSERT INTO Messages " + "(feed, title, is_read, is_important, url, author, date_created, contents, enclosures, custom_id, account_id) " + "VALUES (:feed, :title, :is_read, :is_important, :url, :author, :date_created, :contents, :enclosures, :custom_id, :account_id);"); + + if (!database.transaction()) { + database.rollback(); + qDebug("Transaction start for message downloader failed."); + return updated_messages; + } + + foreach (Message message, messages) { + query_select.bindValue(QSL(":account_id"), account_id); + query_select.bindValue(QSL(":custom_id"), message.m_customId); + + query_select.exec(); + + int id_existing_message = -1; + qint64 date_existing_message; + + if (query_select.next()) { + id_existing_message = query_select.value(0).toInt(); + date_existing_message = query_select.value(1).value(); + } + + query_select.finish(); + + // Now, check if this message is already in the DB. + if (id_existing_message >= 0) { + if (message.m_created.toMSecsSinceEpoch() != date_existing_message) { + // Message exists, it is changed, update it. + query_update.bindValue(QSL(":title"), message.m_title); + query_update.bindValue(QSL(":is_read"), (int) message.m_isRead); + query_update.bindValue(QSL(":is_important"), (int) message.m_isImportant); + query_update.bindValue(QSL(":url"), message.m_url); + query_update.bindValue(QSL(":author"), message.m_author); + query_update.bindValue(QSL(":date_created"), message.m_created.toMSecsSinceEpoch()); + query_update.bindValue(QSL(":contents"), message.m_contents); + query_update.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures)); + query_update.bindValue(QSL(":id"), id_existing_message); + + if (query_update.exec()) { + updated_messages++; + } + + query_update.finish(); + + qDebug("Updating message '%s' in DB.", qPrintable(message.m_title)); + } + } + else { + // Message with this URL is not fetched in this feed yet. + query_insert.bindValue(QSL(":feed"), feed_id); + query_insert.bindValue(QSL(":title"), message.m_title); + query_insert.bindValue(QSL(":is_read"), (int) message.m_isRead); + query_insert.bindValue(QSL(":is_important"), (int) message.m_isImportant); + query_insert.bindValue(QSL(":url"), message.m_url); + query_insert.bindValue(QSL(":author"), message.m_author); + query_insert.bindValue(QSL(":date_created"), message.m_created.toMSecsSinceEpoch()); + query_insert.bindValue(QSL(":contents"), message.m_contents); + query_insert.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures)); + query_insert.bindValue(QSL(":custom_id"), message.m_customId); + query_insert.bindValue(QSL(":account_id"), account_id); + + if (query_insert.exec() && query_insert.numRowsAffected() == 1) { + updated_messages++; + } + + query_insert.finish(); + + qDebug("Adding new message '%s' to DB.", qPrintable(message.m_title)); + } + } + + if (!database.commit()) { + database.rollback(); + + qDebug("Transaction commit for message downloader failed."); + } + else { + setStatus(NewMessages); + updateCounts(true); + serviceRoot()->itemChanged(QList() << this); + } + + return updated_messages; } diff --git a/src/services/tt-rss/ttrssfeed.h b/src/services/tt-rss/ttrssfeed.h index 92fae6ef2..87a2c3e9f 100755 --- a/src/services/tt-rss/ttrssfeed.h +++ b/src/services/tt-rss/ttrssfeed.h @@ -35,8 +35,8 @@ class TtRssFeed : public Feed { void updateCounts(bool including_total_count); - int countOfAllMessages(); - int countOfUnreadMessages(); + int countOfAllMessages() const; + int countOfUnreadMessages() const; int update(); QList undeletedMessages() const; diff --git a/src/services/tt-rss/ttrssserviceroot.cpp b/src/services/tt-rss/ttrssserviceroot.cpp index 465b2d030..16da7dc2c 100755 --- a/src/services/tt-rss/ttrssserviceroot.cpp +++ b/src/services/tt-rss/ttrssserviceroot.cpp @@ -298,7 +298,8 @@ void TtRssServiceRoot::syncIn() { storeNewFeedTree(new_tree); foreach (RootItem *top_level_item, new_tree->childItems()) { - appendChild(top_level_item); + top_level_item->setParent(NULL); + requestItemReassignment(top_level_item, this); } updateCounts(true); @@ -306,10 +307,11 @@ void TtRssServiceRoot::syncIn() { new_tree->clearChildren(); new_tree->deleteLater(); - itemChanged(QList() << this); - requestFeedReadFilterReload(); + QList all_items = getSubTree(); + + itemChanged(all_items); requestReloadMessageList(true); - requestItemExpand(getSubTree(), true); + requestItemExpand(all_items, true); } }