save work

This commit is contained in:
Martin Rotter 2024-03-08 14:12:01 +01:00
parent 07eb444d94
commit b49b7f470b
8 changed files with 126 additions and 11 deletions

View File

@ -416,6 +416,8 @@ set(SOURCES
services/standard/parsers/atomparser.h
services/standard/parsers/feedparser.cpp
services/standard/parsers/feedparser.h
services/standard/parsers/icalparser.cpp
services/standard/parsers/icalparser.h
services/standard/parsers/jsonparser.cpp
services/standard/parsers/jsonparser.h
services/standard/parsers/rdfparser.cpp

View File

@ -13,13 +13,13 @@
#include <utility>
FeedParser::FeedParser(QString data, bool is_xml)
: m_isXml(is_xml), m_data(std::move(data)), m_mrssNamespace(QSL("http://search.yahoo.com/mrss/")) {
FeedParser::FeedParser(QString data, DataType is_xml)
: m_dataType(is_xml), m_data(std::move(data)), m_mrssNamespace(QSL("http://search.yahoo.com/mrss/")) {
if (m_data.isEmpty()) {
return;
}
if (m_isXml) {
if (m_dataType == DataType::Xml) {
// XML.
QString error;
@ -27,7 +27,7 @@ FeedParser::FeedParser(QString data, bool is_xml)
throw FeedFetchException(Feed::Status::ParsingError, QObject::tr("XML problem: %1").arg(error));
}
}
else {
else if (m_dataType == DataType::Json) {
// JSON.
QJsonParseError err;
@ -50,7 +50,6 @@ QList<StandardFeed*> FeedParser::discoverFeeds(ServiceRoot* root, const QUrl& ur
if (QFile::exists(file_path)) {
try {
// 1.
auto guessed_feed = guessFeed(IOFactory::readFile(file_path), {});
guessed_feed.first->setSourceType(StandardFeed::SourceType::LocalFile);
@ -126,7 +125,7 @@ QList<Message> FeedParser::messages() {
QDateTime current_time = QDateTime::currentDateTimeUtc();
// Pull out all messages.
if (m_isXml) {
if (m_dataType == DataType::Xml) {
QDomNodeList messages_in_xml = xmlMessageElements();
for (int i = 0; i < messages_in_xml.size(); i++) {
@ -154,7 +153,7 @@ QList<Message> FeedParser::messages() {
}
}
}
else {
else if (m_dataType == DataType::Json) {
QJsonArray messages_in_json = jsonMessageElements();
for (int i = 0; i < messages_in_json.size(); i++) {

View File

@ -16,7 +16,14 @@
// Base class for all XML-based feed parsers.
class FeedParser {
public:
explicit FeedParser(QString data, bool is_xml = true);
enum class DataType {
Xml,
Json,
Ical,
Other
};
explicit FeedParser(QString data, DataType is_xml = DataType::Xml);
virtual ~FeedParser();
// Returns list of absolute URLs of discovered feeds from provided base URL.
@ -66,7 +73,7 @@ class FeedParser {
bool only_first) const;
protected:
bool m_isXml;
DataType m_dataType;
QString m_data;
QDomDocument m_xml;
QJsonDocument m_json;

View File

@ -0,0 +1,59 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#include "services/standard/parsers/icalparser.h"
#include "definitions/definitions.h"
#include "exceptions/applicationexception.h"
#include "exceptions/feedrecognizedbutfailedexception.h"
#include "services/standard/definitions.h"
IcalParser::IcalParser(const QString& data) : FeedParser(data, DataType::Other) {}
IcalParser::~IcalParser() {}
QPair<StandardFeed*, QList<IconLocation>> IcalParser::guessFeed(const QByteArray& content,
const QString& content_type) const {
if (content_type == QSL("text/calendar") || content.contains('\n')) {
Icalendar calendar;
try {
calendar = Icalendar(content);
}
catch (const ApplicationException& ex) {
throw FeedRecognizedButFailedException(QObject::tr("iCalendar error '%1'").arg(ex.message()));
}
auto* feed = new StandardFeed();
QList<IconLocation> icon_possible_locations;
feed->setEncoding(QSL(DEFAULT_FEED_ENCODING));
feed->setType(StandardFeed::Type::Atom10);
feed->setTitle(calendar.title());
return QPair<StandardFeed*, QList<IconLocation>>(feed, icon_possible_locations);
}
else {
throw ApplicationException(QObject::tr("not an iCalendar"));
}
}
Icalendar::Icalendar() {}
Icalendar::Icalendar(const QByteArray& data) {
processLines(data);
}
QString Icalendar::title() const {
return m_title;
}
void Icalendar::setTitle(const QString& title) {
m_title = title;
}
void Icalendar::processLines(const QByteArray& data) {
QString str_data = QString::fromUtf8(data);
QStringList str_blocks =
str_data.remove(QRegularExpression("^END:\\w+$")).split(QRegularExpression(QSL("^BEGIN:\\w+$")));
}

View File

@ -0,0 +1,44 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#ifndef ICALPARSER_H
#define ICALPARSER_H
#include "services/standard/parsers/feedparser.h"
class IcalendarComponent {};
class EventComponent : public IcalendarComponent {};
class Icalendar {
public:
enum class ProcessingState {
BeginCalendar,
EndCalendar,
BeginEvent,
EndEvent
}
explicit Icalendar();
explicit Icalendar(const QByteArray& data);
QString title() const;
void setTitle(const QString& title);
private:
void processLines(const QByteArray& data);
private:
QString m_title;
QList<IcalendarComponent> m_components;
};
class IcalParser : public FeedParser {
public:
explicit IcalParser(const QString& data);
virtual ~IcalParser();
virtual QPair<StandardFeed*, QList<IconLocation>> guessFeed(const QByteArray& content,
const QString& content_type) const;
};
#endif // ICALPARSER_H

View File

@ -15,7 +15,7 @@
#include <QJsonDocument>
#include <QJsonObject>
JsonParser::JsonParser(const QString& data) : FeedParser(data, false) {}
JsonParser::JsonParser(const QString& data) : FeedParser(data, DataType::Json) {}
JsonParser::~JsonParser() {}

View File

@ -187,6 +187,9 @@ QString StandardFeed::typeToString(StandardFeed::Type type) {
case Type::Sitemap:
return QSL("Sitemap");
case Type::iCalendar:
return QSL("iCalendar");
case Type::Rss2X:
default:
return QSL("RSS 2.0/2.0.1");

View File

@ -37,7 +37,8 @@ class StandardFeed : public Feed {
Rdf = 2, // Sometimes denoted as RSS 1.0.
Atom10 = 3,
Json = 4,
Sitemap = 5
Sitemap = 5,
iCalendar = 6
};
explicit StandardFeed(RootItem* parent_item = nullptr);