Syndication

atom/document.cpp
1 /*
2  This file is part of the syndication library
3  SPDX-FileCopyrightText: 2006 Frank Osterfeld <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "document.h"
9 #include "atomtools.h"
10 #include "category.h"
11 #include "constants.h"
12 #include "entry.h"
13 #include "generator.h"
14 #include "link.h"
15 #include "person.h"
16 
17 #include <documentvisitor.h>
18 #include <tools.h>
19 
20 #include <QDomElement>
21 #include <QList>
22 #include <QString>
23 
24 #include <vector>
25 
26 namespace Syndication
27 {
28 namespace Atom
29 {
31  : ElementWrapper()
32 {
33 }
34 
36  : ElementWrapper(element)
37 {
38 }
39 
41 {
42  return visitor->visitAtomFeedDocument(this);
43 }
44 
46 {
47  const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("author"));
48  QList<Person> list;
49  list.reserve(a.count());
50 
51  std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) {
52  return Person(element);
53  });
54 
55  return list;
56 }
57 
59 {
60  const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("contributor"));
61  QList<Person> list;
62  list.reserve(a.count());
63 
64  std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) {
65  return Person(element);
66  });
67 
68  return list;
69 }
70 
72 {
73  const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("category"));
74  QList<Category> list;
75  list.reserve(a.count());
76 
77  std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) {
78  return Category(element);
79  });
80 
81  return list;
82 }
83 
85 {
86  return Generator(firstElementByTagNameNS(atom1Namespace(), QStringLiteral("generator")));
87 }
88 
90 {
91  const QString iconPath = extractElementTextNS(atom1Namespace(), QStringLiteral("icon"));
92  if (iconPath.isEmpty()) {
93  return {};
94  }
95  return completeURI(iconPath);
96 }
97 
99 {
100  return completeURI(extractElementTextNS(atom1Namespace(), QStringLiteral("logo")));
101 }
102 
104 {
105  return extractElementTextNS(atom1Namespace(), QStringLiteral("id"));
106 }
107 
109 {
110  return extractAtomText(*this, QStringLiteral("rights"));
111 }
112 
114 {
115  return extractAtomText(*this, QStringLiteral("title"));
116 }
117 
119 {
120  return extractAtomText(*this, QStringLiteral("subtitle"));
121 }
122 
123 time_t FeedDocument::updated() const
124 {
125  QString upd = extractElementTextNS(atom1Namespace(), QStringLiteral("updated"));
126  return parseDate(upd, ISODate);
127 }
128 
130 {
131  const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("link"));
132  QList<Link> list;
133  list.reserve(a.count());
134 
135  std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) {
136  return Link(element);
137  });
138 
139  return list;
140 }
141 
143 {
144  const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("entry"));
145  QList<Entry> list;
146  list.reserve(a.count());
147 
148  const QList<Person> feedAuthors = authors();
149 
150  std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [&feedAuthors](const QDomElement &element) {
151  Entry entry(element);
152  entry.setFeedAuthors(feedAuthors);
153  return entry;
154  });
155 
156  return list;
157 }
158 
160 {
161  // TODO: do not hardcode this list here
162  static std::vector<ElementType> handled; // QVector would require a default ctor, and ElementType is too big for QList
163  if (handled.empty()) {
164  handled.reserve(13);
165  handled.push_back(ElementType(QStringLiteral("author"), atom1Namespace()));
166  handled.push_back(ElementType(QStringLiteral("contributor"), atom1Namespace()));
167  handled.push_back(ElementType(QStringLiteral("category"), atom1Namespace()));
168  handled.push_back(ElementType(QStringLiteral("generator"), atom1Namespace()));
169  handled.push_back(ElementType(QStringLiteral("icon"), atom1Namespace()));
170  handled.push_back(ElementType(QStringLiteral("logo"), atom1Namespace()));
171  handled.push_back(ElementType(QStringLiteral("id"), atom1Namespace()));
172  handled.push_back(ElementType(QStringLiteral("rights"), atom1Namespace()));
173  handled.push_back(ElementType(QStringLiteral("title"), atom1Namespace()));
174  handled.push_back(ElementType(QStringLiteral("subtitle"), atom1Namespace()));
175  handled.push_back(ElementType(QStringLiteral("updated"), atom1Namespace()));
176  handled.push_back(ElementType(QStringLiteral("link"), atom1Namespace()));
177  handled.push_back(ElementType(QStringLiteral("entry"), atom1Namespace()));
178  }
179 
180  QList<QDomElement> notHandled;
181 
182  QDomNodeList children = element().childNodes();
183  const int numChildren = children.size();
184  for (int i = 0; i < numChildren; ++i) {
185  QDomElement el = children.at(i).toElement();
186  if (!el.isNull() //
187  && std::find(handled.cbegin(), handled.cend(), ElementType(el.localName(), el.namespaceURI())) == handled.cend()) {
188  notHandled.append(el);
189  }
190  }
191 
192  return notHandled;
193 }
194 
196 {
197  return !isNull();
198 }
199 
201 {
202  QString info = QLatin1String("### FeedDocument: ###################\n");
203  if (!title().isEmpty()) {
204  info += QLatin1String("title: #") + title() + QLatin1String("#\n");
205  }
206  if (!subtitle().isEmpty()) {
207  info += QLatin1String("subtitle: #") + subtitle() + QLatin1String("#\n");
208  }
209  if (!id().isEmpty()) {
210  info += QLatin1String("id: #") + id() + QLatin1String("#\n");
211  }
212 
213  if (!rights().isEmpty()) {
214  info += QLatin1String("rights: #") + rights() + QLatin1String("#\n");
215  }
216  if (!icon().isEmpty()) {
217  info += QLatin1String("icon: #") + icon() + QLatin1String("#\n");
218  }
219  if (!logo().isEmpty()) {
220  info += QLatin1String("logo: #") + logo() + QLatin1String("#\n");
221  }
222  if (!generator().isNull()) {
223  info += generator().debugInfo();
224  }
225 
226  QString dupdated = dateTimeToString(updated());
227  if (!dupdated.isNull()) {
228  info += QLatin1String("updated: #") + dupdated + QLatin1String("#\n");
229  }
230 
231  const QList<Link> dlinks = links();
232  for (const auto &link : dlinks) {
233  info += link.debugInfo();
234  }
235 
236  const QList<Category> dcats = categories();
237  for (const auto &cat : dcats) {
238  info += cat.debugInfo();
239  }
240 
241  info += QLatin1String("### Authors: ###################\n");
242 
243  const QList<Person> dauthors = authors();
244  for (const auto &author : dauthors) {
245  info += author.debugInfo();
246  }
247 
248  info += QLatin1String("### Contributors: ###################\n");
249 
250  const QList<Person> dcontri = contributors();
251  for (const auto &person : dcontri) {
252  info += person.debugInfo();
253  }
254 
255  const QList<Entry> dentries = entries();
256  for (const auto &entry : dentries) {
257  info += entry.debugInfo();
258  }
259 
260  info += QLatin1String("### FeedDocument end ################\n");
261 
262  return info;
263 }
264 
266  : ElementWrapper()
267 {
268 }
269 
271  : ElementWrapper(element)
272 {
273 }
274 
276 {
277  return visitor->visitAtomEntryDocument(this);
278 }
279 
281 {
282  return Entry(element());
283 }
284 
286 {
287  return !isNull();
288 }
289 
291 {
292  QString info;
293  info += QLatin1String("### EntryDocument: ##################\n");
294 
295  Entry dentry = entry();
296  if (!dentry.isNull()) {
297  info += dentry.debugInfo();
298  }
299 
300  info += QLatin1String("### EntryDocument end ###############\n");
301  return info;
302 }
303 
304 } // namespace Atom
305 } // namespace Syndication
Generator generator() const
description of the agent used to generate the feed.
void append(const T &value)
time_t updated() const
The datetime of the last modification of the feed content.
QList< Person > authors() const
a list of persons who are the authors of this feed.
bool isNull() const const
QString logo() const
URL of an image serving as a feed logo (optional)
QDomElement toElement() const const
QString rights() const
copyright information (optional)
int count(const T &value) const const
bool accept(DocumentVisitor *visitor) override
Used by visitors for double dispatch.
bool isNull() const const
QString title() const
feed title (required).
QDomNode at(int index) const const
int size() const const
QString debugInfo() const override
returns a description of this entry document for debugging purposes.
QString namespaceURI() const const
FeedDocument()
default constructor, creates a null feed, which is invalid.
void reserve(int alloc)
an Atom entry, equivalent to the "items" in the RSS world.
Definition: entry.h:38
QString debugInfo() const override
returns a description of this feed document for debugging purposes.
Visitor interface, following the Visitor design pattern.
QString localName() const const
QString debugInfo() const
a description of this generator for debugging purposes.
Definition: generator.cpp:42
QList< Person > contributors() const
a list of persons who contribute to this feed.
bool isEmpty() const const
Description of the agent used to generate the feed.
Definition: generator.h:25
QString id() const
a string that unambiguously identifies the feed (required)
Entry entry() const
returns the single entry described in the source.
QList::const_iterator cend() const const
QString debugInfo() const
returns a description of this entry for debugging purposes
Definition: entry.cpp:178
QString atom1Namespace()
namespace used by Atom 1.0 elements
KCALUTILS_EXPORT QString dateTimeToString(const QDateTime &date, bool dateOnly=false, bool shortfmt=true)
bool isValid() const override
returns whether this document is valid or not.
EntryDocument()
default constructor, creates a null document, which is invalid.
bool accept(DocumentVisitor *visitor) override
Used by visitors for double dispatch.
QString extractAtomText(const Syndication::ElementWrapper &parent, const QString &tagname)
extracts the content of an atomTextConstruct.
Definition: atomtools.cpp:21
QList< Entry > entries() const
a list of the entries (items) in this feed.
QList::const_iterator cbegin() const const
QString icon() const
URL of an image serving as a feed icon (optional)
QList< Link > links() const
a list of links.
virtual bool visitAtomFeedDocument(Syndication::Atom::FeedDocument *document)
reimplement this method to handle Atom feed documents (most Atom feeds are of this type).
bool isValid() const override
returns whether this document is valid or not.
QString subtitle() const
description or subtitle of the feed (optional).
QList< Category > categories() const
a list of categories this feed is assigned to (optional)
QList< QDomElement > unhandledElements() const
returns all child elements of this feed not covered by this class.
virtual bool visitAtomEntryDocument(Syndication::Atom::EntryDocument *document)
reimplement this method to handle Atom entry documents.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Dec 4 2023 03:51:53 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.