File indexing completed on 2023-10-03 03:26:48
0001 /* 0002 This file is part of the syndication library 0003 SPDX-FileCopyrightText: 2006 Frank Osterfeld <osterfeld@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "entry.h" 0009 #include "atomtools.h" 0010 #include "category.h" 0011 #include "constants.h" 0012 #include "content.h" 0013 #include "link.h" 0014 #include "person.h" 0015 #include "source.h" 0016 0017 #include <specificitemvisitor.h> 0018 #include <tools.h> 0019 0020 #include <QDomElement> 0021 #include <QString> 0022 0023 #include <vector> 0024 0025 namespace Syndication 0026 { 0027 namespace Atom 0028 { 0029 Entry::Entry() 0030 : ElementWrapper() 0031 { 0032 } 0033 0034 Entry::Entry(const QDomElement &element) 0035 : ElementWrapper(element) 0036 { 0037 } 0038 0039 void Entry::setFeedAuthors(const QList<Person> &feedAuthors) 0040 { 0041 m_feedAuthors = feedAuthors; 0042 } 0043 0044 QList<Person> Entry::authors() const 0045 { 0046 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("author")); 0047 QList<Person> list; 0048 0049 if (!a.isEmpty()) { 0050 list.reserve(a.count()); 0051 0052 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) { 0053 return Person(element); 0054 }); 0055 } else { 0056 list = source().authors(); 0057 } 0058 0059 return !list.isEmpty() ? list : m_feedAuthors; 0060 } 0061 0062 QList<Person> Entry::contributors() const 0063 { 0064 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("contributor")); 0065 QList<Person> list; 0066 list.reserve(a.count()); 0067 0068 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) { 0069 return Person(element); 0070 }); 0071 0072 return list; 0073 } 0074 0075 QList<Category> Entry::categories() const 0076 { 0077 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("category")); 0078 QList<Category> list; 0079 list.reserve(a.count()); 0080 0081 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) { 0082 return Category(element); 0083 }); 0084 0085 return list; 0086 } 0087 0088 QString Entry::id() const 0089 { 0090 return extractElementTextNS(atom1Namespace(), QStringLiteral("id")); 0091 } 0092 0093 QList<Link> Entry::links() const 0094 { 0095 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("link")); 0096 QList<Link> list; 0097 list.reserve(a.count()); 0098 0099 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) { 0100 return Link(element); 0101 }); 0102 0103 return list; 0104 } 0105 0106 QString Entry::rights() const 0107 { 0108 return extractAtomText(*this, QStringLiteral("rights")); 0109 } 0110 0111 Source Entry::source() const 0112 { 0113 return Source(firstElementByTagNameNS(atom1Namespace(), QStringLiteral("source"))); 0114 } 0115 0116 time_t Entry::published() const 0117 { 0118 QString pub = extractElementTextNS(atom1Namespace(), QStringLiteral("published")); 0119 return parseDate(pub, ISODate); 0120 } 0121 0122 time_t Entry::updated() const 0123 { 0124 QString upd = extractElementTextNS(atom1Namespace(), QStringLiteral("updated")); 0125 return parseDate(upd, ISODate); 0126 } 0127 0128 QString Entry::summary() const 0129 { 0130 return extractAtomText(*this, QStringLiteral("summary")); 0131 } 0132 0133 QString Entry::title() const 0134 { 0135 return extractAtomText(*this, QStringLiteral("title")); 0136 } 0137 0138 Content Entry::content() const 0139 { 0140 return Content(firstElementByTagNameNS(atom1Namespace(), QStringLiteral("content"))); 0141 } 0142 0143 QList<QDomElement> Entry::unhandledElements() const 0144 { 0145 // TODO: do not hardcode this list here 0146 static std::vector<ElementType> handled; // QVector would require a default ctor, and ElementType is too big for QList 0147 if (handled.empty()) { 0148 handled.reserve(12); 0149 handled.push_back(ElementType(QStringLiteral("author"), atom1Namespace())); 0150 handled.push_back(ElementType(QStringLiteral("contributor"), atom1Namespace())); 0151 handled.push_back(ElementType(QStringLiteral("category"), atom1Namespace())); 0152 handled.push_back(ElementType(QStringLiteral("id"), atom1Namespace())); 0153 handled.push_back(ElementType(QStringLiteral("link"), atom1Namespace())); 0154 handled.push_back(ElementType(QStringLiteral("rights"), atom1Namespace())); 0155 handled.push_back(ElementType(QStringLiteral("source"), atom1Namespace())); 0156 handled.push_back(ElementType(QStringLiteral("published"), atom1Namespace())); 0157 handled.push_back(ElementType(QStringLiteral("updated"), atom1Namespace())); 0158 handled.push_back(ElementType(QStringLiteral("summary"), atom1Namespace())); 0159 handled.push_back(ElementType(QStringLiteral("title"), atom1Namespace())); 0160 handled.push_back(ElementType(QStringLiteral("content"), atom1Namespace())); 0161 } 0162 0163 QList<QDomElement> notHandled; 0164 0165 QDomNodeList children = element().childNodes(); 0166 const int numChildren = children.size(); 0167 for (int i = 0; i < numChildren; ++i) { 0168 QDomElement el = children.at(i).toElement(); 0169 if (!el.isNull() // 0170 && std::find(handled.cbegin(), handled.cend(), ElementType(el.localName(), el.namespaceURI())) == handled.cend()) { 0171 notHandled.append(el); 0172 } 0173 } 0174 0175 return notHandled; 0176 } 0177 0178 QString Entry::debugInfo() const 0179 { 0180 QString info; 0181 info += QLatin1String("### Entry: ###################\n"); 0182 if (!title().isEmpty()) { 0183 info += QLatin1String("title: #") + title() + QLatin1String("#\n"); 0184 } 0185 if (!summary().isEmpty()) { 0186 info += QLatin1String("summary: #") + summary() + QLatin1String("#\n"); 0187 } 0188 if (!id().isEmpty()) { 0189 info += QLatin1String("id: #") + id() + QLatin1String("#\n"); 0190 } 0191 if (!content().isNull()) { 0192 info += content().debugInfo(); 0193 } 0194 0195 if (!rights().isEmpty()) { 0196 info += QLatin1String("rights: #") + rights() + QLatin1String("#\n"); 0197 } 0198 0199 QString dupdated = dateTimeToString(updated()); 0200 if (!dupdated.isNull()) { 0201 info += QLatin1String("updated: #") + dupdated + QLatin1String("#\n"); 0202 } 0203 0204 QString dpublished = dateTimeToString(published()); 0205 if (!dpublished.isNull()) { 0206 info += QLatin1String("published: #") + dpublished + QLatin1String("#\n"); 0207 } 0208 0209 const QList<Link> dlinks = links(); 0210 for (const auto &link : dlinks) { 0211 info += link.debugInfo(); 0212 } 0213 0214 const QList<Category> dcats = categories(); 0215 for (const auto &cat : dcats) { 0216 info += cat.debugInfo(); 0217 } 0218 0219 info += QLatin1String("### Authors: ###################\n"); 0220 0221 const QList<Person> dauthors = authors(); 0222 for (const auto &author : dauthors) { 0223 info += author.debugInfo(); 0224 } 0225 0226 info += QLatin1String("### Contributors: ###################\n"); 0227 0228 const QList<Person> dcontri = contributors(); 0229 for (const auto &person : dcontri) { 0230 info += person.debugInfo(); 0231 } 0232 0233 if (!source().isNull()) { 0234 info += source().debugInfo(); 0235 } 0236 0237 info += QLatin1String("### Entry end ################\n"); 0238 0239 return info; 0240 } 0241 0242 bool Entry::accept(SpecificItemVisitor *visitor) 0243 { 0244 return visitor->visitAtomEntry(this); 0245 } 0246 0247 } // namespace Atom 0248 } // namespace Syndication