1/*
2 This file is part of the syndication library
3 SPDX-FileCopyrightText: 2006 Frank Osterfeld <osterfeld@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "entry.h"
9#include "atomtools.h"
10#include "category.h"
11#include "constants.h"
12#include "content.h"
13#include "link.h"
14#include "person.h"
15#include "source.h"
16
17#include <specificitemvisitor.h>
18#include <tools.h>
19
20#include <QDomElement>
21#include <QString>
22
23#include <vector>
24
25namespace Syndication
26{
27namespace Atom
28{
29Entry::Entry()
30 : ElementWrapper()
31{
32}
33
34Entry::Entry(const QDomElement &element)
35 : ElementWrapper(element)
36{
37}
38
39void Entry::setFeedAuthors(const QList<Person> &feedAuthors)
40{
41 m_feedAuthors = feedAuthors;
42}
43
44QList<Person> Entry::authors() const
45{
46 const QList<QDomElement> a = elementsByTagNameNS(nsURI: atom1Namespace(), QStringLiteral("author"));
47 QList<Person> list;
48
49 if (!a.isEmpty()) {
50 list.reserve(asize: a.count());
51
52 std::transform(first: a.cbegin(), last: a.cend(), result: std::back_inserter(x&: list), unary_op: [](const QDomElement &element) {
53 return Person(element);
54 });
55 } else {
56 list = source().authors();
57 }
58
59 return !list.isEmpty() ? list : m_feedAuthors;
60}
61
62QList<Person> Entry::contributors() const
63{
64 const QList<QDomElement> a = elementsByTagNameNS(nsURI: atom1Namespace(), QStringLiteral("contributor"));
65 QList<Person> list;
66 list.reserve(asize: a.count());
67
68 std::transform(first: a.cbegin(), last: a.cend(), result: std::back_inserter(x&: list), unary_op: [](const QDomElement &element) {
69 return Person(element);
70 });
71
72 return list;
73}
74
75QList<Category> Entry::categories() const
76{
77 const QList<QDomElement> a = elementsByTagNameNS(nsURI: atom1Namespace(), QStringLiteral("category"));
78 QList<Category> list;
79 list.reserve(asize: a.count());
80
81 std::transform(first: a.cbegin(), last: a.cend(), result: std::back_inserter(x&: list), unary_op: [](const QDomElement &element) {
82 return Category(element);
83 });
84
85 return list;
86}
87
88QString Entry::id() const
89{
90 return extractElementTextNS(namespaceURI: atom1Namespace(), QStringLiteral("id"));
91}
92
93QList<Link> Entry::links() const
94{
95 const QList<QDomElement> a = elementsByTagNameNS(nsURI: atom1Namespace(), QStringLiteral("link"));
96 QList<Link> list;
97 list.reserve(asize: a.count());
98
99 std::transform(first: a.cbegin(), last: a.cend(), result: std::back_inserter(x&: list), unary_op: [](const QDomElement &element) {
100 return Link(element);
101 });
102
103 return list;
104}
105
106QString Entry::rights() const
107{
108 return extractAtomText(parent: *this, QStringLiteral("rights"));
109}
110
111Source Entry::source() const
112{
113 return Source(firstElementByTagNameNS(nsURI: atom1Namespace(), QStringLiteral("source")));
114}
115
116time_t Entry::published() const
117{
118 QString pub = extractElementTextNS(namespaceURI: atom1Namespace(), QStringLiteral("published"));
119 return parseDate(str: pub, hint: ISODate);
120}
121
122time_t Entry::updated() const
123{
124 QString upd = extractElementTextNS(namespaceURI: atom1Namespace(), QStringLiteral("updated"));
125 return parseDate(str: upd, hint: ISODate);
126}
127
128QString Entry::summary() const
129{
130 return extractAtomText(parent: *this, QStringLiteral("summary"));
131}
132
133QString Entry::title() const
134{
135 return extractAtomText(parent: *this, QStringLiteral("title"));
136}
137
138Content Entry::content() const
139{
140 return Content(firstElementByTagNameNS(nsURI: atom1Namespace(), QStringLiteral("content")));
141}
142
143QList<QDomElement> Entry::unhandledElements() const
144{
145 // TODO: do not hardcode this list here
146 static std::vector<ElementType> handled; // QVector would require a default ctor, and ElementType is too big for QList
147 if (handled.empty()) {
148 handled.reserve(n: 12);
149 handled.push_back(x: ElementType(QStringLiteral("author"), atom1Namespace()));
150 handled.push_back(x: ElementType(QStringLiteral("contributor"), atom1Namespace()));
151 handled.push_back(x: ElementType(QStringLiteral("category"), atom1Namespace()));
152 handled.push_back(x: ElementType(QStringLiteral("id"), atom1Namespace()));
153 handled.push_back(x: ElementType(QStringLiteral("link"), atom1Namespace()));
154 handled.push_back(x: ElementType(QStringLiteral("rights"), atom1Namespace()));
155 handled.push_back(x: ElementType(QStringLiteral("source"), atom1Namespace()));
156 handled.push_back(x: ElementType(QStringLiteral("published"), atom1Namespace()));
157 handled.push_back(x: ElementType(QStringLiteral("updated"), atom1Namespace()));
158 handled.push_back(x: ElementType(QStringLiteral("summary"), atom1Namespace()));
159 handled.push_back(x: ElementType(QStringLiteral("title"), atom1Namespace()));
160 handled.push_back(x: ElementType(QStringLiteral("content"), atom1Namespace()));
161 }
162
163 QList<QDomElement> notHandled;
164
165 QDomNodeList children = element().childNodes();
166 const int numChildren = children.size();
167 for (int i = 0; i < numChildren; ++i) {
168 QDomElement el = children.at(index: i).toElement();
169 if (!el.isNull() //
170 && std::find(first: handled.cbegin(), last: handled.cend(), val: ElementType(el.localName(), el.namespaceURI())) == handled.cend()) {
171 notHandled.append(t: el);
172 }
173 }
174
175 return notHandled;
176}
177
178QString Entry::debugInfo() const
179{
180 QString info;
181 info += QLatin1String("### Entry: ###################\n");
182 if (!title().isEmpty()) {
183 info += QLatin1String("title: #") + title() + QLatin1String("#\n");
184 }
185 if (!summary().isEmpty()) {
186 info += QLatin1String("summary: #") + summary() + QLatin1String("#\n");
187 }
188 if (!id().isEmpty()) {
189 info += QLatin1String("id: #") + id() + QLatin1String("#\n");
190 }
191 if (!content().isNull()) {
192 info += content().debugInfo();
193 }
194
195 if (!rights().isEmpty()) {
196 info += QLatin1String("rights: #") + rights() + QLatin1String("#\n");
197 }
198
199 QString dupdated = dateTimeToString(date: updated());
200 if (!dupdated.isNull()) {
201 info += QLatin1String("updated: #") + dupdated + QLatin1String("#\n");
202 }
203
204 QString dpublished = dateTimeToString(date: published());
205 if (!dpublished.isNull()) {
206 info += QLatin1String("published: #") + dpublished + QLatin1String("#\n");
207 }
208
209 const QList<Link> dlinks = links();
210 for (const auto &link : dlinks) {
211 info += link.debugInfo();
212 }
213
214 const QList<Category> dcats = categories();
215 for (const auto &cat : dcats) {
216 info += cat.debugInfo();
217 }
218
219 info += QLatin1String("### Authors: ###################\n");
220
221 const QList<Person> dauthors = authors();
222 for (const auto &author : dauthors) {
223 info += author.debugInfo();
224 }
225
226 info += QLatin1String("### Contributors: ###################\n");
227
228 const QList<Person> dcontri = contributors();
229 for (const auto &person : dcontri) {
230 info += person.debugInfo();
231 }
232
233 if (!source().isNull()) {
234 info += source().debugInfo();
235 }
236
237 info += QLatin1String("### Entry end ################\n");
238
239 return info;
240}
241
242bool Entry::accept(SpecificItemVisitor *visitor)
243{
244 return visitor->visitAtomEntry(item: this);
245}
246
247} // namespace Atom
248} // namespace Syndication
249

source code of syndication/src/atom/entry.cpp