fix #420 and add some more fixes for XML -> json utility function, also make filtering dialog work with "rawContents" to enable basic testing
This commit is contained in:
parent
ac6092f671
commit
bc739ca9fa
6 changed files with 70 additions and 26 deletions
|
@ -50,7 +50,7 @@ Here is the reference of methods and properties of some types available in your
|
||||||
| `String url` | URL of the message. |
|
| `String url` | URL of the message. |
|
||||||
| `String author` | Author of the message. |
|
| `String author` | Author of the message. |
|
||||||
| `String contents` | Contents of the message. |
|
| `String contents` | Contents of the message. |
|
||||||
| `String rawContents` | This is RAW contents of the message as it was obtained from remote service/feed. You can expect raw `XML` or `JSON` element data here. Note that this attribute has some value only if `alreadyStoredInDb` returns `false`. In other words, this attribute is not persistently stored inside RSS Guard's DB. Also, this attribute might not be filled when testing the filter, it is only filled during live filter execution on real incoming messages. |
|
| `String rawContents` | This is RAW contents of the message as it was obtained from remote service/feed. You can expect raw `XML` or `JSON` element data here. Note that this attribute has some value only if `alreadyStoredInDb` returns `false`. In other words, this attribute is not persistently stored inside RSS Guard's DB. Also, this attribute is artificially filled with ATOM-like data when testing the filter. |
|
||||||
| `Number score` | Arbitrary number in range <0.0, 100.0>. You can use this number to sort messages in a custom fashion as this attribute also has its own column in messages list. |
|
| `Number score` | Arbitrary number in range <0.0, 100.0>. You can use this number to sort messages in a custom fashion as this attribute also has its own column in messages list. |
|
||||||
| `Date created` | Date/time of the message. |
|
| `Date created` | Date/time of the message. |
|
||||||
| `Boolean isRead` | Is message read? |
|
| `Boolean isRead` | Is message read? |
|
||||||
|
|
|
@ -33,8 +33,13 @@ QString jsonProcessXmlElement(const QDomElement& elem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList elems;
|
QStringList elems;
|
||||||
|
QString elem_text;
|
||||||
|
|
||||||
for (int i = 0; i < elem.childNodes().size(); i++) {
|
for (int i = 0; i < elem.childNodes().size(); i++) {
|
||||||
|
if (elem.childNodes().at(i).isText()) {
|
||||||
|
elem_text = jsonEscapeString(elem.childNodes().at(i).nodeValue());
|
||||||
|
}
|
||||||
|
|
||||||
if (!elem.childNodes().at(i).isElement()) {
|
if (!elem.childNodes().at(i).isElement()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -43,22 +48,26 @@ QString jsonProcessXmlElement(const QDomElement& elem) {
|
||||||
jsonProcessXmlElement(elem.childNodes().at(i).toElement()));
|
jsonProcessXmlElement(elem.childNodes().at(i).toElement()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.isEmpty()) {
|
QString str;
|
||||||
if (elems.isEmpty()) {
|
|
||||||
return QSL("\"%1\"").arg(jsonEscapeString(elem.text()));
|
if (!elems.isEmpty() && !attrs.isEmpty()) {
|
||||||
}
|
str = QSL("{%1, %2, %3}").arg(attrs.join(QSL(",\n")),
|
||||||
else {
|
elems.join(QSL(",\n")),
|
||||||
return QSL("{%1}").arg(elems.join(QSL(",\n")));
|
QSL("\"__text\": \"%1\"").arg(elem_text));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (elems.isEmpty()) {
|
else if (!elems.isEmpty()) {
|
||||||
return QSL("{%1, \"__text\": \"%2\"}").arg(attrs.join(QSL(",\n")),
|
str = QSL("{%1, %2}").arg(elems.join(QSL(",\n")),
|
||||||
jsonEscapeString(elem.text()));
|
QSL("\"__text\": \"%1\"").arg(elem_text));
|
||||||
|
}
|
||||||
|
else if (!attrs.isEmpty()) {
|
||||||
|
str = QSL("{%1, %2}").arg(attrs.join(QSL(",\n")),
|
||||||
|
QSL("\"__text\": \"%1\"").arg(elem_text));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return QSL("{%1, %2}").arg(attrs.join(QSL(",\n")),
|
str = QSL("{%1}").arg(QSL("\"__text\": \"%1\"").arg(elem_text));
|
||||||
elems.join(QSL(",\n")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FilterUtils::fromXmlToJson(const QString& xml) const {
|
QString FilterUtils::fromXmlToJson(const QString& xml) const {
|
||||||
|
|
|
@ -120,6 +120,23 @@ Message Message::fromSqlRecord(const QSqlRecord& record, bool* result) {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Message::generateRawAtomContents(const Message& msg) {
|
||||||
|
return QSL("<entry>"
|
||||||
|
"<title>%1</title>"
|
||||||
|
"<link href=\"%2\" rel=\"alternate\" type=\"text/html\" title=\"%1\"/>"
|
||||||
|
"<published>%3</published>"
|
||||||
|
"<author><name>%6</name></author>"
|
||||||
|
"<updated>%3</updated>"
|
||||||
|
"<id>%4</id>"
|
||||||
|
"<summary type=\"html\">%5</summary>"
|
||||||
|
"</entry>").arg(msg.m_title,
|
||||||
|
msg.m_url,
|
||||||
|
msg.m_created.toUTC().toString(QSL("yyyy-MM-ddThh:mm:ss")),
|
||||||
|
msg.m_url,
|
||||||
|
msg.m_contents.toHtmlEscaped(),
|
||||||
|
msg.m_author);
|
||||||
|
}
|
||||||
|
|
||||||
QDataStream& operator<<(QDataStream& out, const Message& my_obj) {
|
QDataStream& operator<<(QDataStream& out, const Message& my_obj) {
|
||||||
out << my_obj.m_accountId
|
out << my_obj.m_accountId
|
||||||
<< my_obj.m_customHash
|
<< my_obj.m_customHash
|
||||||
|
|
|
@ -39,6 +39,7 @@ class RSSGUARD_DLLSPEC Message {
|
||||||
// Creates Message from given record, which contains
|
// Creates Message from given record, which contains
|
||||||
// row from query SELECT * FROM Messages WHERE ....;
|
// row from query SELECT * FROM Messages WHERE ....;
|
||||||
static Message fromSqlRecord(const QSqlRecord& record, bool* result = nullptr);
|
static Message fromSqlRecord(const QSqlRecord& record, bool* result = nullptr);
|
||||||
|
static QString generateRawAtomContents(const Message& msg);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QString m_title;
|
QString m_title;
|
||||||
|
|
|
@ -117,6 +117,7 @@ void MessagesForFiltersModel::testFilter(MessageFilter* filter, QJSEngine* engin
|
||||||
for (int i = 0; i < m_messages.size(); i++) {
|
for (int i = 0; i < m_messages.size(); i++) {
|
||||||
Message* msg = messageForRow(i);
|
Message* msg = messageForRow(i);
|
||||||
|
|
||||||
|
msg->m_rawContents = Message::generateRawAtomContents(*msg);
|
||||||
msg_proxy->setMessage(msg);
|
msg_proxy->setMessage(msg);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -263,11 +263,13 @@ void FormMessageFiltersManager::testFilter() {
|
||||||
" Author = '%3'\n"
|
" Author = '%3'\n"
|
||||||
" Is read/important = '%4/%5'\n"
|
" Is read/important = '%4/%5'\n"
|
||||||
" Created on = '%6'\n"
|
" Created on = '%6'\n"
|
||||||
" Contents = '%7'").arg(msg.m_title, msg.m_url, msg.m_author,
|
" Contents = '%7'\n"
|
||||||
msg.m_isRead ? tr("yes") : tr("no"),
|
" RAW contents = '%8'").arg(msg.m_title, msg.m_url, msg.m_author,
|
||||||
msg.m_isImportant ? tr("yes") : tr("no"),
|
msg.m_isRead ? tr("yes") : tr("no"),
|
||||||
QString::number(msg.m_created.toMSecsSinceEpoch()),
|
msg.m_isImportant ? tr("yes") : tr("no"),
|
||||||
msg.m_contents);
|
QString::number(msg.m_created.toMSecsSinceEpoch()),
|
||||||
|
msg.m_contents,
|
||||||
|
msg.m_rawContents);
|
||||||
|
|
||||||
m_ui.m_txtErrors->insertPlainText(answer);
|
m_ui.m_txtErrors->insertPlainText(answer);
|
||||||
}
|
}
|
||||||
|
@ -315,22 +317,35 @@ void FormMessageFiltersManager::processCheckedFeeds() {
|
||||||
|
|
||||||
// Create backup of message.
|
// Create backup of message.
|
||||||
Message* msg = &msgs[i]; msg->m_assignedLabels = labels_in_message;
|
Message* msg = &msgs[i]; msg->m_assignedLabels = labels_in_message;
|
||||||
|
|
||||||
|
msg->m_rawContents = Message::generateRawAtomContents(*msg);
|
||||||
|
|
||||||
Message msg_backup(*msg);
|
Message msg_backup(*msg);
|
||||||
|
|
||||||
msg_obj.setMessage(msg);
|
msg_obj.setMessage(msg);
|
||||||
|
|
||||||
MessageObject::FilteringAction result = fltr->filterMessage(&filter_engine);
|
|
||||||
bool remove_from_list = false;
|
bool remove_from_list = false;
|
||||||
|
|
||||||
if (result == MessageObject::FilteringAction::Purge) {
|
try {
|
||||||
remove_from_list = true;
|
MessageObject::FilteringAction result = fltr->filterMessage(&filter_engine);
|
||||||
|
|
||||||
// Purge the message completely and remove leftovers.
|
if (result == MessageObject::FilteringAction::Purge) {
|
||||||
DatabaseQueries::purgeMessage(database, msg->m_id);
|
remove_from_list = true;
|
||||||
DatabaseQueries::purgeLeftoverLabelAssignments(database, msg->m_accountId);
|
|
||||||
|
// Purge the message completely and remove leftovers.
|
||||||
|
DatabaseQueries::purgeMessage(database, msg->m_id);
|
||||||
|
DatabaseQueries::purgeLeftoverLabelAssignments(database, msg->m_accountId);
|
||||||
|
}
|
||||||
|
else if (result == MessageObject::FilteringAction::Ignore) {
|
||||||
|
remove_from_list = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (result == MessageObject::FilteringAction::Ignore) {
|
catch (const FilteringException& ex) {
|
||||||
remove_from_list = true;
|
qCriticalNN << LOGSEC_CORE
|
||||||
|
<< "Error when running script when processing existing messages:"
|
||||||
|
<< QUOTE_W_SPACE_DOT(ex.message());
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!msg_backup.m_isRead && msg->m_isRead) {
|
if (!msg_backup.m_isRead && msg->m_isRead) {
|
||||||
|
@ -585,6 +600,7 @@ Message FormMessageFiltersManager::testingMessage() const {
|
||||||
msg.m_isImportant = m_ui.m_cbSampleImportant->isChecked();
|
msg.m_isImportant = m_ui.m_cbSampleImportant->isChecked();
|
||||||
msg.m_created = QDateTime::fromMSecsSinceEpoch(m_ui.m_txtSampleCreatedOn->text().toLongLong());
|
msg.m_created = QDateTime::fromMSecsSinceEpoch(m_ui.m_txtSampleCreatedOn->text().toLongLong());
|
||||||
msg.m_contents = m_ui.m_txtSampleContents->toPlainText();
|
msg.m_contents = m_ui.m_txtSampleContents->toPlainText();
|
||||||
|
msg.m_rawContents = Message::generateRawAtomContents(msg);
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue