• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

syndication/rss2

  • sources
  • kde-4.14
  • kdepimlibs
  • syndication
  • rss2
document.cpp
1 /*
2  * This file is part of the syndication library
3  *
4  * Copyright (C) 2005 Frank Osterfeld <osterfeld@kde.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include <rss2/document.h>
24 #include <rss2/category.h>
25 #include <rss2/cloud.h>
26 #include <rss2/image.h>
27 #include <rss2/item.h>
28 #include <rss2/textinput.h>
29 
30 #include <constants.h>
31 #include <documentvisitor.h>
32 #include <tools.h>
33 
34 #include <QtXml/QDomDocument>
35 #include <QtCore/QList>
36 #include <QtCore/QSet>
37 #include <QtCore/QString>
38 
39 namespace Syndication {
40 namespace RSS2 {
41 
42 class Document::DocumentPrivate
43 {
44  public:
45  DocumentPrivate() : itemDescriptionIsCDATA(false),
46  itemDescriptionContainsMarkup(false),
47  itemDescGuessed(false),
48  itemTitleIsCDATA(false),
49  itemTitleContainsMarkup(false),
50  itemTitlesGuessed(false)
51  {}
52  mutable bool itemDescriptionIsCDATA;
53  mutable bool itemDescriptionContainsMarkup;
54  mutable bool itemDescGuessed;
55  mutable bool itemTitleIsCDATA;
56  mutable bool itemTitleContainsMarkup;
57  mutable bool itemTitlesGuessed;
58 };
59 
60 Document::Document(const QDomElement& element) : SpecificDocument(),
61  ElementWrapper(element),
62  d(new DocumentPrivate)
63 {
64 }
65 
66 Document Document::fromXML(const QDomDocument& doc)
67 {
68  QDomNode channelNode = doc.namedItem(QLatin1String("rss")).namedItem(QLatin1String("channel"));
69 
70  return Document(channelNode.toElement());
71 }
72 
73 Document::Document() : SpecificDocument(), ElementWrapper(), d(new DocumentPrivate)
74 {
75 }
76 
77 Document::Document(const Document& other) : SpecificDocument(other), ElementWrapper(other)
78 {
79  d = other.d;
80 }
81 
82 Document::~Document()
83 {
84 }
85 
86 Document& Document::operator=(const Document& other)
87 {
88  ElementWrapper::operator=(other);
89  d = other.d;
90  return *this;
91 }
92 bool Document::isValid() const
93 {
94  return !isNull();
95 }
96 
97 QString Document::title() const
98 {
99  return extractElementTextNS(QString(), QLatin1String("title"));
100 }
101 
102 QString Document::link() const
103 {
104  return extractElementTextNS(QString(), QLatin1String("link") );
105 }
106 
107 QString Document::description() const
108 {
109  QString desc = extractElementTextNS(QString(), QLatin1String("description"));
110  return normalize(desc);
111 }
112 
113 QString Document::language() const
114 {
115  QString lang = extractElementTextNS(QString(),
116  QLatin1String("language"));
117 
118  if (!lang.isNull())
119  {
120  return lang;
121  }
122  else
123  {
124  return extractElementTextNS(
125  dublinCoreNamespace(), QLatin1String("language"));
126  }
127 
128 }
129 
130 QString Document::copyright() const
131 {
132  QString rights = extractElementTextNS(QString(),
133  QLatin1String("copyright"));
134  if (!rights.isNull())
135  {
136  return rights;
137  }
138  else
139  {
140  // if <copyright> is not provided, use <dc:rights>
141  return extractElementTextNS(dublinCoreNamespace(),
142  QLatin1String("rights"));
143  }
144 }
145 
146 QString Document::managingEditor() const
147 {
148  return extractElementTextNS(QString(), QLatin1String("managingEditor"));
149 }
150 
151 QString Document::webMaster() const
152 {
153  return extractElementTextNS(QString(), QLatin1String("webMaster"));
154 }
155 
156 time_t Document::pubDate() const
157 {
158  QString str = extractElementTextNS(QString(), QLatin1String("pubDate"));
159 
160  if (!str.isNull())
161  {
162  return parseDate(str, RFCDate);
163  }
164  else
165  { // if there is no pubDate, check for dc:date
166  str = extractElementTextNS(dublinCoreNamespace(), QLatin1String("date"));
167  return parseDate(str, ISODate);
168  }
169 }
170 
171 time_t Document::lastBuildDate() const
172 {
173  QString str = extractElementTextNS(QString(), QLatin1String("lastBuildDate"));
174 
175  return parseDate(str, RFCDate);
176 }
177 
178 QList<Category> Document::categories() const
179 {
180  QList<Category> categories;
181 
182  QList<QDomElement> catNodes = elementsByTagNameNS(QString(),
183  QLatin1String("category"));
184  QList<QDomElement>::ConstIterator it = catNodes.constBegin();
185  for ( ; it != catNodes.constEnd(); ++it)
186  {
187  categories.append(Category(*it));
188  }
189 
190  return categories;
191 }
192 
193 QString Document::generator() const
194 {
195  return extractElementTextNS(QString(), QLatin1String("generator"));
196 }
197 
198 QString Document::docs() const
199 {
200  return extractElementTextNS(QString(), QLatin1String("docs"));
201 }
202 
203 Cloud Document::cloud() const
204 {
205  return Cloud(firstElementByTagNameNS(QString(), QLatin1String("cloud")));
206 }
207 
208 int Document::ttl() const
209 {
210  bool ok;
211  int c;
212 
213  QString text = extractElementTextNS(QString(), QLatin1String("ttl"));
214  c = text.toInt(&ok);
215  return ok ? c : 0;
216 }
217 
218 Image Document::image() const
219 {
220  return Image(firstElementByTagNameNS(QString(), QLatin1String("image")));
221 }
222 
223 TextInput Document::textInput() const
224 {
225  TextInput ti = TextInput(firstElementByTagNameNS(QString(), QLatin1String("textInput")));
226 
227  if (!ti.isNull())
228  return ti;
229 
230  // Netscape's version of RSS 0.91 has textinput, not textInput
231  return TextInput(firstElementByTagNameNS(QString(), QLatin1String("textinput")));
232 }
233 
234 QSet<int> Document::skipHours() const
235 {
236  QSet<int> skipHours;
237  QDomElement skipHoursNode = firstElementByTagNameNS(QString(),
238  QLatin1String("skipHours"));
239  if (!skipHoursNode.isNull())
240  {
241  ElementWrapper skipHoursWrapper(skipHoursNode);
242  bool ok = false;
243  QList<QDomElement> hours =
244  skipHoursWrapper.elementsByTagNameNS(QString(),
245  QLatin1String("hour"));
246  QList<QDomElement>::ConstIterator it = hours.constBegin();
247  for ( ; it != hours.constEnd(); ++it)
248  {
249  int h = (*it).text().toInt(&ok);
250  if (ok)
251  skipHours.insert(h);
252  }
253  }
254 
255  return skipHours;
256 }
257 
258 QSet<Document::DayOfWeek> Document::skipDays() const
259 {
260  QSet<DayOfWeek> skipDays;
261  QDomElement skipDaysNode = firstElementByTagNameNS(QString(), QLatin1String("skipDays"));
262  if (!skipDaysNode.isNull())
263  {
264  ElementWrapper skipDaysWrapper(skipDaysNode);
265  QHash<QString, DayOfWeek> weekDays;
266 
267  weekDays[QLatin1String("Monday")] = Monday;
268  weekDays[QLatin1String("Tuesday")] = Tuesday;
269  weekDays[QLatin1String("Wednesday")] = Wednesday;
270  weekDays[QLatin1String("Thursday")] = Thursday;
271  weekDays[QLatin1String("Friday")] = Friday;
272  weekDays[QLatin1String("Saturday")] = Saturday;
273  weekDays[QLatin1String("Sunday")] = Sunday;
274 
275  QList<QDomElement> days = skipDaysWrapper.elementsByTagNameNS(QString(), QLatin1String("day"));
276  for (QList<QDomElement>::ConstIterator it = days.constBegin(); it != days.constEnd(); ++it)
277  {
278  if (weekDays.contains((*it).text()))
279  skipDays.insert(weekDays[(*it).text()]);
280  }
281  }
282 
283  return skipDays;
284 }
285 
286 QList<Item> Document::items() const
287 {
288  QList<Item> items;
289 
290  QList<QDomElement> itemNodes = elementsByTagNameNS(QString(), QLatin1String("item"));
291 
292  DocumentPtr doccpy(new Document(*this));
293 
294  for (QList<QDomElement>::ConstIterator it = itemNodes.constBegin(); it != itemNodes.constEnd(); ++it)
295  {
296  items.append(Item(*it, doccpy));
297  }
298 
299  return items;
300 }
301 QList<QDomElement> Document::unhandledElements() const
302 {
303  // TODO: do not hardcode this list here
304  QList<ElementType> handled;
305  handled.append(ElementType(QLatin1String("title")));
306  handled.append(ElementType(QLatin1String("link")));
307  handled.append(ElementType(QLatin1String("description")));
308  handled.append(ElementType(QLatin1String("language")));
309  handled.append(ElementType(QLatin1String("copyright")));
310  handled.append(ElementType(QLatin1String("managingEditor")));
311  handled.append(ElementType(QLatin1String("webMaster")));
312  handled.append(ElementType(QLatin1String("pubDate")));
313  handled.append(ElementType(QLatin1String("lastBuildDate")));
314  handled.append(ElementType(QLatin1String("skipDays")));
315  handled.append(ElementType(QLatin1String("skipHours")));
316  handled.append(ElementType(QLatin1String("item")));
317  handled.append(ElementType(QLatin1String("textinput")));
318  handled.append(ElementType(QLatin1String("textInput")));
319  handled.append(ElementType(QLatin1String("image")));
320  handled.append(ElementType(QLatin1String("ttl")));
321  handled.append(ElementType(QLatin1String("generator")));
322  handled.append(ElementType(QLatin1String("docs")));
323  handled.append(ElementType(QLatin1String("cloud")));
324  handled.append(ElementType(QLatin1String("language"), dublinCoreNamespace()));
325  handled.append(ElementType(QLatin1String("rights"), dublinCoreNamespace()));
326  handled.append(ElementType(QLatin1String("date"), dublinCoreNamespace()));
327 
328  QList<QDomElement> notHandled;
329 
330  QDomNodeList children = element().childNodes();
331  for (int i = 0; i < children.size(); ++i)
332  {
333  QDomElement el = children.at(i).toElement();
334  if (!el.isNull()
335  && !handled.contains(ElementType(el.localName(), el.namespaceURI())))
336  {
337  notHandled.append(el);
338  }
339  }
340 
341  return notHandled;
342 }
343 
344 QString Document::debugInfo() const
345 {
346  QString info;
347  info += QLatin1String("### Document: ###################\n");
348  if (!title().isNull())
349  info += QLatin1String("title: #") + title() + QLatin1String("#\n");
350  if (!description().isNull())
351  info += QLatin1String("description: #") + description() + QLatin1String("#\n");
352  if (!link().isNull())
353  info += QLatin1String("link: #") + link() + QLatin1String("#\n");
354  if (!language().isNull())
355  info += QLatin1String("language: #") + language() + QLatin1String("#\n");
356  if (!copyright().isNull())
357  info += QLatin1String("copyright: #") + copyright() + QLatin1String("#\n");
358  if (!managingEditor().isNull())
359  info += QLatin1String("managingEditor: #") + managingEditor() + QLatin1String("#\n");
360  if (!webMaster().isNull())
361  info += QLatin1String("webMaster: #") + webMaster() + QLatin1String("#\n");
362 
363  QString dpubdate = dateTimeToString(pubDate());
364  if (!dpubdate.isNull())
365  info += QLatin1String("pubDate: #") + dpubdate + QLatin1String("#\n");
366 
367  QString dlastbuilddate = dateTimeToString(lastBuildDate());
368  if (!dlastbuilddate.isNull())
369  info += QLatin1String("lastBuildDate: #") + dlastbuilddate + QLatin1String("#\n");
370 
371  if (!textInput().isNull())
372  info += textInput().debugInfo();
373  if (!cloud().isNull())
374  info += cloud().debugInfo();
375  if (!image().isNull())
376  info += image().debugInfo();
377 
378  QList<Category> cats = categories();
379 
380  for (QList<Category>::ConstIterator it = cats.constBegin(); it != cats.constEnd(); ++it)
381  info += (*it).debugInfo();
382  QList<Item> litems = items();
383  for (QList<Item>::ConstIterator it = litems.constBegin(); it != litems.constEnd(); ++it)
384  info += (*it).debugInfo();
385  info += QLatin1String("### Document end ################\n");
386  return info;
387 }
388 
389 void Document::getItemTitleFormatInfo(bool* isCDATA, bool* containsMarkup) const
390 {
391  if (!d->itemTitlesGuessed)
392  {
393  QString titles;
394  QList<Item> litems = items();
395 
396  if (litems.isEmpty())
397  {
398  d->itemTitlesGuessed = true;
399  return;
400  }
401 
402  QDomElement titleEl = (*litems.begin()).firstElementByTagNameNS(QString(), QLatin1String("title"));
403  d->itemTitleIsCDATA = titleEl.firstChild().isCDATASection();
404 
405  int nmax = litems.size() < 10 ? litems.size() : 10; // we check a maximum of 10 items
406  int i = 0;
407 
408  QList<Item>::ConstIterator it = litems.constBegin();
409 
410  while (i < nmax)
411  {
412  titles += (*it).originalTitle();
413  ++it;
414  ++i;
415  }
416 
417  d->itemTitleContainsMarkup = stringContainsMarkup(titles);
418  d->itemTitlesGuessed = true;
419  }
420 
421  if (isCDATA != 0L)
422  *isCDATA = d->itemTitleIsCDATA;
423  if (containsMarkup != 0L)
424  *containsMarkup = d->itemTitleContainsMarkup;
425 }
426 
427 void Document::getItemDescriptionFormatInfo(bool* isCDATA, bool* containsMarkup) const
428 {
429  if (!d->itemDescGuessed)
430  {
431  QString desc;
432  QList<Item> litems = items();
433 
434 
435  if (litems.isEmpty())
436  {
437  d->itemDescGuessed = true;
438  return;
439  }
440 
441  QDomElement descEl = (*litems.begin()).firstElementByTagNameNS(QString(), QLatin1String("description"));
442  d->itemDescriptionIsCDATA = descEl.firstChild().isCDATASection();
443 
444  int nmax = litems.size() < 10 ? litems.size() : 10; // we check a maximum of 10 items
445  int i = 0;
446 
447  QList<Item>::ConstIterator it = litems.constBegin();
448 
449  while (i < nmax)
450  {
451  desc += (*it).originalDescription();
452  ++it;
453  ++i;
454  }
455 
456  d->itemDescriptionContainsMarkup = stringContainsMarkup(desc);
457  d->itemDescGuessed = true;
458  }
459 
460  if (isCDATA != 0L)
461  *isCDATA = d->itemDescriptionIsCDATA;
462  if (containsMarkup != 0L)
463  *containsMarkup = d->itemDescriptionContainsMarkup;
464 }
465 
466 bool Document::accept(DocumentVisitor* visitor)
467 {
468  return visitor->visitRSS2Document(this);
469 }
470 
471 } // namespace RSS2
472 } // namespace Syndication
Syndication::RSS2::Document::Friday
self-explanatory
Definition: document.h:260
Syndication::RSS2::Document::textInput
TextInput textInput() const
Specifies a text input box that can be displayed with the channel.
Definition: document.cpp:223
Syndication::RSS2::Document::skipHours
QSet< int > skipHours() const
Contains a set of hours (from 0 to 23), time in GMT, when the channel is not updated.
Definition: document.cpp:234
Syndication::RSS2::Cloud
Cloud information for an RSS channel.
Definition: cloud.h:59
Syndication::RSS2::Document
document implementation, representing an RSS feed from the 0.91-0.94/2.0 family.
Definition: document.h:55
Syndication::RSS2::Document::operator=
Document & operator=(const Document &other)
assigns another document.
Definition: document.cpp:86
Syndication::RSS2::Document::isValid
bool isValid() const
returns whether this document is valid or not.
Definition: document.cpp:92
QDomNodeList
Syndication::RSS2::Cloud::debugInfo
QString debugInfo() const
Returns a description of the object for debugging purposes.
Definition: cloud.cpp:72
QDomNode::namespaceURI
QString namespaceURI() const
Syndication::RSS2::Document::ttl
int ttl() const
ttl stands for time to live.
Definition: document.cpp:208
Syndication::RSS2::Document::docs
QString docs() const
A URL that points to the documentation for the format used in the RSS file.
Definition: document.cpp:198
QDomNode
QSet::insert
const_iterator insert(const T &value)
Syndication::RSS2::Document::generator
QString generator() const
A string indicating the program used to generate the channel.
Definition: document.cpp:193
Syndication::RSS2::Document::fromXML
static Document fromXML(const QDomDocument &document)
Parses an RSS2 document from an XML document.
Definition: document.cpp:66
Syndication::RSS2::Document::Tuesday
self-explanatory
Definition: document.h:257
QList::size
int size() const
QDomNode::isCDATASection
bool isCDATASection() const
QString::isNull
bool isNull() const
QDomNode::toElement
QDomElement toElement() const
Syndication::RSS2::Document::unhandledElements
QList< QDomElement > unhandledElements() const
returns all child elements of this document not covered by this class.
Definition: document.cpp:301
QList::append
void append(const T &value)
QDomNode::localName
QString localName() const
QHash
Syndication::RSS2::Document::Thursday
self-explanatory
Definition: document.h:259
QString::toInt
int toInt(bool *ok, int base) const
QList::isEmpty
bool isEmpty() const
Syndication::RSS2::Document::description
QString description() const
Phrase or sentence describing the channel.
Definition: document.cpp:107
Syndication::RSS2::Document::categories
QList< Category > categories() const
Specifies one or more categories that the channel belongs to.
Definition: document.cpp:178
Syndication::RSS2::Document::Wednesday
self-explanatory
Definition: document.h:258
Syndication::RSS2::Document::title
QString title() const
The title of the channel.
Definition: document.cpp:97
QSet
Definition: document.h:36
QString
QList
Definition: document.h:35
Syndication::RSS2::Document::copyright
QString copyright() const
Copyright notice for content in the channel.
Definition: document.cpp:130
Syndication::RSS2::Document::~Document
virtual ~Document()
destructor
Definition: document.cpp:82
Syndication::RSS2::Document::debugInfo
QString debugInfo() const
Returns a description of the object and its children for debugging purposes.
Definition: document.cpp:344
QDomNode::namedItem
QDomNode namedItem(const QString &name) const
QDomDocument
Syndication::RSS2::Document::accept
virtual bool accept(DocumentVisitor *visitor)
Used by visitors for double dispatch.
Definition: document.cpp:466
QList::contains
bool contains(const T &value) const
Syndication::RSS2::Document::lastBuildDate
time_t lastBuildDate() const
The last time the content of the channel changed.
Definition: document.cpp:171
Syndication::RSS2::Document::managingEditor
QString managingEditor() const
Email address for person responsible for editorial content.
Definition: document.cpp:146
Syndication::RSS2::Document::Sunday
self-explanatory
Definition: document.h:262
QDomNode::isNull
bool isNull() const
Syndication::RSS2::Document::Monday
self-explanatory
Definition: document.h:256
Syndication::RSS2::Document::Document
Document()
Default constructor, creates a null object, for which isNull() is true and isValid() is false...
Definition: document.cpp:73
QDomNode::firstChild
QDomNode firstChild() const
QLatin1String
Syndication::RSS2::Document::webMaster
QString webMaster() const
Email address for person responsible for technical issues relating to channel.
Definition: document.cpp:151
Syndication::RSS2::Document::image
Image image() const
Specifies a GIF, JPEG or PNG image that can be displayed with the channel.
Definition: document.cpp:218
Syndication::RSS2::TextInput
"The purpose of the element is something of a mystery.
Definition: textinput.h:40
Syndication::RSS2::Image
An RSS2 image, used to describe feed logos.
Definition: image.h:37
QHash::contains
bool contains(const Key &key) const
Syndication::RSS2::Document::cloud
Cloud cloud() const
Allows processes to register with a cloud to be notified of updates to the channel, implementing a lightweight publish-subscribe protocol for RSS feeds.
Definition: document.cpp:203
Syndication::RSS2::Image::debugInfo
QString debugInfo() const
Returns a description of the object for debugging purposes.
Definition: image.cpp:82
Syndication::RSS2::Document::language
QString language() const
Definition: document.cpp:113
QDomNodeList::size
int size() const
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
Syndication::RSS2::Document::skipDays
QSet< DayOfWeek > skipDays() const
A set of week days where aggregators shouldn't read the channel.
Definition: document.cpp:258
Syndication::RSS2::Document::link
QString link() const
The URL to the HTML website corresponding to the channel.
Definition: document.cpp:102
QDomElement
Syndication::RSS2::TextInput::debugInfo
QString debugInfo() const
Returns a description of the object for debugging purposes.
Definition: textinput.cpp:61
QList::begin
iterator begin()
Syndication::RSS2::Document::pubDate
time_t pubDate() const
The publication date for the content in the channel.
Definition: document.cpp:156
Syndication::RSS2::Document::items
QList< Item > items() const
the items contained in this document
Definition: document.cpp:286
Syndication::RSS2::Document::Saturday
self-explanatory
Definition: document.h:261
QDomNodeList::at
QDomNode at(int index) const
Syndication::RSS2::Category
A category which can be assigned to items or whole feeds.
Definition: category.h:41
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:37:41 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

syndication/rss2

Skip menu "syndication/rss2"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Members
  • File List

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal