-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreader-rdf.cpp
98 lines (84 loc) · 4.2 KB
/
reader-rdf.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "reader-rdf.h"
#include "feed.h"
#include "feedarticle.h"
#include "feedfavicon.h"
#include <QDomDocument>
QUrl baseUrlForLink(const QUrl &link); // defined in RSS reader
void RdfFeedReader::loadBytes(const QByteArray &bytes)
{
QDomDocument document;
document.setContent(bytes);
loadDocument(document);
}
static QDomElement findElement(QDomElement root, const QStringList &candidates)
{
for (const auto &candidate : candidates) {
QDomElement element = root.firstChildElement(candidate);
if (!element.isNull())
return element;
}
return QDomElement();
}
static QDomElement findElementWithOptionalNamespace(QDomElement root, const QString &tagName, const QString &ns = QStringLiteral("dc:"))
{
return findElement(root, QStringList() << tagName << ns + tagName);
}
static QString findAttribute(QDomElement element, const QStringList &candidates)
{
for (const auto &candidate : candidates) {
if (element.hasAttribute(candidate))
return element.attribute(candidate);
}
return QString();
}
void RdfFeedReader::loadDocument(const QDomNode &document)
{
QDomElement rdf = document.firstChildElement(QStringLiteral("rdf:RDF"));
QDomElement channel = rdf.firstChildElement(QStringLiteral("channel"));
QDomElement titleElement = findElementWithOptionalNamespace(channel, QStringLiteral("title"));
QDomElement descriptionElement = findElementWithOptionalNamespace(channel, QStringLiteral("description"));
QDomElement linkElement = findElementWithOptionalNamespace(channel, QStringLiteral("link"));
QDomElement imageElement = findElementWithOptionalNamespace(channel, QStringLiteral("image"));
QDomElement languageElement = findElementWithOptionalNamespace(channel, QStringLiteral("language"));
QDomElement firstArticle = rdf.firstChildElement(QStringLiteral("item"));
feed.setDescription(descriptionElement.isNull() ? QString() : descriptionElement.text());
feed.setLanguage(languageElement.isNull() ? QString() : languageElement.text());
feed.setLink(baseUrlForLink(linkElement.isNull() ? feed.xmlUrl() : QUrl(linkElement.text())));
feed.setName(titleElement.isNull() ? QString() : titleElement.text());
loadArticles(firstArticle);
if (imageElement.isNull())
feed.loadFaviconFrom(feed.link());
else {
QString imageUrl = findAttribute(imageElement, QStringList() << QStringLiteral("rdf:about") << QStringLiteral("rdf:resource"));
QDomElement urlElement = imageElement.firstChildElement(QStringLiteral("url"));
feed.setFaviconUrl(QUrl(urlElement.isNull() ? imageUrl : urlElement.text()));
feed.setLogoUrl(QUrl(imageUrl));
}
}
void RdfFeedReader::loadArticles(QDomElement itemElement)
{
while (!itemElement.isNull()) {
QString href = itemElement.attribute(QStringLiteral("rdf:about"));
FeedArticle *article = feed.findArticleByLink(QUrl(href));
if (article)
loadArticle(itemElement, *article);
else {
article = feed.newArticle();
loadArticle(itemElement, *article);
feed.insertArticle(article);
}
itemElement = itemElement.nextSiblingElement(QStringLiteral("item"));
}
}
void RdfFeedReader::loadArticle(const QDomElement &itemElement, FeedArticle &article)
{
QDomElement titleElement = findElementWithOptionalNamespace(itemElement, QStringLiteral("title"));
QDomElement dateElement = findElementWithOptionalNamespace(itemElement, QStringLiteral("date"));
QDomElement descriptionElement = findElementWithOptionalNamespace(itemElement, QStringLiteral("description"));
QDomElement contentElement = findElementWithOptionalNamespace(itemElement, QStringLiteral("content"));
QDomElement encodedContentElement = findElementWithOptionalNamespace(itemElement, QStringLiteral("content:encoded"));
article.setTitle(titleElement.isNull() ? QString() : titleElement.text());
article.updatePublicationDate(dateElement.isNull() ? QDateTime() : QDateTime::fromString(dateElement.text(), Qt::ISODateWithMs));
article.setLink(QUrl(itemElement.attribute(QStringLiteral("rdf:about"))));
article.setDescription(descriptionElement.isNull() ? QString() : descriptionElement.text());
}