Simplify author handling

- Don't make them QObjects; those are heavy and there's no reason for that
- In fact, don't make them objects at all; we're only using them in string form anyway
This commit is contained in:
Tobias Fella 2023-12-19 09:14:48 +00:00 committed by Bart De Vries
parent fe6626ebeb
commit eb74c913a9
11 changed files with 45 additions and 165 deletions

View File

@ -10,7 +10,6 @@ add_executable(kasts
database.cpp
entry.cpp
feed.cpp
author.cpp
enclosure.cpp
chapter.cpp
datamanager.cpp

View File

@ -731,11 +731,8 @@ void AudioManager::updateMetaData()
if (!d->m_entry->feed()->name().isEmpty()) {
d->m_player.metaData()->setAlbum(d->m_entry->feed()->name());
}
if (d->m_entry->authors().count() > 0) {
QString authors;
for (auto &author : d->m_entry->authors())
authors.append(author->name());
d->m_player.metaData()->setArtist(authors);
if (d->m_entry->authors().length() > 0) {
d->m_player.metaData()->setArtist(d->m_entry->authors());
}
if (!d->m_entry->image().isEmpty()) {
d->m_player.metaData()->setArtworkUrl(QUrl(d->m_entry->cachedImage()));

View File

@ -1,30 +0,0 @@
/**
* SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "author.h"
Author::Author(const QString &name, const QString &email, const QString &url, QObject *parent)
: QObject(parent)
, m_name(name)
, m_email(email)
, m_url(url)
{
}
QString Author::name() const
{
return m_name;
}
QString Author::email() const
{
return m_email;
}
QString Author::url() const
{
return m_url;
}

View File

@ -1,30 +0,0 @@
/**
* SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#pragma once
#include <QObject>
class Author : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString email READ email CONSTANT)
Q_PROPERTY(QString url READ url CONSTANT)
public:
Author(const QString &name, const QString &email, const QString &url, QObject *parent = nullptr);
QString name() const;
QString email() const;
QString url() const;
private:
QString m_name;
QString m_email;
QString m_url;
};

View File

@ -12,6 +12,8 @@
#include <QSqlQuery>
#include <QUrl>
#include <KLocalizedString>
#include "database.h"
#include "datamanager.h"
#include "feed.h"
@ -76,55 +78,31 @@ void Entry::updateFromDb(bool emitSignals)
setHasEnclosure(entryQuery.value(QStringLiteral("hasEnclosure")).toBool(), emitSignals);
setImage(entryQuery.value(QStringLiteral("image")).toString(), emitSignals);
updateAuthors(emitSignals);
updateAuthors();
}
void Entry::updateAuthors(bool emitSignals)
void Entry::updateAuthors()
{
QVector<Author *> newAuthors;
bool haveAuthorsChanged = false;
QStringList authors;
QSqlQuery authorQuery;
authorQuery.prepare(QStringLiteral("SELECT * FROM Authors WHERE id=:id AND feed=:feed;"));
authorQuery.prepare(QStringLiteral("SELECT name FROM Authors WHERE id=:id AND feed=:feed"));
authorQuery.bindValue(QStringLiteral(":id"), m_id);
authorQuery.bindValue(QStringLiteral(":feed"), m_feed->url());
Database::instance().execute(authorQuery);
while (authorQuery.next()) {
// check if author already exists, if so, then reuse
bool existingAuthor = false;
QString name = authorQuery.value(QStringLiteral("name")).toString();
QString email = authorQuery.value(QStringLiteral("email")).toString();
QString url = authorQuery.value(QStringLiteral("uri")).toString();
qCDebug(kastsEntry) << name << email << url;
for (Author *author : m_authors) {
if (author)
qCDebug(kastsEntry) << "old authors" << author->name() << author->email() << author->url();
if (author && author->name() == name && author->email() == email && author->url() == url) {
existingAuthor = true;
newAuthors += author;
}
}
if (!existingAuthor) {
newAuthors += new Author(name, email, url, this);
haveAuthorsChanged = true;
}
authors += authorQuery.value(QStringLiteral("name")).toString();
}
// Finally check whether m_authors and newAuthors are identical
// if not, then delete the authors that were removed
for (Author *author : m_authors) {
if (!newAuthors.contains(author)) {
delete author;
haveAuthorsChanged = true;
}
}
m_authors = newAuthors;
if (haveAuthorsChanged && emitSignals) {
Q_EMIT authorsChanged(m_authors);
qCDebug(kastsEntry) << "entry" << m_id << "authors have changed?" << haveAuthorsChanged;
if (authors.size() == 1) {
m_authors = authors[0];
} else if (authors.size() == 2) {
m_authors = i18nc("<name> and <name>", "%1 and %2", authors.first(), authors.last());
} else if (authors.size() > 2) {
auto last = authors.takeLast();
m_authors = i18nc("<name(s)>, and <name>", "%1, and %2", authors.join(u','), last);
}
Q_EMIT authorsChanged(m_authors);
}
QString Entry::id() const
@ -142,7 +120,7 @@ QString Entry::content() const
return m_content;
}
QVector<Author *> Entry::authors() const
QString Entry::authors() const
{
return m_authors;
}

View File

@ -13,7 +13,6 @@
#include <QString>
#include <QStringList>
#include "author.h"
#include "enclosure.h"
#include "feed.h"
@ -25,7 +24,7 @@ class Entry : public QObject
Q_PROPERTY(QString id READ id CONSTANT)
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(QString content READ content NOTIFY contentChanged)
Q_PROPERTY(QVector<Author *> authors READ authors NOTIFY authorsChanged)
Q_PROPERTY(QString authors READ authors NOTIFY authorsChanged)
Q_PROPERTY(QDateTime created READ created NOTIFY createdChanged)
Q_PROPERTY(QDateTime updated READ updated NOTIFY updatedChanged)
Q_PROPERTY(QString link READ link NOTIFY linkChanged)
@ -45,7 +44,7 @@ public:
QString id() const;
QString title() const;
QString content() const;
QVector<Author *> authors() const;
QString authors() const;
QDateTime created() const;
QDateTime updated() const;
QString link() const;
@ -76,7 +75,7 @@ public:
Q_SIGNALS:
void titleChanged(const QString &title);
void contentChanged(const QString &content);
void authorsChanged(const QVector<Author *> &authors);
void authorsChanged(const QString &authors);
void createdChanged(const QDateTime &created);
void updatedChanged(const QDateTime &updated);
void linkChanged(const QString &link);
@ -91,7 +90,7 @@ Q_SIGNALS:
private:
void updateFromDb(bool emitSignals = true);
void updateAuthors(bool emitSignals = true);
void updateAuthors();
void setTitle(const QString &title, bool emitSignal = true);
void setContent(const QString &content, bool emitSignal = true);
void setCreated(const QDateTime &created, bool emitSignal = true);
@ -104,7 +103,7 @@ private:
QString m_id;
QString m_title;
QString m_content;
QVector<Author *> m_authors;
QString m_authors;
QDateTime m_created;
QDateTime m_updated;
QString m_link;

View File

@ -7,7 +7,8 @@
#include <QVariant>
#include "author.h"
#include <KLocalizedString>
#include "database.h"
#include "datamanager.h"
#include "error.h"
@ -100,47 +101,25 @@ Feed::Feed(const QString &feedurl)
void Feed::updateAuthors()
{
QVector<Author *> newAuthors;
bool haveAuthorsChanged = false;
QStringList authors;
QSqlQuery authorQuery;
authorQuery.prepare(QStringLiteral("SELECT * FROM Authors WHERE id='' AND feed=:feed"));
authorQuery.prepare(QStringLiteral("SELECT name FROM Authors WHERE id='' AND feed=:feed"));
authorQuery.bindValue(QStringLiteral(":feed"), m_url);
Database::instance().execute(authorQuery);
while (authorQuery.next()) {
// check if author already exists, if so, then reuse
bool existingAuthor = false;
QString name = authorQuery.value(QStringLiteral("name")).toString();
QString email = authorQuery.value(QStringLiteral("email")).toString();
QString url = authorQuery.value(QStringLiteral("uri")).toString();
qCDebug(kastsFeed) << name << email << url;
for (int i = 0; i < m_authors.count(); i++) {
qCDebug(kastsFeed) << "old authors" << m_authors[i]->name() << m_authors[i]->email() << m_authors[i]->url();
if (m_authors[i] && m_authors[i]->name() == name && m_authors[i]->email() == email && m_authors[i]->url() == url) {
existingAuthor = true;
newAuthors += m_authors[i];
}
}
if (!existingAuthor) {
newAuthors += new Author(name, email, url, nullptr);
haveAuthorsChanged = true;
}
authors += authorQuery.value(QStringLiteral("name")).toString();
}
// Finally check whether m_authors and newAuthors are identical
// if not, then delete the authors that were removed
for (int i = 0; i < m_authors.count(); i++) {
if (!newAuthors.contains(m_authors[i])) {
delete m_authors[i];
haveAuthorsChanged = true;
}
if (authors.size() == 1) {
m_authors = authors[0];
} else if (authors.size() == 2) {
m_authors = i18nc("<name> and <name>", "%1 and %2", authors.first(), authors.last());
} else if (authors.size() > 2) {
auto last = authors.takeLast();
m_authors = i18nc("<name(s)>, and <name>", "%1, and %2", authors.join(u','), last);
}
m_authors = newAuthors;
if (haveAuthorsChanged)
Q_EMIT authorsChanged(m_authors);
qCDebug(kastsFeed) << "feed" << m_name << "authors have changed?" << haveAuthorsChanged;
Q_EMIT authorsChanged(m_authors);
}
void Feed::updateUnreadEntryCountFromDB()
@ -206,7 +185,7 @@ QString Feed::description() const
return m_description;
}
QVector<Author *> Feed::authors() const
QString Feed::authors() const
{
return m_authors;
}
@ -309,16 +288,6 @@ void Feed::setDescription(const QString &description)
}
}
void Feed::setAuthors(const QVector<Author *> &authors)
{
for (auto &author : m_authors) {
delete author;
}
m_authors.clear();
m_authors = authors;
Q_EMIT authorsChanged(m_authors);
}
void Feed::setDeleteAfterCount(int count)
{
m_deleteAfterCount = count;

View File

@ -12,7 +12,6 @@
#include <QString>
#include <QVector>
#include "author.h"
#include "models/entriesproxymodel.h"
class Feed : public QObject
@ -25,7 +24,7 @@ class Feed : public QObject
Q_PROPERTY(QString cachedImage READ cachedImage NOTIFY cachedImageChanged)
Q_PROPERTY(QString link READ link WRITE setLink NOTIFY linkChanged)
Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
Q_PROPERTY(QVector<Author *> authors READ authors WRITE setAuthors NOTIFY authorsChanged)
Q_PROPERTY(QString authors READ authors NOTIFY authorsChanged)
Q_PROPERTY(bool refreshing READ refreshing WRITE setRefreshing NOTIFY refreshingChanged)
Q_PROPERTY(int deleteAfterCount READ deleteAfterCount WRITE setDeleteAfterCount NOTIFY deleteAfterCountChanged)
Q_PROPERTY(int deleteAfterType READ deleteAfterType WRITE setDeleteAfterType NOTIFY deleteAfterTypeChanged)
@ -52,7 +51,7 @@ public:
QString cachedImage() const;
QString link() const;
QString description() const;
QVector<Author *> authors() const;
QString authors() const;
int deleteAfterCount() const;
int deleteAfterType() const;
QDateTime subscribed() const;
@ -73,7 +72,6 @@ public:
void setImage(const QString &image);
void setLink(const QString &link);
void setDescription(const QString &description);
void setAuthors(const QVector<Author *> &authors);
void setDeleteAfterCount(int count);
void setDeleteAfterType(int type);
void setLastUpdated(const QDateTime &lastUpdated);
@ -92,7 +90,7 @@ Q_SIGNALS:
void cachedImageChanged(const QString &imagePath);
void linkChanged(const QString &link);
void descriptionChanged(const QString &description);
void authorsChanged(const QVector<Author *> &authors);
void authorsChanged(const QString &authors);
void deleteAfterCountChanged(int count);
void deleteAfterTypeChanged(int type);
void lastUpdatedChanged(const QDateTime &lastUpdated);
@ -117,7 +115,7 @@ private:
QString m_image;
QString m_link;
QString m_description;
QVector<Author *> m_authors;
QString m_authors;
int m_deleteAfterCount;
int m_deleteAfterType;
QDateTime m_subscribed;

View File

@ -32,7 +32,6 @@
#include "androidlogging.h"
#endif
#include "audiomanager.h"
#include "author.h"
#include "database.h"
#include "datamanager.h"
#include "entry.h"

View File

@ -116,7 +116,7 @@ FocusScope {
property string blurredImage: AudioManager.entry ? AudioManager.entry.cachedImage : "no-image"
property string title: AudioManager.entry ? AudioManager.entry.title : i18n("No Track Title")
property string feed: AudioManager.entry ? AudioManager.entry.feed.name : i18n("No track loaded")
property string authors: AudioManager.entry ? (AudioManager.entry.feed.authors.length !== 0 ? AudioManager.entry.feed.authors[0].name : "") : ""
property string authors: AudioManager.entry ? AudioManager.entry.feed.authors : ""
implicitHeight: headerBar.handlePosition
implicitWidth: parent.width

View File

@ -23,7 +23,6 @@ Kirigami.ScrollablePage {
property bool isSubscribed: true
property var subscribeAction: undefined // this is only used if instantiated from the discoverpage
property string author: isSubscribed ? (page.feed.authors.length === 0 ? "" : page.feed.authors[0].name) : feed.author
property bool showMoreInfo: false
title: i18n("Podcast Details")
@ -114,9 +113,11 @@ Kirigami.ScrollablePage {
id: headerImage
Layout.fillWidth: true
property string authors: isSubscribed ? feed.authors : feed.author
image: isSubscribed ? feed.cachedImage : feed.image
title: isSubscribed ? feed.name : feed.title
subtitle: (!page.feed.authors || page.feed.authors.length === 0) ? "" : i18nc("by <author(s)>", "by %1", page.feed.authors[0].name)
subtitle: authors ? i18nc("by <author(s)>", "by %1", authors) : undefined
}
// header actions