From 5139d3ae69826d1e7c186341e9569f754c4d474e Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 23 Jun 2020 13:38:25 +0200 Subject: [PATCH] Work on filter, some code cleanups. --- src/librssguard/core/feeddownloader.cpp | 74 +++--- src/librssguard/core/feeddownloader.h | 4 +- src/librssguard/core/message.cpp | 2 +- src/librssguard/core/message.h | 2 +- src/librssguard/core/messagefilter.cpp | 37 ++- src/librssguard/core/messagefilter.h | 12 +- .../miscellaneous/databasequeries.cpp | 215 ++---------------- .../miscellaneous/databasequeries.h | 108 +++++++-- .../services/gmail/gmailserviceroot.cpp | 2 +- .../inoreader/inoreaderserviceroot.cpp | 4 +- .../services/owncloud/owncloudserviceroot.cpp | 2 +- .../services/standard/standardcategory.cpp | 6 +- .../services/standard/standardfeed.cpp | 4 +- .../standard/standardserviceentrypoint.cpp | 2 +- .../services/standard/standardserviceroot.cpp | 2 +- .../services/tt-rss/ttrssserviceroot.cpp | 2 +- 16 files changed, 204 insertions(+), 274 deletions(-) diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index de95e802a..01b52f763 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -31,7 +31,7 @@ bool FeedDownloader::isUpdateRunning() const { return !m_feeds.isEmpty(); } -void FeedDownloader::updateAvailableFeeds() { +void FeedDownloader::updateAvailableFeeds(const QList& msg_filters) { for (const Feed* feed : m_feeds) { auto* cache = dynamic_cast(feed->getParentServiceRoot()); @@ -42,7 +42,7 @@ void FeedDownloader::updateAvailableFeeds() { } while (!m_feeds.isEmpty()) { - updateOneFeed(m_feeds.takeFirst()); + updateOneFeed(m_feeds.takeFirst(), msg_filters); } } @@ -62,7 +62,7 @@ void FeedDownloader::updateFeeds(const QList& feeds, const QList& msg_filters) { qDebug().nospace() << "Downloading new messages for feed ID " << feed->customId() << " URL: " << feed->url() << " title: " << feed->title() << " in thread: \'" << QThread::currentThreadId() << "\'."; @@ -85,7 +85,7 @@ void FeedDownloader::updateOneFeed(Feed* feed) { << feed->customId() << " URL: " << feed->url() << " title: " << feed->title() << " in thread: \'" << QThread::currentThreadId() << "\'."; - // Now, do some general operations on messages (tweak encoding etc.). + // Now, sanitize messages (tweak encoding etc.). for (auto& msg : msgs) { // Also, make sure that HTML encoding, encoding of special characters, etc., is fixed. msg.m_contents = QUrl::fromPercentEncoding(msg.m_contents.toUtf8()); @@ -101,47 +101,47 @@ void FeedDownloader::updateOneFeed(Feed* feed) { .remove(QRegularExpression(QSL("([\\n\\r])|(^\\s)"))); } -#if defined (DEBUG) - ///// Initial PoC for JS-based msgs filtering engine. + if (!msg_filters.isEmpty()) { + // Perform per-message filtering. + QJSEngine filter_engine; - // Perform per-message filtering. - QJSEngine filter_engine; + // Create JavaScript communication wrapper for the message. + MessageObject msg_obj; - // Create JavaScript communication wrapper for the message. - MessageObject msg_obj; + // Register the wrapper. + auto js_object = filter_engine.newQObject(&msg_obj); - // Register the wrapper. - auto js_object = filter_engine.newQObject(&msg_obj); + filter_engine.globalObject().setProperty("msg", js_object); - filter_engine.globalObject().setProperty("msg", js_object); + for (int i = 0; i < msgs.size(); i++) { + // Attach live message object to wrapper. + msg_obj.setMessage(&msgs[i]); - for (int i = 0; i < msgs.size(); i++) { - // Attach live message object to wrapper. - msg_obj.setMessage(&msgs[i]); + for (MessageFilter* msg_filter : msg_filters) { + // Call the filtering logic, given function must return integer value from + // FilteringAction enumeration. + // + // 1. All Qt properties of MessageObject class are accessible. + // For example msg.title.includes("A") returns true if message's title includes "A" etc. + // 2. Some Qt properties of MessageObject are writable, so you can alter your message! + // For example msg.isImportant = true. + FilteringAction decision = msg_filter->filterMessage(&filter_engine); - // Call the filtering logic, given function must return integer value from - // FilteringAction enumeration. - // - // 1. All Qt properties of MessageObject class are accessible. - // For example msg.title.includes("A") returns true if message's title includes "A" etc. - // 2. Some Qt properties of MessageObject are writable, so you can alter your message! - // For example msg.isImportant = true. - QJSValue filter_func = filter_engine.evaluate("(function() { " + switch (decision) { + case FilteringAction::Accept: + // Message is normally accepted, it could be tweaked by the filter. + continue; - //"return msg.isDuplicate(4) ? 1 : 2; " - "msg.isImportant = true;" - "return 1;" - "})"); - auto filter_output = filter_func.call().toInt(); - FilteringAction decision = FilteringAction(filter_output); + case FilteringAction::Ignore: + // Remove the message, we do not want it. + msgs.removeAt(i--); + break; + } - // Do something according to decision. - //bool should_skip = PerformFilteringAction(&msgs[i]); - //if (should_skip) { - // msgs.removeAt(i--); - //} + break; + } + } } -#endif m_feedsUpdated++; diff --git a/src/librssguard/core/feeddownloader.h b/src/librssguard/core/feeddownloader.h index 5c78ea17d..d23e15d76 100644 --- a/src/librssguard/core/feeddownloader.h +++ b/src/librssguard/core/feeddownloader.h @@ -50,8 +50,8 @@ class FeedDownloader : public QObject { void updateProgress(const Feed* feed, int current, int total); private: - void updateOneFeed(Feed* feed); - void updateAvailableFeeds(); + void updateOneFeed(Feed* feed, const QList& msg_filters); + void updateAvailableFeeds(const QList& msg_filters); void finalizeUpdate(); QList m_feeds; diff --git a/src/librssguard/core/message.cpp b/src/librssguard/core/message.cpp index b30d491b5..b372c3345 100644 --- a/src/librssguard/core/message.cpp +++ b/src/librssguard/core/message.cpp @@ -135,7 +135,7 @@ void MessageObject::setMessage(Message* message) { m_message = message; } -bool MessageObject::isDuplicate(int attribute_check) const { +bool MessageObject::isDuplicateWithAttribute(int attribute_check) const { // TODO: Check database according to duplication attribute_check. return int(attribute_check) == 4; } diff --git a/src/librssguard/core/message.h b/src/librssguard/core/message.h index dba5a2547..3098b619c 100644 --- a/src/librssguard/core/message.h +++ b/src/librssguard/core/message.h @@ -104,7 +104,7 @@ class MessageObject : public QObject { // Check if message is duplicate with another messages in DB. // Parameter "attribute_check" is DuplicationAttributeCheck enum // value casted to int. - Q_INVOKABLE bool isDuplicate(int attribute_check) const; + Q_INVOKABLE bool isDuplicateWithAttribute(int attribute_check) const; // Generic Message's properties bindings. QString title() const; diff --git a/src/librssguard/core/messagefilter.cpp b/src/librssguard/core/messagefilter.cpp index 7e30dd9e8..0bc9541fc 100755 --- a/src/librssguard/core/messagefilter.cpp +++ b/src/librssguard/core/messagefilter.cpp @@ -2,8 +2,41 @@ #include "core/messagefilter.h" +#include "core/message.h" + +#include + MessageFilter::MessageFilter(QObject* parent) : QObject(parent) {} -FilteringAction MessageFilter::filterMessage() { - return FilteringAction::Accept; +FilteringAction MessageFilter::filterMessage(QJSEngine* engine) { + QJSValue filter_func = engine->evaluate("(function() { " + + //"return msg.isDuplicateWithAttribute(4) ? 1 : 2; " + "msg.isImportant = true;" + "return 1;" + "})"); + auto filter_output = filter_func.call().toInt(); + FilteringAction decision = FilteringAction(filter_output); + + return decision; +} + +int MessageFilter::id() const { + return m_id; +} + +QString MessageFilter::name() const { + return m_name; +} + +void MessageFilter::setName(const QString& name) { + m_name = name; +} + +QString MessageFilter::script() const { + return m_script; +} + +void MessageFilter::setScript(const QString& script) { + m_script = script; } diff --git a/src/librssguard/core/messagefilter.h b/src/librssguard/core/messagefilter.h index d59aa7e37..2b9c8032d 100755 --- a/src/librssguard/core/messagefilter.h +++ b/src/librssguard/core/messagefilter.h @@ -7,6 +7,8 @@ #include "core/message.h" +class QJSEngine; + // Class which represents one message filter. class MessageFilter : public QObject { Q_OBJECT @@ -14,7 +16,15 @@ class MessageFilter : public QObject { public: explicit MessageFilter(QObject* parent = nullptr); - FilteringAction filterMessage(); + FilteringAction filterMessage(QJSEngine* engine); + + int id() const; + + QString name() const; + void setName(const QString& name); + + QString script() const; + void setScript(const QString& script); private: int m_id; diff --git a/src/librssguard/miscellaneous/databasequeries.cpp b/src/librssguard/miscellaneous/databasequeries.cpp index dc5ab28dc..ded7e5cab 100755 --- a/src/librssguard/miscellaneous/databasequeries.cpp +++ b/src/librssguard/miscellaneous/databasequeries.cpp @@ -26,7 +26,6 @@ #include "services/tt-rss/ttrssfeed.h" #include "services/tt-rss/ttrssserviceroot.h" -#include #include #include @@ -1192,37 +1191,6 @@ int DatabaseQueries::createAccount(const QSqlDatabase& db, const QString& code, } } -Assignment DatabaseQueries::getOwnCloudFeeds(const QSqlDatabase& db, int account_id, bool* ok) { - Assignment feeds; - QSqlQuery q(db); - - q.setForwardOnly(true); - q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); - q.bindValue(QSL(":account_id"), account_id); - - if (!q.exec()) { - qFatal("Nextcloud: Query for obtaining feeds failed. Error message: '%s'.", qPrintable(q.lastError().text())); - - if (ok != nullptr) { - *ok = false; - } - } - - while (q.next()) { - AssignmentItem pair; - - pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt(); - pair.second = new OwnCloudFeed(q.record()); - feeds << pair; - } - - if (ok != nullptr) { - *ok = true; - } - - return feeds; -} - bool DatabaseQueries::deleteFeed(const QSqlDatabase& db, int feed_custom_id, int account_id) { QSqlQuery q(db); @@ -1244,7 +1212,7 @@ bool DatabaseQueries::deleteFeed(const QSqlDatabase& db, int feed_custom_id, int return q.exec(); } -bool DatabaseQueries::deleteCategory(const QSqlDatabase& db, int id) { +bool DatabaseQueries::deleteStandardCategory(const QSqlDatabase& db, int id) { QSqlQuery q(db); // Remove this category from database. @@ -1254,9 +1222,9 @@ bool DatabaseQueries::deleteCategory(const QSqlDatabase& db, int id) { return q.exec(); } -int DatabaseQueries::addCategory(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, - const QString& description, const QDateTime& creation_date, const QIcon& icon, - bool* ok) { +int DatabaseQueries::addStandardCategory(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, + const QString& description, const QDateTime& creation_date, const QIcon& icon, + bool* ok) { QSqlQuery q(db); q.setForwardOnly(true); @@ -1296,8 +1264,8 @@ int DatabaseQueries::addCategory(const QSqlDatabase& db, int parent_id, int acco } } -bool DatabaseQueries::editCategory(const QSqlDatabase& db, int parent_id, int category_id, - const QString& title, const QString& description, const QIcon& icon) { +bool DatabaseQueries::editStandardCategory(const QSqlDatabase& db, int parent_id, int category_id, + const QString& title, const QString& description, const QIcon& icon) { QSqlQuery q(db); q.setForwardOnly(true); @@ -1312,12 +1280,12 @@ bool DatabaseQueries::editCategory(const QSqlDatabase& db, int parent_id, int ca return q.exec(); } -int DatabaseQueries::addFeed(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, - const QString& description, const QDateTime& creation_date, const QIcon& icon, - const QString& encoding, const QString& url, bool is_protected, - const QString& username, const QString& password, - Feed::AutoUpdateType auto_update_type, - int auto_update_interval, StandardFeed::Type feed_format, bool* ok) { +int DatabaseQueries::addStandardFeed(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, + const QString& description, const QDateTime& creation_date, const QIcon& icon, + const QString& encoding, const QString& url, bool is_protected, + const QString& username, const QString& password, + Feed::AutoUpdateType auto_update_type, + int auto_update_interval, StandardFeed::Type feed_format, bool* ok) { QSqlQuery q(db); qDebug() << "Adding feed with title '" << title.toUtf8() << "' to DB."; @@ -1372,12 +1340,12 @@ int DatabaseQueries::addFeed(const QSqlDatabase& db, int parent_id, int account_ } } -bool DatabaseQueries::editFeed(const QSqlDatabase& db, int parent_id, int feed_id, const QString& title, - const QString& description, const QIcon& icon, - const QString& encoding, const QString& url, bool is_protected, - const QString& username, const QString& password, - Feed::AutoUpdateType auto_update_type, - int auto_update_interval, StandardFeed::Type feed_format) { +bool DatabaseQueries::editStandardFeed(const QSqlDatabase& db, int parent_id, int feed_id, const QString& title, + const QString& description, const QIcon& icon, + const QString& encoding, const QString& url, bool is_protected, + const QString& username, const QString& password, + Feed::AutoUpdateType auto_update_type, + int auto_update_interval, StandardFeed::Type feed_format) { QSqlQuery q(db); q.setForwardOnly(true); @@ -1428,7 +1396,7 @@ bool DatabaseQueries::editBaseFeed(const QSqlDatabase& db, int feed_id, Feed::Au return q.exec(); } -QList DatabaseQueries::getAccounts(const QSqlDatabase& db, bool* ok) { +QList DatabaseQueries::getStandardAccounts(const QSqlDatabase& db, bool* ok) { QSqlQuery q(db); QList roots; @@ -1492,53 +1460,6 @@ Assignment DatabaseQueries::getStandardCategories(const QSqlDatabase& db, int ac return categories; } -Assignment DatabaseQueries::getStandardFeeds(const QSqlDatabase& db, int account_id, bool* ok) { - Assignment feeds; - QSqlQuery q(db); - - q.setForwardOnly(true); - q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); - q.bindValue(QSL(":account_id"), account_id); - - if (!q.exec()) { - qFatal("Query for obtaining feeds failed. Error message: '%s'.", - qPrintable(q.lastError().text())); - - if (ok != nullptr) { - *ok = false; - } - } - - if (ok != nullptr) { - *ok = true; - } - - while (q.next()) { - // Process this feed. - StandardFeed::Type type = static_cast(q.value(FDS_DB_TYPE_INDEX).toInt()); - - switch (type) { - case StandardFeed::Atom10: - case StandardFeed::Rdf: - case StandardFeed::Rss0X: - case StandardFeed::Rss2X: { - AssignmentItem pair; - - pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt(); - pair.second = new StandardFeed(q.record()); - qobject_cast(pair.second)->setType(type); - feeds << pair; - break; - } - - default: - break; - } - } - - return feeds; -} - bool DatabaseQueries::deleteTtRssAccount(const QSqlDatabase& db, int account_id) { QSqlQuery q(db); @@ -1546,8 +1467,6 @@ bool DatabaseQueries::deleteTtRssAccount(const QSqlDatabase& db, int account_id) q.prepare(QSL("DELETE FROM TtRssAccounts WHERE id = :id;")); q.bindValue(QSL(":id"), account_id); - // Remove extra entry in "Tiny Tiny RSS accounts list" and then delete - // all the categories/feeds and messages. return q.exec(); } @@ -1643,37 +1562,6 @@ Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id return categories; } -Assignment DatabaseQueries::getGmailFeeds(const QSqlDatabase& db, int account_id, bool* ok) { - Assignment feeds; - QSqlQuery q(db); - - q.setForwardOnly(true); - q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); - q.bindValue(QSL(":account_id"), account_id); - - if (!q.exec()) { - qFatal("Gmail: Query for obtaining feeds failed. Error message: '%s'.", qPrintable(q.lastError().text())); - - if (ok != nullptr) { - *ok = false; - } - } - - while (q.next()) { - AssignmentItem pair; - - pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt(); - pair.second = new GmailFeed(q.record()); - feeds << pair; - } - - if (ok != nullptr) { - *ok = true; - } - - return feeds; -} - QList DatabaseQueries::getGmailAccounts(const QSqlDatabase& db, bool* ok) { QSqlQuery query(db); QList roots; @@ -1727,37 +1615,6 @@ bool DatabaseQueries::deleteInoreaderAccount(const QSqlDatabase& db, int account return q.exec(); } -Assignment DatabaseQueries::getInoreaderFeeds(const QSqlDatabase& db, int account_id, bool* ok) { - Assignment feeds; - QSqlQuery q(db); - - q.setForwardOnly(true); - q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); - q.bindValue(QSL(":account_id"), account_id); - - if (!q.exec()) { - qFatal("Inoreader: Query for obtaining feeds failed. Error message: '%s'.", qPrintable(q.lastError().text())); - - if (ok != nullptr) { - *ok = false; - } - } - - while (q.next()) { - AssignmentItem pair; - - pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt(); - pair.second = new InoreaderFeed(q.record()); - feeds << pair; - } - - if (ok != nullptr) { - *ok = true; - } - - return feeds; -} - bool DatabaseQueries::storeNewInoreaderTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id) { QSqlQuery query(db); @@ -1911,40 +1768,6 @@ bool DatabaseQueries::createInoreaderAccount(const QSqlDatabase& db, int id_to_a } } -Assignment DatabaseQueries::getTtRssFeeds(const QSqlDatabase& db, int account_id, bool* ok) { - Assignment feeds; - - // All categories are now loaded. - QSqlQuery query_feeds(db); - - query_feeds.setForwardOnly(true); - query_feeds.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); - query_feeds.bindValue(QSL(":account_id"), account_id); - - if (!query_feeds.exec()) { - qFatal("Query for obtaining feeds failed. Error message: '%s'.", qPrintable(query_feeds.lastError().text())); - - if (ok != nullptr) { - *ok = false; - } - } - else { - if (ok != nullptr) { - *ok = true; - } - } - - while (query_feeds.next()) { - AssignmentItem pair; - - pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt(); - pair.second = new TtRssFeed(query_feeds.record()); - feeds << pair; - } - - return feeds; -} - QString DatabaseQueries::unnulifyString(const QString& str) { return str.isNull() ? "" : str; } diff --git a/src/librssguard/miscellaneous/databasequeries.h b/src/librssguard/miscellaneous/databasequeries.h index 89e34b9ea..e74f501c2 100644 --- a/src/librssguard/miscellaneous/databasequeries.h +++ b/src/librssguard/miscellaneous/databasequeries.h @@ -8,6 +8,7 @@ #include "services/abstract/serviceroot.h" #include "services/standard/standardfeed.h" +#include #include class DatabaseQueries { @@ -76,27 +77,32 @@ class DatabaseQueries { int auto_update_interval); static Assignment getCategories(const QSqlDatabase& db, int account_id, bool* ok = nullptr); + template + static Assignment getFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr); + // Standard account. static bool deleteFeed(const QSqlDatabase& db, int feed_custom_id, int account_id); - static bool deleteCategory(const QSqlDatabase& db, int id); - static int addCategory(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, - const QString& description, const QDateTime& creation_date, const QIcon& icon, bool* ok = nullptr); - static bool editCategory(const QSqlDatabase& db, int parent_id, int category_id, - const QString& title, const QString& description, const QIcon& icon); - static int addFeed(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, - const QString& description, const QDateTime& creation_date, const QIcon& icon, - const QString& encoding, const QString& url, bool is_protected, - const QString& username, const QString& password, - Feed::AutoUpdateType auto_update_type, - int auto_update_interval, StandardFeed::Type feed_format, bool* ok = nullptr); - static bool editFeed(const QSqlDatabase& db, int parent_id, int feed_id, const QString& title, - const QString& description, const QIcon& icon, - const QString& encoding, const QString& url, bool is_protected, - const QString& username, const QString& password, Feed::AutoUpdateType auto_update_type, - int auto_update_interval, StandardFeed::Type feed_format); - static QList getAccounts(const QSqlDatabase& db, bool* ok = nullptr); + static bool deleteStandardCategory(const QSqlDatabase& db, int id); + static int addStandardCategory(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, + const QString& description, const QDateTime& creation_date, const QIcon& icon, bool* ok = nullptr); + static bool editStandardCategory(const QSqlDatabase& db, int parent_id, int category_id, + const QString& title, const QString& description, const QIcon& icon); + static int addStandardFeed(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, + const QString& description, const QDateTime& creation_date, const QIcon& icon, + const QString& encoding, const QString& url, bool is_protected, + const QString& username, const QString& password, + Feed::AutoUpdateType auto_update_type, + int auto_update_interval, StandardFeed::Type feed_format, bool* ok = nullptr); + static bool editStandardFeed(const QSqlDatabase& db, int parent_id, int feed_id, const QString& title, + const QString& description, const QIcon& icon, + const QString& encoding, const QString& url, bool is_protected, + const QString& username, const QString& password, Feed::AutoUpdateType auto_update_type, + int auto_update_interval, StandardFeed::Type feed_format); + static QList getStandardAccounts(const QSqlDatabase& db, bool* ok = nullptr); static Assignment getStandardCategories(const QSqlDatabase& db, int account_id, bool* ok = nullptr); - static Assignment getStandardFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr); + + template + static void fillFeedData(T* feed, const QSqlRecord& sql_record); // Nextcloud account. static QList getOwnCloudAccounts(const QSqlDatabase& db, bool* ok = nullptr); @@ -107,7 +113,6 @@ class DatabaseQueries { static bool createOwnCloudAccount(const QSqlDatabase& db, int id_to_assign, const QString& username, const QString& password, const QString& url, bool force_server_side_feed_update, bool download_only_unread_messages, int batch_size); - static Assignment getOwnCloudFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr); // TT-RSS acccount. static QList getTtRssAccounts(const QSqlDatabase& db, bool* ok = nullptr); @@ -120,10 +125,8 @@ class DatabaseQueries { const QString& password, bool auth_protected, const QString& auth_username, const QString& auth_password, const QString& url, bool force_server_side_feed_update, bool download_only_unread_messages); - static Assignment getTtRssFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr); // Gmail account. - static Assignment getGmailFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static bool deleteGmailAccount(const QSqlDatabase& db, int account_id); static QList getGmailAccounts(const QSqlDatabase& db, bool* ok = nullptr); static bool overwriteGmailAccount(const QSqlDatabase& db, const QString& username, const QString& app_id, @@ -135,7 +138,6 @@ class DatabaseQueries { // Inoreader account. static bool deleteInoreaderAccount(const QSqlDatabase& db, int account_id); - static Assignment getInoreaderFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static bool storeNewInoreaderTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id); static QList getInoreaderAccounts(const QSqlDatabase& db, bool* ok = nullptr); static bool overwriteInoreaderAccount(const QSqlDatabase& db, const QString& username, const QString& app_id, @@ -151,4 +153,66 @@ class DatabaseQueries { explicit DatabaseQueries(); }; +template +void DatabaseQueries::fillFeedData(T* feed, const QSqlRecord& sql_record) { + Q_UNUSED(feed) + Q_UNUSED(sql_record) +} + +template<> +inline void DatabaseQueries::fillFeedData(StandardFeed* feed, const QSqlRecord& sql_record) { + StandardFeed::Type type = static_cast(sql_record.value(FDS_DB_TYPE_INDEX).toInt()); + + switch (type) { + case StandardFeed::Atom10: + case StandardFeed::Rdf: + case StandardFeed::Rss0X: + case StandardFeed::Rss2X: { + feed->setType(type); + break; + } + } +} + +template +Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db, int account_id, bool* ok) { + Assignment feeds; + + // All categories are now loaded. + QSqlQuery query_feeds(db); + + query_feeds.setForwardOnly(true); + query_feeds.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); + query_feeds.bindValue(QSL(":account_id"), account_id); + + if (!query_feeds.exec()) { + qFatal("Query for obtaining feeds failed. Error message: '%s'.", qPrintable(query_feeds.lastError().text())); + + if (ok != nullptr) { + *ok = false; + } + } + else { + if (ok != nullptr) { + *ok = true; + } + } + + while (query_feeds.next()) { + AssignmentItem pair; + + pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt(); + + T* feed = new T(query_feeds.record()); + + fillFeedData(feed, query_feeds.record()); + + pair.second = feed; + + feeds << pair; + } + + return feeds; +} + #endif // DATABASEQUERIES_H diff --git a/src/librssguard/services/gmail/gmailserviceroot.cpp b/src/librssguard/services/gmail/gmailserviceroot.cpp index 58946ac2a..de6c16b3e 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.cpp +++ b/src/librssguard/services/gmail/gmailserviceroot.cpp @@ -59,7 +59,7 @@ void GmailServiceRoot::writeNewEmail() { void GmailServiceRoot::loadFromDatabase() { QSqlDatabase database = qApp->database()->connection(metaObject()->className()); Assignment categories = DatabaseQueries::getCategories(database, accountId()); - Assignment feeds = DatabaseQueries::getGmailFeeds(database, accountId()); + Assignment feeds = DatabaseQueries::getFeeds(database, accountId()); // All data are now obtained, lets create the hierarchy. assembleCategories(categories); diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp index f6484d8fe..47957d3c6 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp @@ -27,7 +27,7 @@ #include "services/abstract/recyclebin.h" #include "services/inoreader/gui/formeditinoreaderaccount.h" #include "services/inoreader/inoreaderentrypoint.h" -#include "services/inoreader/network/inoreadernetworkfactory.h" +#include "services/inoreader/inoreaderfeed.h" #include "services/inoreader/network/inoreadernetworkfactory.h" InoreaderServiceRoot::InoreaderServiceRoot(InoreaderNetworkFactory* network, RootItem* parent) : ServiceRoot(parent), m_network(network) { @@ -51,7 +51,7 @@ void InoreaderServiceRoot::updateTitle() { void InoreaderServiceRoot::loadFromDatabase() { QSqlDatabase database = qApp->database()->connection(metaObject()->className()); Assignment categories = DatabaseQueries::getCategories(database, accountId()); - Assignment feeds = DatabaseQueries::getInoreaderFeeds(database, accountId()); + Assignment feeds = DatabaseQueries::getFeeds(database, accountId()); // All data are now obtained, lets create the hierarchy. assembleCategories(categories); diff --git a/src/librssguard/services/owncloud/owncloudserviceroot.cpp b/src/librssguard/services/owncloud/owncloudserviceroot.cpp index f8c237145..821fcc93b 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.cpp +++ b/src/librssguard/services/owncloud/owncloudserviceroot.cpp @@ -196,7 +196,7 @@ RootItem* OwnCloudServiceRoot::obtainNewTreeForSyncIn() const { void OwnCloudServiceRoot::loadFromDatabase() { QSqlDatabase database = qApp->database()->connection(metaObject()->className()); Assignment categories = DatabaseQueries::getCategories(database, accountId()); - Assignment feeds = DatabaseQueries::getOwnCloudFeeds(database, accountId()); + Assignment feeds = DatabaseQueries::getFeeds(database, accountId()); // All data are now obtained, lets create the hierarchy. assembleCategories(categories); diff --git a/src/librssguard/services/standard/standardcategory.cpp b/src/librssguard/services/standard/standardcategory.cpp index 015a51c86..1f96fcffb 100644 --- a/src/librssguard/services/standard/standardcategory.cpp +++ b/src/librssguard/services/standard/standardcategory.cpp @@ -85,7 +85,7 @@ bool StandardCategory::removeItself() { // Children are removed, remove this standard category too. QSqlDatabase database = qApp->database()->connection(metaObject()->className()); - return DatabaseQueries::deleteCategory(database, id()); + return DatabaseQueries::deleteStandardCategory(database, id()); } else { return false; @@ -95,7 +95,7 @@ bool StandardCategory::removeItself() { bool StandardCategory::addItself(RootItem* parent) { // Now, add category to persistent storage. QSqlDatabase database = qApp->database()->connection(metaObject()->className()); - int new_id = DatabaseQueries::addCategory(database, parent->id(), parent->getParentServiceRoot()->accountId(), + int new_id = DatabaseQueries::addStandardCategory(database, parent->id(), parent->getParentServiceRoot()->accountId(), title(), description(), creationDate(), icon()); if (new_id <= 0) { @@ -113,7 +113,7 @@ bool StandardCategory::editItself(StandardCategory* new_category_data) { StandardCategory* original_category = this; RootItem* new_parent = new_category_data->parent(); - if (DatabaseQueries::editCategory(database, new_parent->id(), original_category->id(), + if (DatabaseQueries::editStandardCategory(database, new_parent->id(), original_category->id(), new_category_data->title(), new_category_data->description(), new_category_data->icon())) { // Setup new model data for the original item. diff --git a/src/librssguard/services/standard/standardfeed.cpp b/src/librssguard/services/standard/standardfeed.cpp index 72eb15342..7fcafa9b3 100644 --- a/src/librssguard/services/standard/standardfeed.cpp +++ b/src/librssguard/services/standard/standardfeed.cpp @@ -307,7 +307,7 @@ bool StandardFeed::addItself(RootItem* parent) { // Now, add feed to persistent storage. QSqlDatabase database = qApp->database()->connection(metaObject()->className()); bool ok; - int new_id = DatabaseQueries::addFeed(database, parent->id(), parent->getParentServiceRoot()->accountId(), title(), + int new_id = DatabaseQueries::addStandardFeed(database, parent->id(), parent->getParentServiceRoot()->accountId(), title(), description(), creationDate(), icon(), encoding(), url(), passwordProtected(), username(), password(), autoUpdateType(), autoUpdateInitialInterval(), type(), &ok); @@ -328,7 +328,7 @@ bool StandardFeed::editItself(StandardFeed* new_feed_data) { StandardFeed* original_feed = this; RootItem* new_parent = new_feed_data->parent(); - if (!DatabaseQueries::editFeed(database, new_parent->id(), original_feed->id(), new_feed_data->title(), + if (!DatabaseQueries::editStandardFeed(database, new_parent->id(), original_feed->id(), new_feed_data->title(), new_feed_data->description(), new_feed_data->icon(), new_feed_data->encoding(), new_feed_data->url(), new_feed_data->passwordProtected(), new_feed_data->username(), new_feed_data->password(), diff --git a/src/librssguard/services/standard/standardserviceentrypoint.cpp b/src/librssguard/services/standard/standardserviceentrypoint.cpp index 8d6012632..5c5ed8c22 100644 --- a/src/librssguard/services/standard/standardserviceentrypoint.cpp +++ b/src/librssguard/services/standard/standardserviceentrypoint.cpp @@ -52,5 +52,5 @@ QList StandardServiceEntryPoint::initializeSubtree() const { // Check DB if standard account is enabled. QSqlDatabase database = qApp->database()->connection(QSL("StandardServiceEntryPoint")); - return DatabaseQueries::getAccounts(database); + return DatabaseQueries::getStandardAccounts(database); } diff --git a/src/librssguard/services/standard/standardserviceroot.cpp b/src/librssguard/services/standard/standardserviceroot.cpp index 755741f72..be899840b 100644 --- a/src/librssguard/services/standard/standardserviceroot.cpp +++ b/src/librssguard/services/standard/standardserviceroot.cpp @@ -133,7 +133,7 @@ Qt::ItemFlags StandardServiceRoot::additionalFlags() const { void StandardServiceRoot::loadFromDatabase() { QSqlDatabase database = qApp->database()->connection(metaObject()->className()); Assignment categories = DatabaseQueries::getStandardCategories(database, accountId()); - Assignment feeds = DatabaseQueries::getStandardFeeds(database, accountId()); + Assignment feeds = DatabaseQueries::getFeeds(database, accountId()); // All data are now obtained, lets create the hierarchy. assembleCategories(categories); diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp index eeae74d96..a1de18358 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp @@ -207,7 +207,7 @@ void TtRssServiceRoot::saveAccountDataToDatabase() { void TtRssServiceRoot::loadFromDatabase() { QSqlDatabase database = qApp->database()->connection(metaObject()->className()); Assignment categories = DatabaseQueries::getCategories(database, accountId()); - Assignment feeds = DatabaseQueries::getTtRssFeeds(database, accountId()); + Assignment feeds = DatabaseQueries::getFeeds(database, accountId()); // All data are now obtained, lets create the hierarchy. assembleCategories(categories);