mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-02-03 18:57:37 +01:00
initial work on supporting embedded categories/labels in feeds/entries
This commit is contained in:
parent
ff7e527399
commit
f925bf3a77
@ -65,6 +65,7 @@ QString Enclosures::encodeEnclosuresToString(const QList<Enclosure>& enclosures)
|
||||
Message::Message() {
|
||||
m_title = m_url = m_author = m_contents = m_rawContents = m_feedId = m_customId = m_customHash = QL1S("");
|
||||
m_enclosures = QList<Enclosure>();
|
||||
m_categories = QList<MessageCategory>();
|
||||
m_accountId = m_id = 0;
|
||||
m_score = 0.0;
|
||||
m_isRead = m_isImportant = m_isDeleted = false;
|
||||
@ -209,3 +210,13 @@ uint qHash(const Message& key, uint seed) {
|
||||
uint qHash(const Message& key) {
|
||||
return (uint(key.m_accountId) * 10000) + uint(key.m_id);
|
||||
}
|
||||
|
||||
MessageCategory::MessageCategory(const QString& title) : QObject(), m_title(title) {}
|
||||
|
||||
MessageCategory::MessageCategory(const MessageCategory& other) {
|
||||
m_title = other.m_title;
|
||||
}
|
||||
|
||||
QString MessageCategory::title() const {
|
||||
return m_title;
|
||||
}
|
||||
|
@ -31,6 +31,22 @@ class RSSGUARD_DLLSPEC Enclosures {
|
||||
|
||||
class Feed;
|
||||
|
||||
// Represents RSS, JSON or ATOM category (or tag, label - depending on terminology of each entry.
|
||||
class RSSGUARD_DLLSPEC MessageCategory : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString title READ title)
|
||||
|
||||
public:
|
||||
explicit MessageCategory(const QString& title);
|
||||
MessageCategory(const MessageCategory& other);
|
||||
|
||||
QString title() const;
|
||||
|
||||
private:
|
||||
QString m_title;
|
||||
};
|
||||
|
||||
// Represents single message.
|
||||
class RSSGUARD_DLLSPEC Message {
|
||||
public:
|
||||
@ -64,6 +80,10 @@ class RSSGUARD_DLLSPEC Message {
|
||||
double m_score;
|
||||
QList<Enclosure> m_enclosures;
|
||||
|
||||
// List of assigned labels.
|
||||
// This field is only field when fetching entries of a feed.
|
||||
QList<MessageCategory> m_categories;
|
||||
|
||||
// List of custom IDs of labels assigned to this message.
|
||||
QList<Label*> m_assignedLabels;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "definitions/definitions.h"
|
||||
#include "services/abstract/labelsnode.h"
|
||||
|
||||
#include <QRandomGenerator>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
@ -168,7 +169,7 @@ QString MessageObject::findLabelId(const QString& label_title) const {
|
||||
return found_lbl != nullptr ? found_lbl->customId() : QString();
|
||||
}
|
||||
|
||||
QString MessageObject::createLabelId(const QString& title, const QString& hex_color) const {
|
||||
QString MessageObject::createLabelId(const QString& title, const QString& hex_color) {
|
||||
QString lbl_id = findLabelId(title);
|
||||
|
||||
if (!lbl_id.isEmpty()) {
|
||||
@ -176,13 +177,37 @@ QString MessageObject::createLabelId(const QString& title, const QString& hex_co
|
||||
return lbl_id;
|
||||
}
|
||||
|
||||
if (hex_color.isEmpty()) {
|
||||
// Generate color.
|
||||
return nullptr;
|
||||
if ((m_account->supportedLabelOperations() & ServiceRoot::LabelOperation::Adding) !=
|
||||
ServiceRoot::LabelOperation::Adding) {
|
||||
qWarningNN << LOGSEC_CORE << "This account does not support creating labels.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO: CONTINUE
|
||||
return nullptr;
|
||||
Label* new_lbl = nullptr;
|
||||
|
||||
try {
|
||||
auto rnd_color = QRandomGenerator::global()->bounded(0xFFFFFF);
|
||||
auto rnd_color_name = QSL("#%1").arg(QString::number(rnd_color, 16));
|
||||
|
||||
new_lbl = new Label(title, hex_color.isEmpty() ? rnd_color_name : hex_color);
|
||||
QSqlDatabase db = qApp->database()->driver()->threadSafeConnection(metaObject()->className());
|
||||
|
||||
DatabaseQueries::createLabel(db, new_lbl, m_account->accountId());
|
||||
m_account->requestItemReassignment(new_lbl, m_account->labelsNode());
|
||||
|
||||
m_availableLabels.append(new_lbl);
|
||||
|
||||
return new_lbl->customId();
|
||||
}
|
||||
catch (const ApplicationException& ex) {
|
||||
qCriticalNN << LOGSEC_CORE << "Cannot create label:" << QUOTE_W_SPACE_DOT(ex.message());
|
||||
|
||||
if (new_lbl != nullptr) {
|
||||
new_lbl->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void MessageObject::addEnclosure(const QString& url, const QString& mime_type) const {
|
||||
@ -310,6 +335,10 @@ QList<Label*> MessageObject::availableLabels() const {
|
||||
return m_availableLabels;
|
||||
}
|
||||
|
||||
QList<MessageCategory> MessageObject::categories() const {
|
||||
return m_message->m_categories;
|
||||
}
|
||||
|
||||
bool MessageObject::runningFilterWhenFetching() const {
|
||||
return m_runningAfterFetching;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
class MessageObject : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QList<MessageCategory> categories READ categories)
|
||||
Q_PROPERTY(QList<Label*> assignedLabels READ assignedLabels)
|
||||
Q_PROPERTY(QList<Label*> availableLabels READ availableLabels)
|
||||
Q_PROPERTY(QString feedCustomId READ feedCustomId)
|
||||
@ -93,7 +94,7 @@ class MessageObject : public QObject {
|
||||
|
||||
// Returns label custom ID given label title or creates
|
||||
// the label if it does not exist.
|
||||
Q_INVOKABLE QString createLabelId(const QString& title, const QString& hex_color = {}) const;
|
||||
Q_INVOKABLE QString createLabelId(const QString& title, const QString& hex_color = {});
|
||||
|
||||
// Add multimedia attachment to the message.
|
||||
Q_INVOKABLE void addEnclosure(const QString& url, const QString& mime_type) const;
|
||||
@ -102,6 +103,8 @@ class MessageObject : public QObject {
|
||||
QList<Label*> assignedLabels() const;
|
||||
QList<Label*> availableLabels() const;
|
||||
|
||||
QList<MessageCategory> categories() const;
|
||||
|
||||
bool runningFilterWhenFetching() const;
|
||||
|
||||
// Generic Message's properties bindings.
|
||||
|
@ -1015,6 +1015,5 @@ QPair<int, int> ServiceRoot::updateMessages(QList<Message>& messages, Feed* feed
|
||||
}
|
||||
|
||||
// NOTE: Do not update model items here. We update only once when all feeds are fetched.
|
||||
|
||||
return updated_messages;
|
||||
}
|
||||
|
@ -128,3 +128,18 @@ QList<Enclosure> AtomParser::xmlMessageEnclosures(const QDomElement& msg_element
|
||||
|
||||
return enclosures;
|
||||
}
|
||||
|
||||
QList<MessageCategory> AtomParser::xmlMessageCategories(const QDomElement& msg_element) const {
|
||||
QList<MessageCategory> cats;
|
||||
QDomNodeList elem_cats = msg_element.toElement().elementsByTagNameNS(m_atomNamespace, QSL("category"));
|
||||
|
||||
for (int i = 0; i < elem_cats.size(); i++) {
|
||||
QDomElement cat = elem_cats.at(i).toElement();
|
||||
QString lbl = cat.attribute(QSL("label"));
|
||||
QString term = cat.attribute(QSL("term"));
|
||||
|
||||
cats.append(MessageCategory(lbl.isEmpty() ? term : lbl));
|
||||
}
|
||||
|
||||
return cats;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class AtomParser : public FeedParser {
|
||||
virtual QString xmlMessageId(const QDomElement& msg_element) const;
|
||||
virtual QString xmlMessageUrl(const QDomElement& msg_element) const;
|
||||
virtual QList<Enclosure> xmlMessageEnclosures(const QDomElement& msg_element) const;
|
||||
virtual QList<MessageCategory> xmlMessageCategories(const QDomElement& msg_element) const;
|
||||
virtual QDomNodeList xmlMessageElements();
|
||||
virtual QString xmlMessageAuthor(const QDomElement& msg_element) const;
|
||||
virtual QString feedAuthor() const;
|
||||
|
@ -76,6 +76,10 @@ QList<Enclosure> FeedParser::jsonMessageEnclosures(const QJsonObject& msg_elemen
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<MessageCategory> FeedParser::jsonMessageCategories(const QJsonObject& msg_element) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString FeedParser::jsonMessageRawContents(const QJsonObject& msg_element) const {
|
||||
return {};
|
||||
}
|
||||
@ -105,6 +109,7 @@ QList<Message> FeedParser::messages() {
|
||||
new_message.m_rawContents = xmlMessageRawContents(message_item);
|
||||
new_message.m_enclosures = xmlMessageEnclosures(message_item);
|
||||
new_message.m_enclosures.append(xmlMrssGetEnclosures(message_item));
|
||||
new_message.m_categories.append(xmlMessageCategories(message_item));
|
||||
|
||||
messages.append(new_message);
|
||||
}
|
||||
@ -322,3 +327,7 @@ QString FeedParser::xmlMessageId(const QDomElement& msg_element) const {
|
||||
QList<Enclosure> FeedParser::xmlMessageEnclosures(const QDomElement& msg_element) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<MessageCategory> FeedParser::xmlMessageCategories(const QDomElement& msg_element) const {
|
||||
return {};
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ class FeedParser {
|
||||
virtual QDateTime xmlMessageDateCreated(const QDomElement& msg_element) const;
|
||||
virtual QString xmlMessageId(const QDomElement& msg_element) const;
|
||||
virtual QList<Enclosure> xmlMessageEnclosures(const QDomElement& msg_element) const;
|
||||
virtual QList<MessageCategory> xmlMessageCategories(const QDomElement& msg_element) const;
|
||||
virtual QString xmlMessageRawContents(const QDomElement& msg_element) const;
|
||||
|
||||
// JSON.
|
||||
@ -41,13 +42,17 @@ class FeedParser {
|
||||
virtual QDateTime jsonMessageDateCreated(const QJsonObject& msg_element) const;
|
||||
virtual QString jsonMessageId(const QJsonObject& msg_element) const;
|
||||
virtual QList<Enclosure> jsonMessageEnclosures(const QJsonObject& msg_element) const;
|
||||
virtual QList<MessageCategory> jsonMessageCategories(const QJsonObject& msg_element) const;
|
||||
virtual QString jsonMessageRawContents(const QJsonObject& msg_element) const;
|
||||
|
||||
protected:
|
||||
QList<Enclosure> xmlMrssGetEnclosures(const QDomElement& msg_element) const;
|
||||
QString xmlMrssTextFromPath(const QDomElement& msg_element, const QString& xml_path) const;
|
||||
QString xmlRawChild(const QDomElement& container) const;
|
||||
QStringList xmlTextsFromPath(const QDomElement& element, const QString& namespace_uri, const QString& xml_path, bool only_first) const;
|
||||
QStringList xmlTextsFromPath(const QDomElement& element,
|
||||
const QString& namespace_uri,
|
||||
const QString& xml_path,
|
||||
bool only_first) const;
|
||||
|
||||
protected:
|
||||
bool m_isXml;
|
||||
|
Loading…
x
Reference in New Issue
Block a user