mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 19:02:53 +00:00
317 lines
8.7 KiB
C++
317 lines
8.7 KiB
C++
![]() |
/*
|
||
|
* This file is part of the syndication library
|
||
|
*
|
||
|
* Copyright (C) 2005 Frank Osterfeld <osterfeld@kde.org>
|
||
|
*
|
||
|
* 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 <rss2/item.h>
|
||
|
#include <rss2/category.h>
|
||
|
#include <rss2/enclosure.h>
|
||
|
#include <rss2/source.h>
|
||
|
#include <rss2/tools_p.h>
|
||
|
#include <constants.h>
|
||
|
#include <specificitem.h>
|
||
|
#include <specificitemvisitor.h>
|
||
|
#include <tools.h>
|
||
|
|
||
|
#include <QtXml/QDomElement>
|
||
|
#include <QtCore/QString>
|
||
|
#include <QtCore/QList>
|
||
|
|
||
|
namespace Syndication {
|
||
|
namespace RSS2 {
|
||
|
|
||
|
class Item::ItemPrivate
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
boost::shared_ptr<Document> doc;
|
||
|
};
|
||
|
|
||
|
Item::Item(boost::shared_ptr<Document> doc) : ElementWrapper(), d(new ItemPrivate)
|
||
|
{
|
||
|
d->doc = doc;
|
||
|
}
|
||
|
|
||
|
Item::Item(const QDomElement& element, boost::shared_ptr<Document> 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<Category> Item::categories() const
|
||
|
{
|
||
|
QList<QDomElement> cats = elementsByTagNameNS(QString(),
|
||
|
QLatin1String("category"));
|
||
|
|
||
|
QList<Category> categories;
|
||
|
|
||
|
QList<QDomElement>::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<Enclosure> Item::enclosures() const
|
||
|
{
|
||
|
QList<QDomElement> encs = elementsByTagNameNS(QString(),
|
||
|
QLatin1String("enclosure"));
|
||
|
|
||
|
QList<Enclosure> enclosures;
|
||
|
|
||
|
QList<QDomElement>::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<Category> cats = categories();
|
||
|
for (QList<Category>::ConstIterator it = cats.constBegin(); it != cats.constEnd(); ++it)
|
||
|
info += (*it).debugInfo();
|
||
|
QList<Enclosure> encs = enclosures();
|
||
|
for (QList<Enclosure>::ConstIterator it = encs.constBegin(); it != encs.constEnd(); ++it)
|
||
|
info += (*it).debugInfo();
|
||
|
|
||
|
info += QLatin1String("### Item end ################\n");
|
||
|
return info;
|
||
|
}
|
||
|
|
||
|
QList<QDomElement> Item::unhandledElements() const
|
||
|
{
|
||
|
// TODO: do not hardcode this list here
|
||
|
QList<ElementType> 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<QDomElement> 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
|