add findLabeldId method for article filtering

This commit is contained in:
Martin Rotter 2022-05-13 10:31:14 +02:00
parent 04773acba0
commit 32fc3863de
4 changed files with 58 additions and 50 deletions

View File

@ -26,7 +26,7 @@
<url type="donation">https://github.com/sponsors/martinrotter</url> <url type="donation">https://github.com/sponsors/martinrotter</url>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<releases> <releases>
<release version="4.2.2" date="2022-05-12"/> <release version="4.2.2" date="2022-05-13"/>
</releases> </releases>
<content_rating type="oars-1.0"> <content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">none</content_attribute> <content_attribute id="violence-cartoon">none</content_attribute>

View File

@ -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 | `isImportant` | `Boolean` | ❌ | ✅ | Is message important?
| Property | `isDeleted` | `Boolean` | ❌ | ❌ | Is message placed in recycle bin? | 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 | `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 | `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. | 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. | 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.

View File

@ -9,8 +9,12 @@
#include <QSqlError> #include <QSqlError>
#include <QSqlQuery> #include <QSqlQuery>
MessageObject::MessageObject(QSqlDatabase* db, const QString& feed_custom_id, int account_id, MessageObject::MessageObject(QSqlDatabase* db,
const QList<Label*>& available_labels, bool is_new_message, QObject* parent) const QString& feed_custom_id,
int account_id,
const QList<Label*>& 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), : 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) {}
@ -33,45 +37,44 @@ bool MessageObject::isDuplicateWithAttribute(MessageObject::DuplicateCheck attri
QVector<QPair<QString, QVariant>> bind_values; QVector<QPair<QString, QVariant>> bind_values;
// Now we construct the query according to parameter. // 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")); 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")); 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")); 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")); 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")); 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")); 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. // Limit to current feed.
where_clauses.append(QSL("feed = :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(";"); QString full_query = QSL("SELECT COUNT(*) FROM Messages WHERE ") + where_clauses.join(QSL(" AND ")) + QSL(";");
qDebugNN << LOGSEC_MESSAGEMODEL qDebugNN << LOGSEC_MESSAGEMODEL
<< "Prepared query for MSG duplicate identification is:" << "Prepared query for MSG duplicate identification is:" << QUOTE_W_SPACE_DOT(full_query);
<< QUOTE_W_SPACE_DOT(full_query);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(full_query); q.prepare(full_query);
@ -81,22 +84,17 @@ bool MessageObject::isDuplicateWithAttribute(MessageObject::DuplicateCheck attri
} }
if (q.exec() && q.next()) { if (q.exec() && q.next()) {
qDebugNN << LOGSEC_DB qDebugNN << LOGSEC_DB << "Executed SQL for message duplicates check:"
<< "Executed SQL for message duplicates check:"
<< QUOTE_W_SPACE_DOT(DatabaseFactory::lastExecutedQuery(q)); << QUOTE_W_SPACE_DOT(DatabaseFactory::lastExecutedQuery(q));
if (q.record().value(0).toInt() > 0) { if (q.record().value(0).toInt() > 0) {
// Whoops, we have the "same" message in database. // Whoops, we have the "same" message in database.
qDebugNN << LOGSEC_CORE qDebugNN << LOGSEC_CORE << "Message" << QUOTE_W_SPACE(title()) << "was identified as duplicate by filter script.";
<< "Message"
<< QUOTE_W_SPACE(title())
<< "was identified as duplicate by filter script.";
return true; return true;
} }
} }
else if (q.lastError().isValid()) { else if (q.lastError().isValid()) {
qWarningNN << LOGSEC_CORE qWarningNN << LOGSEC_CORE << "Error when checking for duplicate messages via filtering system, error:"
<< "Error when checking for duplicate messages via filtering system, error:"
<< QUOTE_W_SPACE_DOT(q.lastError().text()); << 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 { QString MessageObject::title() const {
return m_message->m_title; return m_message->m_title;
} }

View File

@ -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. // 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; 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. // Returns list of assigned and available messages.
QList<Label*> assignedLabels() const; QList<Label*> assignedLabels() const;
QList<Label*> availableLabels() const; QList<Label*> availableLabels() const;
@ -146,13 +149,11 @@ class MessageObject : public QObject {
bool m_runningAfterFetching; bool m_runningAfterFetching;
}; };
inline MessageObject::DuplicateCheck operator|(MessageObject::DuplicateCheck lhs, inline MessageObject::DuplicateCheck operator|(MessageObject::DuplicateCheck lhs, MessageObject::DuplicateCheck rhs) {
MessageObject::DuplicateCheck rhs) {
return static_cast<MessageObject::DuplicateCheck>(int(lhs) | int(rhs)); return static_cast<MessageObject::DuplicateCheck>(int(lhs) | int(rhs));
} }
inline MessageObject::DuplicateCheck operator&(MessageObject::DuplicateCheck lhs, inline MessageObject::DuplicateCheck operator&(MessageObject::DuplicateCheck lhs, MessageObject::DuplicateCheck rhs) {
MessageObject::DuplicateCheck rhs) {
return static_cast<MessageObject::DuplicateCheck>(int(lhs) & int(rhs)); return static_cast<MessageObject::DuplicateCheck>(int(lhs) & int(rhs));
} }