From 22f7920819d00a9f72c805b6fb964f34d9713aed Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Mon, 11 Mar 2024 13:13:13 +0100 Subject: [PATCH] ical PoC --- src/librssguard/miscellaneous/textfactory.cpp | 8 +- .../services/standard/parsers/feedparser.cpp | 64 ++++++++++ .../services/standard/parsers/feedparser.h | 22 ++-- .../services/standard/parsers/icalparser.cpp | 111 ++++++++++++++---- .../services/standard/parsers/icalparser.h | 42 ++++--- 5 files changed, 191 insertions(+), 56 deletions(-) diff --git a/src/librssguard/miscellaneous/textfactory.cpp b/src/librssguard/miscellaneous/textfactory.cpp index eaee586e6..c939b902d 100644 --- a/src/librssguard/miscellaneous/textfactory.cpp +++ b/src/librssguard/miscellaneous/textfactory.cpp @@ -143,10 +143,10 @@ QStringList TextFactory::dateTimePatterns() { return QStringList() << QSL("yyyy-MM-ddTHH:mm:ss") << QSL("MMM dd yyyy hh:mm:ss") << QSL("MMM d yyyy hh:mm:ss") << QSL("ddd, dd MMM yyyy HH:mm:ss") << QSL("ddd, dd MMM yyyy HH:mm") << QSL("ddd, d MMM yyyy HH:mm:ss") << QSL("dd MMM yyyy hh:mm:ss") << QSL("dd MMM yyyy") - << QSL("yyyy-MM-dd HH:mm:ss.z") << QSL("yyyy-MM-dd") << QSL("yyyy") << QSL("yyyy-MM") - << QSL("yyyy-MM-dd") << QSL("yyyy-MM-ddThh:mm") << QSL("yyyy-MM-ddThh:mm:ss") - << QSL("d MMM yyyy HH:mm:ss") << QSL("yyyyMMddThhmmss") << QSL("yyyyMMdd") << QSL("hh:mm:ss") - << QSL("h:m:s AP") << QSL("h:mm") << QSL("H:mm") << QSL("h:m") << QSL("h.m"); + << QSL("yyyy-MM-dd HH:mm:ss.z") << QSL("yyyy-MM-ddThh:mm:ss") << QSL("yyyy-MM-ddThh:mm") + << QSL("yyyy-MM-dd") << QSL("yyyy-MM-dd") << QSL("yyyy-MM") << QSL("d MMM yyyy HH:mm:ss") + << QSL("yyyyMMddThhmmss") << QSL("yyyyMMdd") << QSL("yyyy") << QSL("hh:mm:ss") << QSL("h:m:s AP") + << QSL("h:mm") << QSL("H:mm") << QSL("h:m") << QSL("h.m"); } QString TextFactory::encrypt(const QString& text, quint64 key) { diff --git a/src/librssguard/services/standard/parsers/feedparser.cpp b/src/librssguard/services/standard/parsers/feedparser.cpp index 8384f3329..d46ee07fe 100644 --- a/src/librssguard/services/standard/parsers/feedparser.cpp +++ b/src/librssguard/services/standard/parsers/feedparser.cpp @@ -119,6 +119,46 @@ QString FeedParser::jsonMessageRawContents(const QJsonObject& msg_element) const return {}; } +QVariantList FeedParser::objMessageElements() { + return {}; +} + +QString FeedParser::objMessageTitle(const QVariant& msg_element) const { + return {}; +} + +QString FeedParser::objMessageUrl(const QVariant& msg_element) const { + return {}; +} + +QString FeedParser::objMessageDescription(const QVariant& msg_element) const { + return {}; +} + +QString FeedParser::objMessageAuthor(const QVariant& msg_element) const { + return {}; +} + +QDateTime FeedParser::objMessageDateCreated(const QVariant& msg_element) const { + return {}; +} + +QString FeedParser::objMessageId(const QVariant& msg_element) const { + return {}; +} + +QList FeedParser::objMessageEnclosures(const QVariant& msg_element) const { + return {}; +} + +QList FeedParser::objMessageCategories(const QVariant& msg_element) const { + return {}; +} + +QString FeedParser::objMessageRawContents(const QVariant& msg_element) const { + return {}; +} + QList FeedParser::messages() { QString feed_author = feedAuthor(); QList messages; @@ -179,6 +219,30 @@ QList FeedParser::messages() { } } } + else if (m_dataType == DataType::Other) { + auto messages_in_obj = objMessageElements(); + + for (const QVariant& message_item : messages_in_obj) { + try { + Message new_message; + + // Fill available data. + new_message.m_title = objMessageTitle(message_item); + new_message.m_contents = objMessageDescription(message_item); + new_message.m_author = objMessageAuthor(message_item); + new_message.m_url = objMessageUrl(message_item); + new_message.m_created = objMessageDateCreated(message_item); + new_message.m_customId = objMessageId(message_item); + new_message.m_rawContents = objMessageRawContents(message_item); + new_message.m_enclosures = objMessageEnclosures(message_item); + + messages.append(new_message); + } + catch (const ApplicationException& ex) { + qDebugNN << LOGSEC_CORE << "Problem when extracting OBJ message: " << ex.message(); + } + } + } // Fixup missing data. // diff --git a/src/librssguard/services/standard/parsers/feedparser.h b/src/librssguard/services/standard/parsers/feedparser.h index 9b1dbd0f3..9e37a8ca8 100644 --- a/src/librssguard/services/standard/parsers/feedparser.h +++ b/src/librssguard/services/standard/parsers/feedparser.h @@ -19,7 +19,6 @@ class FeedParser { enum class DataType { Xml, Json, - Ical, Other }; @@ -63,19 +62,18 @@ class FeedParser { virtual QList jsonMessageCategories(const QJsonObject& msg_element) const; virtual QString jsonMessageRawContents(const QJsonObject& msg_element) const; - /* // Objects. virtual QVariantList objMessageElements(); - virtual QString objMessageTitle(const QVariantMap& msg_element) const; - virtual QString objMessageUrl(const QVariantMap& msg_element) const; - virtual QString objMessageDescription(const QVariantMap& msg_element) const; - virtual QString objMessageAuthor(const QVariantMap& msg_element) const; - virtual QDateTime objMessageDateCreated(const QVariantMap& msg_element) const; - virtual QString objMessageId(const QVariantMap& msg_element) const; - virtual QList objMessageEnclosures(const QVariantMap& msg_element) const; - virtual QList objMessageCategories(const QVariantMap& msg_element) const; - virtual QString objMessageRawContents(const QVariantMap& msg_element) const; -*/ + virtual QString objMessageTitle(const QVariant& msg_element) const; + virtual QString objMessageUrl(const QVariant& msg_element) const; + virtual QString objMessageDescription(const QVariant& msg_element) const; + virtual QString objMessageAuthor(const QVariant& msg_element) const; + virtual QDateTime objMessageDateCreated(const QVariant& msg_element) const; + virtual QString objMessageId(const QVariant& msg_element) const; + virtual QList objMessageEnclosures(const QVariant& msg_element) const; + virtual QList objMessageCategories(const QVariant& msg_element) const; + virtual QString objMessageRawContents(const QVariant& msg_element) const; + protected: QList xmlMrssGetEnclosures(const QDomElement& msg_element) const; QString xmlMrssTextFromPath(const QDomElement& msg_element, const QString& xml_path) const; diff --git a/src/librssguard/services/standard/parsers/icalparser.cpp b/src/librssguard/services/standard/parsers/icalparser.cpp index 7884ced48..95fae7964 100644 --- a/src/librssguard/services/standard/parsers/icalparser.cpp +++ b/src/librssguard/services/standard/parsers/icalparser.cpp @@ -10,7 +10,8 @@ #include "miscellaneous/textfactory.h" #include "services/standard/definitions.h" -IcalParser::IcalParser(const QString& data) : FeedParser(data, DataType::Other) {} +IcalParser::IcalParser(const QString& data) + : FeedParser(data, DataType::Other), m_iCalendar(Icalendar(m_data.toUtf8())) {} IcalParser::~IcalParser() {} @@ -80,7 +81,68 @@ QPair> IcalParser::guessFeed(const QByteArray } } -Icalendar::Icalendar(const QByteArray& data) : FeedParser(QString::fromUtf8(data), FeedParser::DataType::Ical) { +QVariantList IcalParser::objMessageElements() { + QVariantList lst; + + for (const auto& comp : m_iCalendar.m_components) { + lst.append(QVariant::fromValue(comp)); + } + + return lst; +} + +QString IcalParser::objMessageTitle(const QVariant& msg_element) const { + EventComponent& comp = static_cast(msg_element.value()); + + return comp.title(); +} + +QString IcalParser::objMessageUrl(const QVariant& msg_element) const { + EventComponent& comp = static_cast(msg_element.value()); + + return comp.url(); +} + +QString IcalParser::objMessageDescription(const QVariant& msg_element) const { + EventComponent& comp = static_cast(msg_element.value()); + + return comp.description(); +} + +QString IcalParser::objMessageAuthor(const QVariant& msg_element) const { + EventComponent& comp = static_cast(msg_element.value()); + + return comp.organizer(); +} + +QDateTime IcalParser::objMessageDateCreated(const QVariant& msg_element) const { + EventComponent& comp = static_cast(msg_element.value()); + + return comp.created(); +} + +QString IcalParser::objMessageId(const QVariant& msg_element) const { + EventComponent& comp = static_cast(msg_element.value()); + + return comp.uid(); +} + +QList IcalParser::objMessageEnclosures(const QVariant& msg_element) const { + return {}; +} + +QList IcalParser::objMessageCategories(const QVariant& msg_element) const { + return {}; +} + +QString IcalParser::objMessageRawContents(const QVariant& msg_element) const { + EventComponent& comp = static_cast(msg_element.value()); + + return QString::fromUtf8(QJsonDocument(QJsonObject::fromVariantMap(comp.properties())) + .toJson(QJsonDocument::JsonFormat::Indented)); +} + +Icalendar::Icalendar(const QByteArray& data) : FeedParser(QString::fromUtf8(data), FeedParser::DataType::Other) { processLines(m_data); } @@ -117,7 +179,7 @@ void Icalendar::processLines(const QString& data) { void Icalendar::processComponentCalendar(const QString& body) { auto tokenized = tokenizeBody(body); - setTitle(tokenized.value(QSL("X-WR-CALNAME"))); + setTitle(tokenized.value(QSL("X-WR-CALNAME")).toString()); } void Icalendar::processComponentEvent(const QString& body) { @@ -125,18 +187,15 @@ void Icalendar::processComponentEvent(const QString& body) { EventComponent event; - event.setUid(tokenized.value(QSL("UID"))); - event.setTitle(tokenized.value(QSL("SUMMARY"))); - event.setDescription(tokenized.value(QSL("DESCRIPTION"))); - event.setCreated(TextFactory::parseDateTime(tokenized.value(QSL("CREATED")))); + event.setProperties(tokenized); m_components.append(event); } -QMap Icalendar::tokenizeBody(const QString& body) const { +QVariantMap Icalendar::tokenizeBody(const QString& body) const { QRegularExpression regex("^(?=[A-Z-]+:)", QRegularExpression::PatternOption::MultilineOption); auto all_matches = body.split(regex); - QMap res; + QVariantMap res; for (const QString& match : all_matches) { int sep = match.indexOf(':'); @@ -149,7 +208,7 @@ QMap Icalendar::tokenizeBody(const QString& body) const { QString value = match.mid(sep + 1); value = value.replace(QRegularExpression("\\r\\n\\s?"), QString()); - value = value.replace(QRegularExpression("\\r?\\n"), QSL("
")); + value = value.replace(QRegularExpression("\\\\n"), QSL("
")); res.insert(property, value); } @@ -158,33 +217,33 @@ QMap Icalendar::tokenizeBody(const QString& body) const { } QString IcalendarComponent::uid() const { - return m_uid; + return m_properties.value(QSL("UID")).toString(); } -void IcalendarComponent::setUid(const QString& uid) { - m_uid = uid; +QVariantMap IcalendarComponent::properties() const { + return m_properties; +} + +void IcalendarComponent::setProperties(const QVariantMap& properties) { + m_properties = properties; } QString EventComponent::title() const { - return m_title; + return m_properties.value(QSL("SUMMARY")).toString(); } -void EventComponent::setTitle(const QString& title) { - m_title = title; +QString EventComponent::url() const { + return m_properties.value(QSL("URL")).toString(); +} + +QString EventComponent::organizer() const { + return m_properties.value(QSL("ORGANIZER")).toString(); } QString EventComponent::description() const { - return m_description; -} - -void EventComponent::setDescription(const QString& description) { - m_description = description; + return m_properties.value(QSL("DESCRIPTION")).toString(); } QDateTime EventComponent::created() const { - return m_created; -} - -void EventComponent::setCreated(const QDateTime& created) { - m_created = created; + return TextFactory::parseDateTime(m_properties.value(QSL("CREATED")).toString()); } diff --git a/src/librssguard/services/standard/parsers/icalparser.h b/src/librssguard/services/standard/parsers/icalparser.h index 9fb246839..898f49d0a 100644 --- a/src/librssguard/services/standard/parsers/icalparser.h +++ b/src/librssguard/services/standard/parsers/icalparser.h @@ -8,30 +8,30 @@ class IcalendarComponent { public: QString uid() const; - void setUid(const QString& uid); - private: - QString m_uid; + QVariantMap properties() const; + void setProperties(const QVariantMap& properties); + + protected: + QVariantMap m_properties; }; +Q_DECLARE_METATYPE(IcalendarComponent) + class EventComponent : public IcalendarComponent { public: QString title() const; - void setTitle(const QString& title); - + QString url() const; + QString organizer() const; QString description() const; - void setDescription(const QString& description); - QDateTime created() const; - void setCreated(const QDateTime& created); - - private: - QString m_title; - QString m_description; - QDateTime m_created; }; +Q_DECLARE_METATYPE(EventComponent) + class Icalendar : public FeedParser { + friend class IcalParser; + public: explicit Icalendar(const QByteArray& data = {}); @@ -44,7 +44,7 @@ class Icalendar : public FeedParser { void processComponentEvent(const QString& body); QDateTime parseDateTime(const QString& date_time) const; - QMap tokenizeBody(const QString& body) const; + QVariantMap tokenizeBody(const QString& body) const; private: QString m_title; @@ -60,6 +60,20 @@ class IcalParser : public FeedParser { virtual QPair> guessFeed(const QByteArray& content, const QString& content_type) const; + + virtual QVariantList objMessageElements(); + virtual QString objMessageTitle(const QVariant& msg_element) const; + virtual QString objMessageUrl(const QVariant& msg_element) const; + virtual QString objMessageDescription(const QVariant& msg_element) const; + virtual QString objMessageAuthor(const QVariant& msg_element) const; + virtual QDateTime objMessageDateCreated(const QVariant& msg_element) const; + virtual QString objMessageId(const QVariant& msg_element) const; + virtual QList objMessageEnclosures(const QVariant& msg_element) const; + virtual QList objMessageCategories(const QVariant& msg_element) const; + virtual QString objMessageRawContents(const QVariant& msg_element) const; + + private: + Icalendar m_iCalendar; }; #endif // ICALPARSER_H