2020-05-26 16:32:07 +02:00
|
|
|
/**
|
2020-08-14 20:56:04 +02:00
|
|
|
* SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
2021-04-08 13:16:36 +02:00
|
|
|
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
2020-05-26 16:32:07 +02:00
|
|
|
*
|
2020-08-14 20:56:04 +02:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
2020-05-26 16:32:07 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "entry.h"
|
2020-06-06 00:05:32 +02:00
|
|
|
|
2020-06-07 17:14:13 +02:00
|
|
|
#include <QRegularExpression>
|
2020-06-06 00:05:32 +02:00
|
|
|
#include <QSqlQuery>
|
2020-05-26 16:32:07 +02:00
|
|
|
#include <QUrl>
|
|
|
|
|
2020-06-06 00:05:32 +02:00
|
|
|
#include "database.h"
|
2021-04-07 22:10:39 +02:00
|
|
|
#include "datamanager.h"
|
2021-04-05 14:15:44 +02:00
|
|
|
#include "fetcher.h"
|
2020-06-06 00:05:32 +02:00
|
|
|
|
2021-04-02 22:31:34 +02:00
|
|
|
Entry::Entry(Feed *feed, QString id)
|
|
|
|
: QObject(nullptr)
|
|
|
|
, m_feed(feed)
|
|
|
|
{
|
2021-04-05 14:15:44 +02:00
|
|
|
connect(&Fetcher::instance(), &Fetcher::downloadFinished, this, [this](QString url) {
|
|
|
|
if(url == m_image)
|
|
|
|
Q_EMIT imageChanged(url);
|
|
|
|
});
|
2021-04-07 22:10:39 +02:00
|
|
|
connect(&DataManager::instance(), &DataManager::queueEntryAdded, this, [this](const int &index, const QString &id) {
|
|
|
|
Q_UNUSED(index)
|
|
|
|
if(id == m_id)
|
|
|
|
Q_EMIT queueStatusChanged(queueStatus());
|
|
|
|
});
|
|
|
|
connect(&DataManager::instance(), &DataManager::queueEntryRemoved, this, [this](const int &index, const QString &id) {
|
|
|
|
Q_UNUSED(index)
|
|
|
|
if(id == m_id)
|
|
|
|
Q_EMIT queueStatusChanged(queueStatus());
|
|
|
|
});
|
2021-04-02 22:31:34 +02:00
|
|
|
QSqlQuery entryQuery;
|
|
|
|
entryQuery.prepare(QStringLiteral("SELECT * FROM Entries WHERE feed=:feed AND id=:id;"));
|
|
|
|
entryQuery.bindValue(QStringLiteral(":feed"), m_feed->url());
|
|
|
|
entryQuery.bindValue(QStringLiteral(":id"), id);
|
|
|
|
Database::instance().execute(entryQuery);
|
|
|
|
if (!entryQuery.next())
|
|
|
|
qWarning() << "No element with index" << id << "found in feed" << m_feed->url();
|
|
|
|
|
|
|
|
QSqlQuery authorQuery;
|
|
|
|
authorQuery.prepare(QStringLiteral("SELECT * FROM Authors WHERE id=:id"));
|
|
|
|
authorQuery.bindValue(QStringLiteral(":id"), entryQuery.value(QStringLiteral("id")).toString());
|
|
|
|
Database::instance().execute(authorQuery);
|
|
|
|
|
|
|
|
while (authorQuery.next()) {
|
|
|
|
m_authors += new Author(authorQuery.value(QStringLiteral("name")).toString(), authorQuery.value(QStringLiteral("email")).toString(), authorQuery.value(QStringLiteral("uri")).toString(), nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_created.setSecsSinceEpoch(entryQuery.value(QStringLiteral("created")).toInt());
|
2020-06-10 00:07:08 +02:00
|
|
|
m_updated.setSecsSinceEpoch(entryQuery.value(QStringLiteral("updated")).toInt());
|
|
|
|
|
|
|
|
m_id = entryQuery.value(QStringLiteral("id")).toString();
|
|
|
|
m_title = entryQuery.value(QStringLiteral("title")).toString();
|
|
|
|
m_content = entryQuery.value(QStringLiteral("content")).toString();
|
|
|
|
m_link = entryQuery.value(QStringLiteral("link")).toString();
|
|
|
|
m_read = entryQuery.value(QStringLiteral("read")).toBool();
|
2021-04-07 10:39:12 +02:00
|
|
|
m_new = entryQuery.value(QStringLiteral("new")).toBool();
|
2021-02-21 19:54:10 +01:00
|
|
|
|
|
|
|
if (entryQuery.value(QStringLiteral("hasEnclosure")).toBool()) {
|
2021-04-03 21:39:20 +02:00
|
|
|
m_hasenclosure = true;
|
2021-02-21 19:54:10 +01:00
|
|
|
m_enclosure = new Enclosure(this);
|
|
|
|
}
|
2021-04-05 14:15:44 +02:00
|
|
|
m_image = entryQuery.value(QStringLiteral("image")).toString();
|
2020-05-26 16:32:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Entry::~Entry()
|
|
|
|
{
|
2020-11-01 13:03:04 +01:00
|
|
|
qDeleteAll(m_authors);
|
2020-05-26 16:32:07 +02:00
|
|
|
}
|
|
|
|
|
2020-06-06 00:05:32 +02:00
|
|
|
QString Entry::id() const
|
|
|
|
{
|
|
|
|
return m_id;
|
|
|
|
}
|
|
|
|
|
2020-05-26 16:32:07 +02:00
|
|
|
QString Entry::title() const
|
|
|
|
{
|
|
|
|
return m_title;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Entry::content() const
|
|
|
|
{
|
|
|
|
return m_content;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVector<Author *> Entry::authors() const
|
|
|
|
{
|
|
|
|
return m_authors;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDateTime Entry::created() const
|
|
|
|
{
|
|
|
|
return m_created;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDateTime Entry::updated() const
|
|
|
|
{
|
|
|
|
return m_updated;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Entry::link() const
|
|
|
|
{
|
|
|
|
return m_link;
|
|
|
|
}
|
|
|
|
|
2020-06-06 00:05:32 +02:00
|
|
|
bool Entry::read() const
|
|
|
|
{
|
|
|
|
return m_read;
|
|
|
|
}
|
|
|
|
|
2021-04-07 10:39:12 +02:00
|
|
|
bool Entry::getNew() const
|
|
|
|
{
|
|
|
|
return m_new;
|
|
|
|
}
|
|
|
|
|
2020-05-26 16:32:07 +02:00
|
|
|
QString Entry::baseUrl() const
|
|
|
|
{
|
|
|
|
return QUrl(m_link).adjusted(QUrl::RemovePath).toString();
|
|
|
|
}
|
2020-06-06 00:05:32 +02:00
|
|
|
|
2021-04-16 20:38:13 +02:00
|
|
|
void Entry::setRead(const bool read)
|
2020-06-06 00:05:32 +02:00
|
|
|
{
|
|
|
|
m_read = read;
|
|
|
|
Q_EMIT readChanged(m_read);
|
|
|
|
QSqlQuery query;
|
|
|
|
query.prepare(QStringLiteral("UPDATE Entries SET read=:read WHERE id=:id AND feed=:feed"));
|
|
|
|
query.bindValue(QStringLiteral(":id"), m_id);
|
|
|
|
query.bindValue(QStringLiteral(":feed"), m_feed->url());
|
|
|
|
query.bindValue(QStringLiteral(":read"), m_read);
|
|
|
|
Database::instance().execute(query);
|
2020-07-29 23:41:11 +02:00
|
|
|
Q_EMIT m_feed->unreadEntryCountChanged();
|
2021-04-17 22:54:35 +02:00
|
|
|
Q_EMIT DataManager::instance().unreadEntryCountChanged(m_feed->url());
|
|
|
|
//TODO: can one of the two slots be removed??
|
2020-06-06 00:05:32 +02:00
|
|
|
}
|
2020-06-07 17:14:13 +02:00
|
|
|
|
2021-04-16 20:38:13 +02:00
|
|
|
void Entry::setNew(const bool state)
|
2021-04-07 10:39:12 +02:00
|
|
|
{
|
|
|
|
m_new = state;
|
|
|
|
Q_EMIT newChanged(m_new);
|
|
|
|
QSqlQuery query;
|
|
|
|
query.prepare(QStringLiteral("UPDATE Entries SET new=:new WHERE id=:id AND feed=:feed"));
|
|
|
|
query.bindValue(QStringLiteral(":id"), m_id);
|
|
|
|
query.bindValue(QStringLiteral(":feed"), m_feed->url());
|
|
|
|
query.bindValue(QStringLiteral(":new"), m_new);
|
|
|
|
Database::instance().execute(query);
|
|
|
|
// Q_EMIT m_feed->newEntryCountChanged(); // TODO: signal and slots to be implemented
|
2021-04-17 22:54:35 +02:00
|
|
|
Q_EMIT DataManager::instance().newEntryCountChanged(m_feed->url());
|
2021-04-07 10:39:12 +02:00
|
|
|
}
|
2021-04-09 16:55:31 +02:00
|
|
|
|
2020-06-07 17:14:13 +02:00
|
|
|
QString Entry::adjustedContent(int width, int fontSize)
|
|
|
|
{
|
|
|
|
QString ret(m_content);
|
|
|
|
QRegularExpression imgRegex(QStringLiteral("<img ((?!width=\"[0-9]+(px)?\").)*(width=\"([0-9]+)(px)?\")?[^>]*>"));
|
|
|
|
|
|
|
|
QRegularExpressionMatchIterator i = imgRegex.globalMatch(ret);
|
|
|
|
while (i.hasNext()) {
|
|
|
|
QRegularExpressionMatch match = i.next();
|
|
|
|
|
|
|
|
QString imgTag(match.captured());
|
|
|
|
if (imgTag.contains(QStringLiteral("wp-smiley")))
|
|
|
|
imgTag.insert(4, QStringLiteral(" width=\"%1\"").arg(fontSize));
|
|
|
|
|
|
|
|
QString widthParameter = match.captured(4);
|
|
|
|
|
|
|
|
if (widthParameter.length() != 0) {
|
|
|
|
if (widthParameter.toInt() > width)
|
|
|
|
imgTag.replace(match.captured(3), QStringLiteral("width=\"%1\"").arg(width));
|
|
|
|
} else {
|
|
|
|
imgTag.insert(4, QStringLiteral(" width=\"%1\"").arg(width));
|
|
|
|
}
|
|
|
|
ret.replace(match.captured(), imgTag);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret.replace(QRegularExpression(QStringLiteral("<ul[^>]*>")), QLatin1String(""));
|
|
|
|
ret.replace(QRegularExpression(QStringLiteral("</ul>")), QLatin1String(""));
|
|
|
|
|
|
|
|
ret.replace(QRegularExpression(QStringLiteral("<li[^>]*>")), QLatin1String(""));
|
|
|
|
ret.replace(QRegularExpression(QStringLiteral("</li>")), QLatin1String(""));
|
|
|
|
|
|
|
|
ret.replace(QStringLiteral("<img"), QStringLiteral("<br /> <img"));
|
|
|
|
return ret;
|
|
|
|
}
|
2021-02-21 19:54:10 +01:00
|
|
|
|
|
|
|
Enclosure *Entry::enclosure() const
|
|
|
|
{
|
|
|
|
return m_enclosure;
|
|
|
|
}
|
|
|
|
|
2021-04-03 21:39:20 +02:00
|
|
|
bool Entry::hasEnclosure() const
|
|
|
|
{
|
|
|
|
return m_hasenclosure;
|
|
|
|
}
|
|
|
|
|
2021-04-05 14:15:44 +02:00
|
|
|
QString Entry::image() const
|
|
|
|
{
|
|
|
|
if (!m_image.isEmpty()) {
|
|
|
|
return m_image;
|
|
|
|
} else {
|
|
|
|
return m_feed->image();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-07 22:10:39 +02:00
|
|
|
bool Entry::queueStatus() const
|
|
|
|
{
|
2021-04-16 20:38:13 +02:00
|
|
|
return DataManager::instance().entryInQueue(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::setQueueStatus(const bool state)
|
|
|
|
{
|
|
|
|
if (state != DataManager::instance().entryInQueue(this)) {
|
|
|
|
if (state)
|
|
|
|
DataManager::instance().addToQueue(this);
|
|
|
|
else
|
|
|
|
DataManager::instance().removeQueueItem(this);
|
|
|
|
Q_EMIT queueStatusChanged(state);
|
|
|
|
}
|
2021-04-07 22:10:39 +02:00
|
|
|
}
|
|
|
|
|
2021-04-05 14:15:44 +02:00
|
|
|
void Entry::setImage(const QString &image)
|
|
|
|
{
|
|
|
|
m_image = image;
|
|
|
|
Q_EMIT imageChanged(m_image);
|
|
|
|
}
|
|
|
|
|
2021-02-21 19:54:10 +01:00
|
|
|
Feed *Entry::feed() const
|
|
|
|
{
|
|
|
|
return m_feed;
|
|
|
|
}
|