File indexing completed on 2024-05-12 16:23:39

0001 /**
0002  * SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "entry.h"
0008 
0009 #include <QDesktopServices>
0010 #include <QRegularExpression>
0011 #include <QSqlQuery>
0012 #include <QUrl>
0013 
0014 #include "database.h"
0015 
0016 Entry::Entry(Feed *feed, int index)
0017     : QObject(nullptr)
0018     , m_feed(feed)
0019 {
0020     QSqlQuery entryQuery;
0021     bool entryQueryPrepared = false;
0022     if (m_feed) {
0023         entryQueryPrepared = entryQuery.prepare(QStringLiteral("SELECT * FROM Entries WHERE feed=:feed ORDER BY updated DESC LIMIT 1 OFFSET :index;"));
0024         entryQuery.bindValue(QStringLiteral(":feed"), m_feed->url());
0025     } else {
0026         entryQueryPrepared = entryQuery.prepare(QStringLiteral("SELECT * FROM Entries ORDER BY updated DESC LIMIT 1 OFFSET :index;"));
0027     }
0028     if (entryQueryPrepared) {
0029         entryQuery.bindValue(QStringLiteral(":index"), index);
0030         Database::instance().execute(entryQuery);
0031         if (!entryQuery.next()) {
0032             qWarning() << "No element with index" << index << "found";
0033             if (m_feed) {
0034                 qDebug() << " in feed" << m_feed->url();
0035             }
0036         }
0037     }
0038 
0039     QSqlQuery authorQuery;
0040     if (authorQuery.prepare(QStringLiteral("SELECT * FROM Authors WHERE id=:id"))) {
0041         authorQuery.bindValue(QStringLiteral(":id"), entryQuery.value(QStringLiteral("id")).toString());
0042         Database::instance().execute(authorQuery);
0043 
0044         while (authorQuery.next()) {
0045             m_authors += new Author(authorQuery.value(QStringLiteral("name")).toString(),
0046                                     authorQuery.value(QStringLiteral("email")).toString(),
0047                                     authorQuery.value(QStringLiteral("uri")).toString(),
0048                                     nullptr);
0049         }
0050     }
0051 
0052     m_created.setSecsSinceEpoch(entryQuery.value(QStringLiteral("created")).toInt());
0053     m_updated.setSecsSinceEpoch(entryQuery.value(QStringLiteral("updated")).toInt());
0054 
0055     m_id = entryQuery.value(QStringLiteral("id")).toString();
0056     m_title = entryQuery.value(QStringLiteral("title")).toString();
0057     m_content = entryQuery.value(QStringLiteral("content")).toString();
0058     m_link = entryQuery.value(QStringLiteral("link")).toString();
0059     m_read = entryQuery.value(QStringLiteral("read")).toBool();
0060 }
0061 
0062 Entry::~Entry()
0063 {
0064     qDeleteAll(m_authors);
0065 }
0066 
0067 QString Entry::id() const
0068 {
0069     return m_id;
0070 }
0071 
0072 QString Entry::title() const
0073 {
0074     return m_title;
0075 }
0076 
0077 QString Entry::content() const
0078 {
0079     return m_content;
0080 }
0081 
0082 QVector<Author *> Entry::authors() const
0083 {
0084     return m_authors;
0085 }
0086 
0087 QDateTime Entry::created() const
0088 {
0089     return m_created;
0090 }
0091 
0092 QDateTime Entry::updated() const
0093 {
0094     return m_updated;
0095 }
0096 
0097 QString Entry::link() const
0098 {
0099     return m_link;
0100 }
0101 
0102 bool Entry::read() const
0103 {
0104     return m_read;
0105 }
0106 
0107 QString Entry::baseUrl() const
0108 {
0109     return QUrl(m_link).adjusted(QUrl::RemovePath).toString();
0110 }
0111 
0112 void Entry::openLink(const QString &link)
0113 {
0114     QUrl url(link);
0115     if (link.startsWith(QStringLiteral("//"))) {
0116         // we a protocol-relative, see https://en.wikipedia.org/wiki/Wikipedia:Protocol-relative_URL
0117         url.setScheme(QUrl(m_link).scheme());
0118     }
0119     QDesktopServices::openUrl(url);
0120 }
0121 
0122 void Entry::setRead(bool read)
0123 {
0124     m_read = read;
0125     Q_EMIT readChanged(m_read);
0126     Database::instance().setRead(m_id, m_read);
0127     if (m_feed) {
0128         Q_EMIT m_feed->unreadEntryCountChanged();
0129     }
0130 }
0131 
0132 QString Entry::adjustedContent(int width, int fontSize)
0133 {
0134     QString ret(m_content);
0135     QRegularExpression imgRegex(QStringLiteral("<img ((?!width=\"[0-9]+(px)?\").)*(width=\"([0-9]+)(px)?\")?[^>]*>"));
0136 
0137     QRegularExpressionMatchIterator i = imgRegex.globalMatch(ret);
0138     while (i.hasNext()) {
0139         QRegularExpressionMatch match = i.next();
0140 
0141         QString imgTag(match.captured());
0142         if (imgTag.contains(QStringLiteral("wp-smiley"))) {
0143             imgTag.insert(4, QStringLiteral(" width=\"%1\"").arg(fontSize));
0144         }
0145 
0146         QString widthParameter = match.captured(4);
0147 
0148         if (widthParameter.length() != 0) {
0149             if (widthParameter.toInt() > width) {
0150                 imgTag.replace(match.captured(3), QStringLiteral("width=\"%1\"").arg(width));
0151                 imgTag.replace(QRegularExpression(QStringLiteral("height=\"([0-9]+)(px)?\"")), QString());
0152             }
0153         } else {
0154             imgTag.insert(4, QStringLiteral(" width=\"%1\"").arg(width));
0155         }
0156         ret.replace(match.captured(), imgTag);
0157     }
0158 
0159     ret.replace(QStringLiteral("<img"), QStringLiteral("<br /> <img"));
0160     return ret;
0161 }