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>
30 #include <constants.h>
31 #include <documentvisitor.h>
34 #include <QtXml/QDomDocument>
35 #include <QtCore/QList>
36 #include <QtCore/QSet>
37 #include <QtCore/QString>
39 namespace Syndication {
42 class Document::DocumentPrivate
45 DocumentPrivate() : itemDescriptionIsCDATA(false),
46 itemDescriptionContainsMarkup(false),
47 itemDescGuessed(false),
48 itemTitleIsCDATA(false),
49 itemTitleContainsMarkup(false),
50 itemTitlesGuessed(false)
52 mutable bool itemDescriptionIsCDATA;
53 mutable bool itemDescriptionContainsMarkup;
54 mutable bool itemDescGuessed;
55 mutable bool itemTitleIsCDATA;
56 mutable bool itemTitleContainsMarkup;
57 mutable bool itemTitlesGuessed;
61 ElementWrapper(element),
62 d(new DocumentPrivate)
68 QDomNode channelNode = doc.namedItem(QLatin1String(
"rss")).namedItem(QLatin1String(
"channel"));
70 return Document(channelNode.toElement());
88 ElementWrapper::operator=(other);
99 return extractElementTextNS(QString(), QLatin1String(
"title"));
104 return extractElementTextNS(QString(), QLatin1String(
"link") );
109 QString desc = extractElementTextNS(QString(), QLatin1String(
"description"));
110 return normalize(desc);
115 QString lang = extractElementTextNS(QString(),
116 QLatin1String(
"language"));
124 return extractElementTextNS(
125 dublinCoreNamespace(), QLatin1String(
"language"));
132 QString rights = extractElementTextNS(QString(),
133 QLatin1String(
"copyright"));
134 if (!rights.isNull())
141 return extractElementTextNS(dublinCoreNamespace(),
142 QLatin1String(
"rights"));
148 return extractElementTextNS(QString(), QLatin1String(
"managingEditor"));
153 return extractElementTextNS(QString(), QLatin1String(
"webMaster"));
158 QString str = extractElementTextNS(QString(), QLatin1String(
"pubDate"));
162 return parseDate(str, RFCDate);
166 str = extractElementTextNS(dublinCoreNamespace(), QLatin1String(
"date"));
167 return parseDate(str, ISODate);
173 QString str = extractElementTextNS(QString(), QLatin1String(
"lastBuildDate"));
175 return parseDate(str, RFCDate);
182 QList<QDomElement> catNodes = elementsByTagNameNS(QString(),
183 QLatin1String(
"category"));
184 QList<QDomElement>::ConstIterator it = catNodes.constBegin();
185 for ( ; it != catNodes.constEnd(); ++it)
195 return extractElementTextNS(QString(), QLatin1String(
"generator"));
200 return extractElementTextNS(QString(), QLatin1String(
"docs"));
205 return Cloud(firstElementByTagNameNS(QString(), QLatin1String(
"cloud")));
213 QString text = extractElementTextNS(QString(), QLatin1String(
"ttl"));
220 return Image(firstElementByTagNameNS(QString(), QLatin1String(
"image")));
225 TextInput ti =
TextInput(firstElementByTagNameNS(QString(), QLatin1String(
"textInput")));
231 return TextInput(firstElementByTagNameNS(QString(), QLatin1String(
"textinput")));
237 QDomElement skipHoursNode = firstElementByTagNameNS(QString(),
238 QLatin1String(
"skipHours"));
239 if (!skipHoursNode.isNull())
241 ElementWrapper skipHoursWrapper(skipHoursNode);
243 QList<QDomElement> hours =
244 skipHoursWrapper.elementsByTagNameNS(QString(),
245 QLatin1String(
"hour"));
246 QList<QDomElement>::ConstIterator it = hours.constBegin();
247 for ( ; it != hours.constEnd(); ++it)
249 int h = (*it).text().toInt(&ok);
261 QDomElement skipDaysNode = firstElementByTagNameNS(QString(), QLatin1String(
"skipDays"));
262 if (!skipDaysNode.isNull())
264 ElementWrapper skipDaysWrapper(skipDaysNode);
265 QHash<QString, DayOfWeek> weekDays;
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;
275 QList<QDomElement> days = skipDaysWrapper.elementsByTagNameNS(QString(), QLatin1String(
"day"));
276 for (QList<QDomElement>::ConstIterator it = days.constBegin(); it != days.constEnd(); ++it)
278 if (weekDays.contains((*it).text()))
279 skipDays.insert(weekDays[(*it).text()]);
290 QList<QDomElement> itemNodes = elementsByTagNameNS(QString(), QLatin1String(
"item"));
292 DocumentPtr doccpy(
new Document(*
this));
294 for (QList<QDomElement>::ConstIterator it = itemNodes.constBegin(); it != itemNodes.constEnd(); ++it)
296 items.append(Item(*it, doccpy));
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()));
328 QList<QDomElement> notHandled;
330 QDomNodeList children = element().childNodes();
331 for (
int i = 0; i < children.size(); ++i)
333 QDomElement el = children.at(i).toElement();
335 && !handled.contains(ElementType(el.localName(), el.namespaceURI())))
337 notHandled.append(el);
347 info += QLatin1String(
"### Document: ###################\n");
348 if (!
title().isNull())
349 info += QLatin1String(
"title: #") +
title() + QLatin1String(
"#\n");
351 info += QLatin1String(
"description: #") +
description() + QLatin1String(
"#\n");
352 if (!
link().isNull())
353 info += QLatin1String(
"link: #") +
link() + QLatin1String(
"#\n");
355 info += QLatin1String(
"language: #") +
language() + QLatin1String(
"#\n");
357 info += QLatin1String(
"copyright: #") +
copyright() + QLatin1String(
"#\n");
359 info += QLatin1String(
"managingEditor: #") +
managingEditor() + QLatin1String(
"#\n");
361 info += QLatin1String(
"webMaster: #") +
webMaster() + QLatin1String(
"#\n");
363 QString dpubdate = dateTimeToString(
pubDate());
364 if (!dpubdate.isNull())
365 info += QLatin1String(
"pubDate: #") + dpubdate + QLatin1String(
"#\n");
368 if (!dlastbuilddate.isNull())
369 info += QLatin1String(
"lastBuildDate: #") + dlastbuilddate + QLatin1String(
"#\n");
373 if (!
cloud().isNull())
375 if (!
image().isNull())
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");
389 void Document::getItemTitleFormatInfo(
bool* isCDATA,
bool* containsMarkup)
const
391 if (!d->itemTitlesGuessed)
394 QList<Item> litems =
items();
396 if (litems.isEmpty())
398 d->itemTitlesGuessed =
true;
402 QDomElement titleEl = (*litems.begin()).firstElementByTagNameNS(QString(), QLatin1String(
"title"));
403 d->itemTitleIsCDATA = titleEl.firstChild().isCDATASection();
405 int nmax = litems.size() < 10 ? litems.size() : 10;
408 QList<Item>::ConstIterator it = litems.constBegin();
412 titles += (*it).originalTitle();
417 d->itemTitleContainsMarkup = stringContainsMarkup(titles);
418 d->itemTitlesGuessed =
true;
422 *isCDATA = d->itemTitleIsCDATA;
423 if (containsMarkup != 0L)
424 *containsMarkup = d->itemTitleContainsMarkup;
427 void Document::getItemDescriptionFormatInfo(
bool* isCDATA,
bool* containsMarkup)
const
429 if (!d->itemDescGuessed)
432 QList<Item> litems =
items();
435 if (litems.isEmpty())
437 d->itemDescGuessed =
true;
441 QDomElement descEl = (*litems.begin()).firstElementByTagNameNS(QString(), QLatin1String(
"description"));
442 d->itemDescriptionIsCDATA = descEl.firstChild().isCDATASection();
444 int nmax = litems.size() < 10 ? litems.size() : 10;
447 QList<Item>::ConstIterator it = litems.constBegin();
451 desc += (*it).originalDescription();
456 d->itemDescriptionContainsMarkup = stringContainsMarkup(desc);
457 d->itemDescGuessed =
true;
461 *isCDATA = d->itemDescriptionIsCDATA;
462 if (containsMarkup != 0L)
463 *containsMarkup = d->itemDescriptionContainsMarkup;
468 return visitor->visitRSS2Document(
this);