akregator/src/librss
article.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "article.h"
00012 #include "tools_p.h"
00013 #include "enclosure.h"
00014 #include "category.h"
00015
00016 #include <kdebug.h>
00017 #include <krfcdate.h>
00018 #include <kurl.h>
00019 #include <kurllabel.h>
00020 #include <kmdcodec.h>
00021
00022 #include <qdatetime.h>
00023 #include <qdom.h>
00024
00025 using namespace RSS;
00026 namespace RSS
00027 {
00028 KMD5 md5Machine;
00029 }
00030
00031 struct Article::Private : public Shared
00032 {
00033 QString title;
00034 KURL link;
00035 QString description;
00036 QDateTime pubDate;
00037 QString guid;
00038 QString author;
00039 bool guidIsPermaLink;
00040 MetaInfoMap meta;
00041 KURL commentsLink;
00042 int numComments;
00043 Enclosure enclosure;
00044 QValueList<Category> categories;
00045 };
00046
00047 Article::Article() : d(new Private)
00048 {
00049 }
00050
00051 Article::Article(const Article &other) : d(0)
00052 {
00053 *this = other;
00054 }
00055
00056 Enclosure Article::enclosure() const
00057 {
00058 return d->enclosure;
00059 }
00060
00061 QValueList<Category> Article::categories() const
00062 {
00063 return d->categories;
00064 }
00065
00066
00067 Article::Article(const QDomNode &node, Format format, Version version) : d(new Private)
00068 {
00069 QString elemText;
00070
00071 d->numComments=0;
00072
00073 if (!(elemText = extractTitle(node)).isNull())
00074 d->title = elemText;
00075
00076 if (format==AtomFeed)
00077 {
00078 QDomNode n;
00079 for (n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
00080 const QDomElement e = n.toElement();
00081 if ( (e.tagName()==QString::fromLatin1("link")) &&
00082 (e.attribute(QString::fromLatin1("rel"), QString::fromLatin1("alternate")) == QString::fromLatin1("alternate")))
00083 {
00084 d->link=n.toElement().attribute(QString::fromLatin1("href"));
00085 break;
00086 }
00087 }
00088 }
00089 else
00090 {
00091 if (!(elemText = extractNode(node, QString::fromLatin1("link"))).isNull())
00092 d->link = elemText;
00093 }
00094
00095
00096
00097 QString tagName=(format==AtomFeed)? QString::fromLatin1("content"): QString::fromLatin1("content:encoded");
00098
00099 if (!(elemText = extractNode(node, tagName, false)).isNull())
00100 d->description = elemText;
00101
00102 if (d->description.isEmpty())
00103 {
00104 if (!(elemText = extractNode(node, QString::fromLatin1("body"), false)).isNull())
00105 d->description = elemText;
00106
00107 if (d->description.isEmpty())
00108 {
00109 if (!(elemText = extractNode(node, QString::fromLatin1((format==AtomFeed)? "summary" : "description"), false)).isNull())
00110 d->description = elemText;
00111 }
00112 }
00113
00114 time_t time = 0;
00115
00116 if (format == AtomFeed)
00117 {
00118 if (version == vAtom_1_0)
00119 elemText = extractNode(node, QString::fromLatin1("updated"));
00120 else
00121 elemText = extractNode(node, QString::fromLatin1("issued"));
00122
00123 if (!elemText.isNull())
00124 time = parseISO8601Date(elemText);
00125 }
00126 else
00127 {
00128 elemText = extractNode(node, QString::fromLatin1("pubDate"));
00129 if (!elemText.isNull())
00130 time = KRFCDate::parseDate(elemText);
00131 }
00132
00133 if (!(elemText = extractNode(node, QString::fromLatin1("dc:date"))).isNull())
00134 {
00135 time = parseISO8601Date(elemText);
00136 }
00137
00138
00139 if (time != 0)
00140 d->pubDate.setTime_t(time);
00141
00142 if (!(elemText = extractNode(node, QString::fromLatin1("wfw:comment"))).isNull()) {
00143 d->commentsLink = elemText;
00144 }
00145
00146 if (!(elemText = extractNode(node, QString::fromLatin1("slash:comments"))).isNull()) {
00147 d->numComments = elemText.toInt();
00148 }
00149
00150 QDomElement element = QDomNode(node).toElement();
00151
00152
00153
00154
00155 if (!element.isNull() && element.hasAttribute(QString::fromLatin1("rdf:about")))
00156 {
00157 d->guid = element.attribute(QString::fromLatin1("rdf:about"));
00158 d->guidIsPermaLink = false;
00159 }
00160 else
00161 {
00162 tagName=(format==AtomFeed)? QString::fromLatin1("id"): QString::fromLatin1("guid");
00163 QDomNode n = node.namedItem(tagName);
00164 if (!n.isNull())
00165 {
00166 d->guidIsPermaLink = (format==AtomFeed)? false : true;
00167 if (n.toElement().attribute(QString::fromLatin1("isPermaLink"), "true") == "false") d->guidIsPermaLink = false;
00168 if (!(elemText = extractNode(node, tagName)).isNull())
00169 d->guid = elemText;
00170 }
00171 }
00172
00173 if(d->guid.isEmpty()) {
00174 d->guidIsPermaLink = false;
00175
00176 md5Machine.reset();
00177 QDomNode n(node);
00178 md5Machine.update(d->title.utf8());
00179 md5Machine.update(d->description.utf8());
00180 d->guid = QString(md5Machine.hexDigest().data());
00181 d->meta[QString::fromLatin1("guidIsHash")] = QString::fromLatin1("true");
00182 }
00183
00184 QDomNode enclosure = element.namedItem(QString::fromLatin1("enclosure"));
00185 if (enclosure.isElement())
00186 d->enclosure = Enclosure::fromXML(enclosure.toElement());
00187
00188 d->author = parseItemAuthor(element, format, version);
00189
00190 for (QDomNode i = node.firstChild(); !i.isNull(); i = i.nextSibling())
00191 {
00192 if (i.isElement())
00193 {
00194 if (i.toElement().tagName() == QString::fromLatin1("metaInfo:meta"))
00195 {
00196 QString type = i.toElement().attribute(QString::fromLatin1("type"));
00197 d->meta[type] = i.toElement().text();
00198 }
00199 else if (i.toElement().tagName() == QString::fromLatin1("category"))
00200 {
00201 d->categories.append(Category::fromXML(i.toElement()));
00202 }
00203 }
00204 }
00205 }
00206
00207 Article::~Article()
00208 {
00209 if (d->deref())
00210 delete d;
00211 }
00212
00213 QString Article::title() const
00214 {
00215 return d->title;
00216 }
00217
00218 QString Article::author() const
00219 {
00220 return d->author;
00221 }
00222
00223 const KURL &Article::link() const
00224 {
00225 return d->link;
00226 }
00227
00228 QString Article::description() const
00229 {
00230 return d->description;
00231 }
00232
00233 QString Article::guid() const
00234 {
00235 return d->guid;
00236 }
00237
00238 bool Article::guidIsPermaLink() const
00239 {
00240 return d->guidIsPermaLink;
00241 }
00242
00243 const QDateTime &Article::pubDate() const
00244 {
00245 return d->pubDate;
00246 }
00247
00248 const KURL &Article::commentsLink() const
00249 {
00250 return d->commentsLink;
00251 }
00252
00253 int Article::comments() const
00254 {
00255 return d->numComments;
00256 }
00257
00258
00259 QString Article::meta(const QString &key) const
00260 {
00261 return d->meta[key];
00262 }
00263
00264 KURLLabel *Article::widget(QWidget *parent, const char *name) const
00265 {
00266 KURLLabel *label = new KURLLabel(d->link.url(), d->title, parent, name);
00267 label->setUseTips(true);
00268 if (!d->description.isNull())
00269 label->setTipText(d->description);
00270
00271 return label;
00272 }
00273
00274 Article &Article::operator=(const Article &other)
00275 {
00276 if (this != &other) {
00277 other.d->ref();
00278 if (d && d->deref())
00279 delete d;
00280 d = other.d;
00281 }
00282 return *this;
00283 }
00284
00285 bool Article::operator==(const Article &other) const
00286 {
00287 return d->guid == other.guid();
00288 }
00289
00290
|