diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml index cc0b2dfcc..441528adf 100644 --- a/resources/desktop/com.github.rssguard.appdata.xml +++ b/resources/desktop/com.github.rssguard.appdata.xml @@ -26,7 +26,7 @@ https://github.com/sponsors/martinrotter - + none diff --git a/resources/docs/Documentation.md b/resources/docs/Documentation.md index ce9cfd698..fe8f33ded 100644 --- a/resources/docs/Documentation.md +++ b/resources/docs/Documentation.md @@ -139,6 +139,7 @@ Here is the reference of methods and properties of types available in your filte | Property | `isImportant` | `Boolean` | ❌ | ✅ | Is message important? | Property | `isDeleted` | `Boolean` | ❌ | ❌ | Is message placed in recycle bin? | Method | `isAlreadyInDatabase(DuplicateCheck)` | `Boolean` | ❌ | ❌ | Allows you to test if this particular message is already stored in RSS Guard's DB. +| Method | `findLabelId(String)` | `String` | ❌ | ❌ | You enter title of the label and method returns `customId` of label which then can be used in `assignLabel()` and `deassignLabel` methods. | Method | `assignLabel(String)` | `Boolean` | ❌ | ❌ | Assigns label to this message. The passed `String` value is the `customId` property of `Label` type. See its API reference for relevant info. | Method | `deassignLabel(String)` | `Boolean` | ❌ | ❌ | Removes label from this message. The passed `String` value is the `customId` property of `Label` type. See its API reference for relevant info. | Property | `runningFilterWhenFetching` | `Boolean` | ✅ | ❌ | Returns `true` if current run of the message filter is done when message is fetched. Returns `false` if message filter runs manually, for example from `Article filters` window. diff --git a/src/librssguard/core/messageobject.cpp b/src/librssguard/core/messageobject.cpp index 2fd4d028e..e013e9215 100644 --- a/src/librssguard/core/messageobject.cpp +++ b/src/librssguard/core/messageobject.cpp @@ -9,10 +9,14 @@ #include #include -MessageObject::MessageObject(QSqlDatabase* db, const QString& feed_custom_id, int account_id, - const QList& available_labels, bool is_new_message, QObject* parent) +MessageObject::MessageObject(QSqlDatabase* db, + const QString& feed_custom_id, + int account_id, + const QList& available_labels, + bool is_new_message, + QObject* parent) : QObject(parent), m_db(db), m_feedCustomId(feed_custom_id), m_accountId(account_id), m_message(nullptr), - m_availableLabels(available_labels), m_runningAfterFetching(is_new_message) {} + m_availableLabels(available_labels), m_runningAfterFetching(is_new_message) {} void MessageObject::setMessage(Message* message) { m_message = message; @@ -33,45 +37,44 @@ bool MessageObject::isDuplicateWithAttribute(MessageObject::DuplicateCheck attri QVector> bind_values; // Now we construct the query according to parameter. - if ((attribute_check& DuplicateCheck::SameTitle) == DuplicateCheck::SameTitle) { + if ((attribute_check & DuplicateCheck::SameTitle) == DuplicateCheck::SameTitle) { where_clauses.append(QSL("title = :title")); - bind_values.append({ QSL(":title"), title() }); + bind_values.append({QSL(":title"), title()}); } - if ((attribute_check& DuplicateCheck::SameUrl) == DuplicateCheck::SameUrl) { + if ((attribute_check & DuplicateCheck::SameUrl) == DuplicateCheck::SameUrl) { where_clauses.append(QSL("url = :url")); - bind_values.append({ QSL(":url"), url() }); + bind_values.append({QSL(":url"), url()}); } - if ((attribute_check& DuplicateCheck::SameAuthor) == DuplicateCheck::SameAuthor) { + if ((attribute_check & DuplicateCheck::SameAuthor) == DuplicateCheck::SameAuthor) { where_clauses.append(QSL("author = :author")); - bind_values.append({ QSL(":author"), author() }); + bind_values.append({QSL(":author"), author()}); } - if ((attribute_check& DuplicateCheck::SameDateCreated) == DuplicateCheck::SameDateCreated) { + if ((attribute_check & DuplicateCheck::SameDateCreated) == DuplicateCheck::SameDateCreated) { where_clauses.append(QSL("date_created = :date_created")); - bind_values.append({ QSL(":date_created"), created().toMSecsSinceEpoch() }); + bind_values.append({QSL(":date_created"), created().toMSecsSinceEpoch()}); } - if ((attribute_check& DuplicateCheck::SameCustomId) == DuplicateCheck::SameCustomId) { + if ((attribute_check & DuplicateCheck::SameCustomId) == DuplicateCheck::SameCustomId) { where_clauses.append(QSL("custom_id = :custom_id")); - bind_values.append({ QSL(":custom_id"), customId() }); + bind_values.append({QSL(":custom_id"), customId()}); } where_clauses.append(QSL("account_id = :account_id")); - bind_values.append({ QSL(":account_id"), accountId() }); + bind_values.append({QSL(":account_id"), accountId()}); - if ((attribute_check& DuplicateCheck::AllFeedsSameAccount) != DuplicateCheck::AllFeedsSameAccount) { + if ((attribute_check & DuplicateCheck::AllFeedsSameAccount) != DuplicateCheck::AllFeedsSameAccount) { // Limit to current feed. where_clauses.append(QSL("feed = :feed")); - bind_values.append({ QSL(":feed"), feedCustomId() }); + bind_values.append({QSL(":feed"), feedCustomId()}); } QString full_query = QSL("SELECT COUNT(*) FROM Messages WHERE ") + where_clauses.join(QSL(" AND ")) + QSL(";"); qDebugNN << LOGSEC_MESSAGEMODEL - << "Prepared query for MSG duplicate identification is:" - << QUOTE_W_SPACE_DOT(full_query); + << "Prepared query for MSG duplicate identification is:" << QUOTE_W_SPACE_DOT(full_query); q.setForwardOnly(true); q.prepare(full_query); @@ -81,22 +84,17 @@ bool MessageObject::isDuplicateWithAttribute(MessageObject::DuplicateCheck attri } if (q.exec() && q.next()) { - qDebugNN << LOGSEC_DB - << "Executed SQL for message duplicates check:" + qDebugNN << LOGSEC_DB << "Executed SQL for message duplicates check:" << QUOTE_W_SPACE_DOT(DatabaseFactory::lastExecutedQuery(q)); if (q.record().value(0).toInt() > 0) { // Whoops, we have the "same" message in database. - qDebugNN << LOGSEC_CORE - << "Message" - << QUOTE_W_SPACE(title()) - << "was identified as duplicate by filter script."; + qDebugNN << LOGSEC_CORE << "Message" << QUOTE_W_SPACE(title()) << "was identified as duplicate by filter script."; return true; } } else if (q.lastError().isValid()) { - qWarningNN << LOGSEC_CORE - << "Error when checking for duplicate messages via filtering system, error:" + qWarningNN << LOGSEC_CORE << "Error when checking for duplicate messages via filtering system, error:" << QUOTE_W_SPACE_DOT(q.lastError().text()); } @@ -142,6 +140,14 @@ bool MessageObject::deassignLabel(const QString& label_custom_id) const { } } +QString MessageObject::findLabelId(const QString& label_title) const { + Label* found_lbl = boolinq::from(m_availableLabels).firstOrDefault([label_title](Label* lbl) { + return lbl->title().toLower() == label_title.toLower(); + }); + + return found_lbl != nullptr ? found_lbl->customId() : QString(); +} + QString MessageObject::title() const { return m_message->m_title; } diff --git a/src/librssguard/core/messageobject.h b/src/librssguard/core/messageobject.h index 45d4b3b91..7977a1615 100644 --- a/src/librssguard/core/messageobject.h +++ b/src/librssguard/core/messageobject.h @@ -8,26 +8,26 @@ #include "services/abstract/label.h" class MessageObject : public QObject { - Q_OBJECT + Q_OBJECT - Q_PROPERTY(QList assignedLabels READ assignedLabels) - Q_PROPERTY(QList availableLabels READ availableLabels) - Q_PROPERTY(QString feedCustomId READ feedCustomId) - Q_PROPERTY(int accountId READ accountId) - Q_PROPERTY(int id READ id) - Q_PROPERTY(QString customId READ customId) - Q_PROPERTY(QString title READ title WRITE setTitle) - Q_PROPERTY(QString url READ url WRITE setUrl) - Q_PROPERTY(QString author READ author WRITE setAuthor) - Q_PROPERTY(QString contents READ contents WRITE setContents) - Q_PROPERTY(QString rawContents READ rawContents WRITE setRawContents) - Q_PROPERTY(QDateTime created READ created WRITE setCreated) - Q_PROPERTY(bool createdIsMadeup READ createdIsMadeup WRITE setCreatedIsMadeup) - Q_PROPERTY(double score READ score WRITE setScore) - Q_PROPERTY(bool isRead READ isRead WRITE setIsRead) - Q_PROPERTY(bool isImportant READ isImportant WRITE setIsImportant) - Q_PROPERTY(bool isDeleted READ isDeleted WRITE setIsDeleted) - Q_PROPERTY(bool runningFilterWhenFetching READ runningFilterWhenFetching) + Q_PROPERTY(QList assignedLabels READ assignedLabels) + Q_PROPERTY(QList availableLabels READ availableLabels) + Q_PROPERTY(QString feedCustomId READ feedCustomId) + Q_PROPERTY(int accountId READ accountId) + Q_PROPERTY(int id READ id) + Q_PROPERTY(QString customId READ customId) + Q_PROPERTY(QString title READ title WRITE setTitle) + Q_PROPERTY(QString url READ url WRITE setUrl) + Q_PROPERTY(QString author READ author WRITE setAuthor) + Q_PROPERTY(QString contents READ contents WRITE setContents) + Q_PROPERTY(QString rawContents READ rawContents WRITE setRawContents) + Q_PROPERTY(QDateTime created READ created WRITE setCreated) + Q_PROPERTY(bool createdIsMadeup READ createdIsMadeup WRITE setCreatedIsMadeup) + Q_PROPERTY(double score READ score WRITE setScore) + Q_PROPERTY(bool isRead READ isRead WRITE setIsRead) + Q_PROPERTY(bool isImportant READ isImportant WRITE setIsImportant) + Q_PROPERTY(bool isDeleted READ isDeleted WRITE setIsDeleted) + Q_PROPERTY(bool runningFilterWhenFetching READ runningFilterWhenFetching) public: enum class FilteringAction { @@ -89,6 +89,9 @@ class MessageObject : public QObject { // Returns true if label was now removed or if it is not assigned to the message at all. Q_INVOKABLE bool deassignLabel(const QString& label_custom_id) const; + // Returns label custom ID given label title. + Q_INVOKABLE QString findLabelId(const QString& label_title) const; + // Returns list of assigned and available messages. QList assignedLabels() const; QList availableLabels() const; @@ -146,13 +149,11 @@ class MessageObject : public QObject { bool m_runningAfterFetching; }; -inline MessageObject::DuplicateCheck operator|(MessageObject::DuplicateCheck lhs, - MessageObject::DuplicateCheck rhs) { +inline MessageObject::DuplicateCheck operator|(MessageObject::DuplicateCheck lhs, MessageObject::DuplicateCheck rhs) { return static_cast(int(lhs) | int(rhs)); } -inline MessageObject::DuplicateCheck operator&(MessageObject::DuplicateCheck lhs, - MessageObject::DuplicateCheck rhs) { +inline MessageObject::DuplicateCheck operator&(MessageObject::DuplicateCheck lhs, MessageObject::DuplicateCheck rhs) { return static_cast(int(lhs) & int(rhs)); }