/* * This file is part of the syndication library * * Copyright (C) 2005 Frank Osterfeld * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include namespace Syndication { namespace RSS2 { class Item::ItemPrivate { public: boost::shared_ptr doc; }; Item::Item(boost::shared_ptr doc) : ElementWrapper(), d(new ItemPrivate) { d->doc = doc; } Item::Item(const QDomElement& element, boost::shared_ptr doc) : ElementWrapper(element), d(new ItemPrivate) { d->doc = doc; } Item::~Item() { } Item::Item(const Item& other) : ElementWrapper(other), SpecificItem(other) { d = other.d; } Item& Item::operator=(const Item& other) { ElementWrapper::operator=(other); SpecificItem::operator=(other); d = other.d; return *this; } QString Item::title() const { if (!d->doc) return originalTitle(); bool isCDATA = false; bool containsMarkup = false; d->doc->getItemTitleFormatInfo(&isCDATA, &containsMarkup); return normalize(originalTitle(), isCDATA, containsMarkup); } QString Item::originalDescription() const { return extractElementTextNS(QString(), QLatin1String("description")); } QString Item::originalTitle() const { return extractElementTextNS(QString(), QLatin1String("title")); } QString Item::link() const { QString url = extractElementTextNS(QString(), QLatin1String("link") ); if (url.startsWith(QLatin1String("http://")) || url.startsWith(QLatin1String("https://"))) { return url; } if (url.isEmpty()) { return QString(); } if (d->doc->link().isEmpty()) { return url; } // link does not look like a complete url, assume the feed author expects // the doc link to provide the base of the url. QString baseUrl = d->doc->link(); if (url.startsWith(QLatin1Char('/')) || baseUrl.endsWith(QLatin1Char('/'))) { return baseUrl + url; } else { return baseUrl + QLatin1Char('/') + url; } } QString Item::description() const { if (!d->doc) return originalDescription(); bool isCDATA = false; bool containsMarkup = false; d->doc->getItemDescriptionFormatInfo(&isCDATA, &containsMarkup); return normalize(originalDescription(), isCDATA, containsMarkup); } QString Item::content() const { // parse encoded stuff from content:encoded, xhtml:body and friends into content return extractContent(*this); } QList Item::categories() const { QList cats = elementsByTagNameNS(QString(), QLatin1String("category")); QList categories; QList::ConstIterator it = cats.constBegin(); for ( ; it != cats.constEnd(); ++it) { categories.append(Category(*it)); } return categories; } QString Item::comments() const { return extractElementTextNS(QString(), QLatin1String("comments") ); } QString Item::author() const { QString a = extractElementTextNS(QString(), QLatin1String("author") ); if (!a.isNull()) { return a; } else { // if author is not available, fall back to dc:creator return extractElementTextNS(dublinCoreNamespace(), QLatin1String("creator") ); } } QList Item::enclosures() const { QList encs = elementsByTagNameNS(QString(), QLatin1String("enclosure")); QList enclosures; QList::ConstIterator it = encs.constBegin(); for ( ; it != encs.constEnd(); ++it) { enclosures.append(Enclosure(*it)); } return enclosures; } QString Item::guid() const { return extractElementTextNS(QString(), QLatin1String("guid") ); } bool Item::guidIsPermaLink() const { bool guidIsPermaLink = true; // true is default QDomElement guidNode = firstElementByTagNameNS(QString(), QLatin1String("guid")); if (!guidNode.isNull()) { if (guidNode.attribute(QLatin1String("isPermaLink")) == QLatin1String("false")) { guidIsPermaLink = false; } } return guidIsPermaLink; } time_t Item::pubDate() const { QString str = extractElementTextNS(QString(), QLatin1String("pubDate")); if (!str.isNull()) { return parseDate(str, RFCDate); } // if there is no pubDate, check for dc:date str = extractElementTextNS(dublinCoreNamespace(), QLatin1String("date")); return parseDate(str, ISODate); } time_t Item::expirationDate() const { QString str = extractElementTextNS(QString(), QLatin1String("expirationDate")); return parseDate(str, RFCDate); } Source Item::source() const { return Source(firstElementByTagNameNS(QString(), QLatin1String("source"))); } QString Item::rating() const { return extractElementTextNS(QString(), QLatin1String("rating") ); } QString Item::debugInfo() const { QString info; info += QLatin1String("### Item: ###################\n"); if (!title().isNull()) info += QLatin1String("title: #") + title() + QLatin1String("#\n"); if (!link().isNull()) info += QLatin1String("link: #") + link() + QLatin1String("#\n"); if (!description().isNull()) info += QLatin1String("description: #") + description() + QLatin1String("#\n"); if (!content().isNull()) info += QLatin1String("content: #") + content() + QLatin1String("#\n"); if (!author().isNull()) info += QLatin1String("author: #") + author() + QLatin1String("#\n"); if (!comments().isNull()) info += QLatin1String("comments: #") + comments() + QLatin1String("#\n"); QString dpubdate = dateTimeToString(pubDate()); if (!dpubdate.isNull()) info += QLatin1String("pubDate: #") + dpubdate + QLatin1String("#\n"); if (!guid().isNull()) info += QLatin1String("guid: #") + guid() + QLatin1String("#\n"); if (guidIsPermaLink()) info += QLatin1String("guid is PL: #true#\n"); if (!source().isNull()) info += source().debugInfo(); QList cats = categories(); for (QList::ConstIterator it = cats.constBegin(); it != cats.constEnd(); ++it) info += (*it).debugInfo(); QList encs = enclosures(); for (QList::ConstIterator it = encs.constBegin(); it != encs.constEnd(); ++it) info += (*it).debugInfo(); info += QLatin1String("### Item end ################\n"); return info; } QList Item::unhandledElements() const { // TODO: do not hardcode this list here QList handled; handled.append(ElementType(QLatin1String("title"))); handled.append(ElementType(QLatin1String("link"))); handled.append(ElementType(QLatin1String("description"))); handled.append(ElementType(QLatin1String("pubDate"))); handled.append(ElementType(QLatin1String("expirationDate"))); handled.append(ElementType(QLatin1String("rating"))); handled.append(ElementType(QLatin1String("source"))); handled.append(ElementType(QLatin1String("guid"))); handled.append(ElementType(QLatin1String("comments"))); handled.append(ElementType(QLatin1String("author"))); handled.append(ElementType(QLatin1String("date"), dublinCoreNamespace())); QList notHandled; QDomNodeList children = element().childNodes(); for (int i = 0; i < children.size(); ++i) { QDomElement el = children.at(i).toElement(); if (!el.isNull() && !handled.contains(ElementType(el.localName(), el.namespaceURI()))) { notHandled.append(el); } } return notHandled; } bool Item::accept(SpecificItemVisitor* visitor) { return visitor->visitRSS2Item(this); } } // namespace RSS2 } // namespace Syndication