summaryrefslogtreecommitdiffstats
path: root/src/plugins/rssfeed/rss/article.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/rssfeed/rss/article.cpp')
-rw-r--r--src/plugins/rssfeed/rss/article.cpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/plugins/rssfeed/rss/article.cpp b/src/plugins/rssfeed/rss/article.cpp
new file mode 100644
index 0000000..14c9f21
--- /dev/null
+++ b/src/plugins/rssfeed/rss/article.cpp
@@ -0,0 +1,268 @@
+/*
+ * article.cpp
+ *
+ * Copyright (c) 2001, 2002, 2003, 2004 Frerich Raabe <[email protected]>
+ *
+ * This program 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. For licensing and distribution details, check the
+ * accompanying file 'COPYING'.
+ */
+#include "article.h"
+#include "tools_p.h"
+
+#include <kdebug.h>
+#include <krfcdate.h>
+#include <kurl.h>
+#include <kurllabel.h>
+#include <kmdcodec.h>
+
+#include <tqdatetime.h>
+#include <tqdom.h>
+
+using namespace RSS;
+namespace RSS
+{
+ KMD5 md5Machine;
+}
+
+struct Article::Private : public Shared
+{
+ TQString title;
+ KURL link;
+ TQString description;
+ TQDateTime pubDate;
+ TQString guid;
+ bool guidIsPermaLink;
+ MetaInfoMap meta;
+ KURL commentsLink;
+ int numComments;
+};
+
+Article::Article() : d(new Private)
+{
+}
+
+Article::Article(const Article &other) : d(0)
+{
+ *this = other;
+}
+
+Article::Article(const TQDomNode &node, Format format) : d(new Private)
+{
+ TQString elemText;
+
+ d->numComments=0;
+
+ if (!(elemText = extractNode(node, TQString::fromLatin1("title"))).isNull())
+ d->title = elemText;
+
+
+ TQDomNode n;
+ bool foundTorrentEnclosure = false;
+ for (n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ const TQDomElement e = n.toElement();
+ if ( (e.tagName()==TQString::fromLatin1("enclosure") ) )
+ {
+ TQString enclosureAttr = e.attribute(TQString::fromLatin1("type"));
+ if (!enclosureAttr.isNull() )
+ {
+ if (enclosureAttr == "application/x-bittorrent")
+ {
+ enclosureAttr = e.attribute(TQString::fromLatin1("url"));
+ if (!enclosureAttr.isNull() )
+ {
+ d->link=enclosureAttr;
+ foundTorrentEnclosure = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (!foundTorrentEnclosure)
+ {
+ if (format==AtomFeed)
+ {
+ TQDomNode n;
+ for (n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ const TQDomElement e = n.toElement();
+ if ( (e.tagName()==TQString::fromLatin1("link")) &&
+ (e.attribute(TQString::fromLatin1("rel"))==TQString::fromLatin1("alternate")))
+ {
+ d->link=n.toElement().attribute(TQString::fromLatin1("href"));
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (!(elemText = extractNode(node, TQString::fromLatin1("link"))).isNull())
+ d->link = elemText;
+ }
+ }
+
+
+ // prefer content/content:encoded over summary/description for feeds that provide it
+ TQString tagName=(format==AtomFeed)? TQString::fromLatin1("content"): TQString::fromLatin1("content:encoded");
+
+ if (!(elemText = extractNode(node, tagName, false)).isNull())
+ d->description = elemText;
+
+ if (d->description.isEmpty())
+ {
+ if (!(elemText = extractNode(node, TQString::fromLatin1("body"), false)).isNull())
+ d->description = elemText;
+
+ if (d->description.isEmpty()) // 3rd try: see http://www.intertwingly.net/blog/1299.html
+ {
+ if (!(elemText = extractNode(node, TQString::fromLatin1((format==AtomFeed)? "summary" : "description"), false)).isNull())
+ d->description = elemText;
+ }
+ }
+
+ if (!(elemText = extractNode(node, TQString::fromLatin1((format==AtomFeed)? "created": "pubDate"))).isNull())
+ {
+ time_t _time;
+ if (format==AtomFeed)
+ _time = parseISO8601Date(elemText);
+ else
+ _time = KRFCDate::parseDate(elemText);
+
+ // 0 means invalid, not epoch (it returns epoch+1 when it parsed epoch, see the KRFCDate::parseDate() docs)
+ if (_time != 0)
+ d->pubDate.setTime_t(_time);
+ }
+ if (!(elemText = extractNode(node, TQString::fromLatin1("dc:date"))).isNull())
+ {
+ time_t _time = parseISO8601Date(elemText);
+
+ // 0 means invalid, not epoch (it returns epoch+1 when it parsed epoch, see the KRFCDate::parseDate() docs)
+ if (_time != 0)
+ d->pubDate.setTime_t(_time);
+ }
+
+ //no luck so far - so let's set it to the current time
+ if (!d->pubDate.isValid())
+ {
+ d->pubDate = TQDateTime::currentDateTime();
+ }
+
+
+ if (!(elemText = extractNode(node, TQString::fromLatin1("wfw:comment"))).isNull()) {
+ d->commentsLink = elemText;
+ }
+
+ if (!(elemText = extractNode(node, TQString::fromLatin1("slash:comments"))).isNull()) {
+ d->numComments = elemText.toInt();
+ }
+
+ tagName=(format==AtomFeed)? TQString::fromLatin1("id"): TQString::fromLatin1("guid");
+ n = node.namedItem(tagName);
+ if (!n.isNull()) {
+ d->guidIsPermaLink = (format==AtomFeed)? false : true;
+ if (n.toElement().attribute(TQString::fromLatin1("isPermaLink"), "true") == "false") d->guidIsPermaLink = false;
+
+ if (!(elemText = extractNode(node, tagName)).isNull())
+ d->guid = elemText;
+ }
+
+ if(d->guid.isEmpty()) {
+ d->guidIsPermaLink = false;
+
+ md5Machine.reset();
+ TQDomNode n(node);
+ md5Machine.update(d->title.utf8());
+ md5Machine.update(d->description.utf8());
+ d->guid = TQString(md5Machine.hexDigest().data());
+ d->meta[TQString::fromLatin1("guidIsHash")] = TQString::fromLatin1("true");
+ }
+
+ for (TQDomNode i = node.firstChild(); !i.isNull(); i = i.nextSibling())
+ {
+ if (i.isElement() && i.toElement().tagName() == TQString::fromLatin1("metaInfo:meta"))
+ {
+ TQString type = i.toElement().attribute(TQString::fromLatin1("type"));
+ d->meta[type] = i.toElement().text();
+ }
+ }
+}
+
+Article::~Article()
+{
+ if (d->deref())
+ delete d;
+}
+
+TQString Article::title() const
+{
+ return d->title;
+}
+
+const KURL &Article::link() const
+{
+ return d->link;
+}
+
+TQString Article::description() const
+{
+ return d->description;
+}
+
+TQString Article::guid() const
+{
+ return d->guid;
+}
+
+bool Article::guidIsPermaLink() const
+{
+ return d->guidIsPermaLink;
+}
+
+const TQDateTime &Article::pubDate() const
+{
+ return d->pubDate;
+}
+
+const KURL &Article::commentsLink() const
+{
+ return d->commentsLink;
+}
+
+int Article::comments() const
+{
+ return d->numComments;
+}
+
+
+TQString Article::meta(const TQString &key) const
+{
+ return d->meta[key];
+}
+
+KURLLabel *Article::widget(TQWidget *parent, const char *name) const
+{
+ KURLLabel *label = new KURLLabel(d->link.url(), d->title, parent, name);
+ label->setUseTips(true);
+ if (!d->description.isNull())
+ label->setTipText(d->description);
+
+ return label;
+}
+
+Article &Article::operator=(const Article &other)
+{
+ if (this != &other) {
+ other.d->ref();
+ if (d && d->deref())
+ delete d;
+ d = other.d;
+ }
+ return *this;
+}
+
+bool Article::operator==(const Article &other) const
+{
+ return d->guid == other.guid();
+}