Add model for searching for podcasts

This commit is contained in:
Tobias Fella 2021-06-27 00:53:28 +02:00 committed by Bart De Vries
parent 653f41c94e
commit fa1c308c2d
5 changed files with 113 additions and 1 deletions

View File

@ -20,6 +20,7 @@ set(SRCS_base
powermanagementinterface.cpp
errorlogmodel.cpp
error.cpp
podcastsearchmodel.cpp
mpris2/mpris2.cpp
resources.qrc
)

View File

@ -44,6 +44,7 @@ public:
QString imagePath(const QString &url) const;
QString enclosurePath(const QString &url) const;
QNetworkReply *get(QNetworkRequest &request) const;
// Network status related methods
Q_INVOKABLE bool canCheckNetworkStatus() const;
@ -80,7 +81,6 @@ private:
void processAuthor(const QString &url, const QString &entryId, const QString &authorName, const QString &authorUri, const QString &authorEmail);
void processEnclosure(Syndication::EnclosurePtr enclosure, Syndication::ItemPtr entry, const QString &feedUrl);
QNetworkReply *get(QNetworkRequest &request) const;
QNetworkReply *head(QNetworkRequest &request) const;
void setHeader(QNetworkRequest &request) const;

View File

@ -45,6 +45,7 @@
#include "fetcher.h"
#include "kasts-version.h"
#include "mpris2/mpris2.h"
#include "podcastsearchmodel.h"
#include "queuemodel.h"
#include "settingsmanager.h"
@ -120,6 +121,7 @@ int main(int argc, char *argv[])
qmlRegisterType<QueueModel>("org.kde.kasts", 1, 0, "QueueModel");
qmlRegisterType<EpisodeModel>("org.kde.kasts", 1, 0, "EpisodeModel");
qmlRegisterType<Mpris2>("org.kde.kasts", 1, 0, "Mpris2");
qmlRegisterType<PodcastSearchModel>("org.kde.kasts", 1, 0, "PodcastSearchModel");
qmlRegisterUncreatableType<EntriesModel>("org.kde.kasts", 1, 0, "EntriesModel", QStringLiteral("Get from Feed"));
qmlRegisterUncreatableType<Enclosure>("org.kde.kasts", 1, 0, "Enclosure", QStringLiteral("Only for enums"));

View File

@ -0,0 +1,75 @@
/**
* SPDX-FileCopyrightText: 2021 Tobias Fella <fella@posteo.de>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "podcastsearchmodel.h"
#include <QCryptographicHash>
#include <QDateTime>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QString>
#include <QVariant>
#include "fetcher.h"
PodcastSearchModel::PodcastSearchModel(QObject *parent)
: QAbstractListModel(parent)
{
}
QVariant PodcastSearchModel::data(const QModelIndex &index, int role) const
{
if (index.row() < 0 || index.row() >= rowCount(QModelIndex())) {
// invalid index
return QVariant::fromValue(QStringLiteral("DEADBEEF"));
}
if (role == Title) {
return m_data[QStringLiteral("feeds")].toArray()[index.row()].toObject()[QStringLiteral("title")].toString();
}
return QVariant();
}
QHash<int, QByteArray> PodcastSearchModel::roleNames() const
{
return {{Title, "title"}};
}
int PodcastSearchModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
if (m_data.isEmpty()) {
return 0;
}
return m_data[QStringLiteral("feeds")].toArray().size();
}
void PodcastSearchModel::search(const QString &text)
{
QString safeText(text);
// TODO: Make this more urlsafe
safeText.replace(QLatin1Char(' '), QLatin1Char('+'));
QNetworkRequest request(QUrl(QStringLiteral("https://api.podcastindex.org/api/1.0/search/byterm?q=%1").arg(text)));
request.setRawHeader("X-Auth-Key", "BLVCJJSWUJGD3WJQSZ56");
auto time = QDateTime::currentDateTime().toSecsSinceEpoch();
request.setRawHeader("X-Auth-Date", QString::number(time).toLatin1());
QString hashString = QStringLiteral(
"BLVCJJSWUJGD3WJQSZ56"
"vSPPqM8Tqh9Lr3xbEb77L4$f6kAdVw3v$9TwzGRH")
+ QString::number(time);
auto hash = QCryptographicHash::hash(hashString.toLatin1(), QCryptographicHash::Sha1);
request.setRawHeader("Authorization", hash.toHex());
auto reply = Fetcher::instance().get(request);
// TODO: error handling
connect(reply, &QNetworkReply::finished, this, [=]() {
beginResetModel();
m_data = QJsonDocument::fromJson(reply->readAll()).object();
endResetModel();
});
}

34
src/podcastsearchmodel.h Normal file
View File

@ -0,0 +1,34 @@
/**
* SPDX-FileCopyrightText: 2021 Tobias Fella <fella@posteo.de>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#pragma once
#include <QAbstractListModel>
#include <QHash>
#include <QJsonObject>
#include <QObject>
#include <QVariant>
#include "feed.h"
class PodcastSearchModel : public QAbstractListModel
{
Q_OBJECT
public:
enum Roles {
Title,
};
explicit PodcastSearchModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent) const override;
Q_INVOKABLE void search(const QString &text);
private:
QJsonObject m_data;
};