mirror of https://github.com/KDE/kasts.git
Add ErrorModel, just a placholder GUI for now
This commit is contained in:
parent
51db7ea1cf
commit
5a0972372b
|
@ -15,6 +15,8 @@ add_executable(alligator
|
|||
datamanager.cpp
|
||||
audiomanager.cpp
|
||||
powermanagementinterface.cpp
|
||||
errorlogmodel.cpp
|
||||
error.h
|
||||
mpris2/mpris2.cpp
|
||||
mpris2/mediaplayer2.cpp
|
||||
mpris2/mediaplayer2player.cpp
|
||||
|
|
|
@ -52,6 +52,7 @@ bool Database::migrateTo1()
|
|||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Authors (feed TEXT, id TEXT, name TEXT, uri TEXT, email TEXT);")));
|
||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Enclosures (feed TEXT, id TEXT, duration INTEGER, size INTEGER, title TEXT, type TEXT, url TEXT, playposition INTEGER, downloaded BOOL);"))); //, filename TEXT);")));
|
||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Queue (listnr INTEGER, feed TEXT, id TEXT, playing BOOL);")));
|
||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Errors (url TEXT, id TEXT, code INTEGER, string TEXT, date INTEGER);")));
|
||||
TRUE_OR_RETURN(execute(QStringLiteral("PRAGMA user_version = 1;")));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "entry.h"
|
||||
#include "fetcher.h"
|
||||
#include "downloadprogressmodel.h"
|
||||
#include "errorlogmodel.h"
|
||||
|
||||
Enclosure::Enclosure(Entry *entry)
|
||||
: QObject(entry)
|
||||
|
@ -27,6 +28,7 @@ Enclosure::Enclosure(Entry *entry)
|
|||
Q_EMIT downloadStatusChanged(m_entry, m_status);
|
||||
});
|
||||
connect(this, &Enclosure::downloadStatusChanged, &DownloadProgressModel::instance(), &DownloadProgressModel::monitorDownloadProgress);
|
||||
connect(this,&Enclosure::downloadError, &ErrorLogModel::instance(), &ErrorLogModel::monitorErrorMessages);
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare(QStringLiteral("SELECT * FROM Enclosures WHERE id=:id"));
|
||||
|
@ -105,6 +107,7 @@ void Enclosure::download()
|
|||
if(downloadJob->error() != QNetworkReply::OperationCanceledError) {
|
||||
m_entry->feed()->setErrorId(downloadJob->error());
|
||||
m_entry->feed()->setErrorString(downloadJob->errorString());
|
||||
Q_EMIT downloadError(m_entry->feed()->url(), m_entry->id(), downloadJob->error(), downloadJob->errorString());
|
||||
}
|
||||
}
|
||||
disconnect(this, &Enclosure::cancelDownload, this, nullptr);
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#ifndef ENCLOSURE_H
|
||||
#define ENCLOSURE_H
|
||||
#pragma once
|
||||
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
|
@ -60,6 +59,7 @@ Q_SIGNALS:
|
|||
void durationChanged();
|
||||
void sizeChanged();
|
||||
void downloadStatusChanged(Entry* entry, Status status);
|
||||
void downloadError(const QString &url, const QString &id, const int errorId, const QString &errorString);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -76,5 +76,3 @@ private:
|
|||
double m_downloadProgress = 0;
|
||||
Status m_status;
|
||||
};
|
||||
|
||||
#endif // ENCLOSURE_H
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
|
||||
class Error : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString url MEMBER url CONSTANT)
|
||||
Q_PROPERTY(QString id MEMBER id CONSTANT)
|
||||
Q_PROPERTY(int code MEMBER code CONSTANT)
|
||||
Q_PROPERTY(QString string MEMBER string CONSTANT)
|
||||
Q_PROPERTY(QDateTime date MEMBER date CONSTANT)
|
||||
|
||||
public:
|
||||
Error(const QString url, const QString id, const int code, const QString string, const QDateTime date): QObject(nullptr)
|
||||
{
|
||||
this->url = url;
|
||||
this->id = id;
|
||||
this->code = code;
|
||||
this->string = string;
|
||||
this->date = date;
|
||||
};
|
||||
|
||||
QString url;
|
||||
QString id;
|
||||
int code;
|
||||
QString string;
|
||||
QDateTime date;
|
||||
};
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#include "errorlogmodel.h"
|
||||
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "fetcher.h"
|
||||
#include "database.h"
|
||||
|
||||
|
||||
ErrorLogModel::ErrorLogModel()
|
||||
: QAbstractListModel(nullptr)
|
||||
{
|
||||
connect(&Fetcher::instance(), &Fetcher::error, this, &ErrorLogModel::monitorErrorMessages);
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare(QStringLiteral("SELECT * FROM Errors ORDER BY date DESC;"));
|
||||
Database::instance().execute(query);
|
||||
while (query.next()) {
|
||||
Error* error = new Error(query.value(QStringLiteral("url")).toString(), query.value(QStringLiteral("id")).toString(), query.value(QStringLiteral("code")).toInt(), query.value(QStringLiteral("string")).toString(), QDateTime::fromSecsSinceEpoch(query.value(QStringLiteral("date")).toInt()));
|
||||
m_errors += error;
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ErrorLogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != 0)
|
||||
return QVariant();
|
||||
return QVariant::fromValue(m_errors[index.row()]);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ErrorLogModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roleNames;
|
||||
roleNames[0] = "error";
|
||||
return roleNames;
|
||||
}
|
||||
|
||||
int ErrorLogModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_errors.count();
|
||||
}
|
||||
|
||||
void ErrorLogModel::monitorErrorMessages(const QString &url, const QString& id, const int errorCode, const QString& errorString)
|
||||
{
|
||||
qDebug() << "Error happened:" << url << id << errorCode << errorString;
|
||||
Error* error = new Error(url, id, errorCode, errorString, QDateTime::currentDateTime());
|
||||
beginInsertRows(QModelIndex(), 0, 0);
|
||||
m_errors.prepend(error);
|
||||
endInsertRows();
|
||||
|
||||
// Also add error to database
|
||||
QSqlQuery query;
|
||||
query.prepare(QStringLiteral("INSERT INTO Errors VALUES (:url, :id, :code, :string, :date);"));
|
||||
query.bindValue(QStringLiteral(":url"), error->url);
|
||||
query.bindValue(QStringLiteral(":id"), error->id);
|
||||
query.bindValue(QStringLiteral(":code"), error->code);
|
||||
query.bindValue(QStringLiteral(":string"), error->string);
|
||||
query.bindValue(QStringLiteral(":date"), error->date.toSecsSinceEpoch());
|
||||
Database::instance().execute(query);
|
||||
}
|
||||
|
||||
void ErrorLogModel::clearAll()
|
||||
{
|
||||
beginResetModel();
|
||||
for (auto& error : m_errors) {
|
||||
delete error;
|
||||
}
|
||||
m_errors.clear();
|
||||
endResetModel();
|
||||
|
||||
// Also clear errors from database
|
||||
QSqlQuery query;
|
||||
query.prepare(QStringLiteral("DELETE FROM Errors;"));
|
||||
Database::instance().execute(query);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
class ErrorLogModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ErrorLogModel &instance()
|
||||
{
|
||||
static ErrorLogModel _instance;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
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 clearAll();
|
||||
|
||||
public Q_SLOTS:
|
||||
void monitorErrorMessages(const QString &url, const QString &id, const int errorCode, const QString &errorString);
|
||||
|
||||
private:
|
||||
explicit ErrorLogModel();
|
||||
|
||||
QList<Error*> m_errors;
|
||||
};
|
|
@ -58,7 +58,8 @@ Feed::Feed(QString const feedurl)
|
|||
setErrorString(QLatin1String(""));
|
||||
}
|
||||
});
|
||||
connect(&Fetcher::instance(), &Fetcher::error, this, [this](const QString &url, int errorId, const QString &errorString) {
|
||||
connect(&Fetcher::instance(), &Fetcher::error, this, [this](const QString &url, const QString &id, int errorId, const QString &errorString) {
|
||||
Q_UNUSED(id)
|
||||
if(url == m_url) {
|
||||
setErrorId(errorId);
|
||||
setErrorString(errorString);
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#ifndef FEED_H
|
||||
#define FEED_H
|
||||
#pragma once
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
|
@ -116,5 +115,3 @@ private:
|
|||
|
||||
bool m_refreshing = false;
|
||||
};
|
||||
|
||||
#endif // FEED_H
|
||||
|
|
|
@ -49,7 +49,7 @@ void Fetcher::fetch(const QString &url)
|
|||
if(reply->error()) {
|
||||
qWarning() << "Error fetching feed";
|
||||
qWarning() << reply->errorString();
|
||||
Q_EMIT error(url, reply->error(), reply->errorString());
|
||||
Q_EMIT error(url, QStringLiteral(""), reply->error(), reply->errorString());
|
||||
} else {
|
||||
QByteArray data = reply->readAll();
|
||||
Syndication::DocumentSource *document = new Syndication::DocumentSource(data, url);
|
||||
|
@ -341,6 +341,7 @@ QString Fetcher::image(const QString& url) const
|
|||
QNetworkReply *Fetcher::download(const QString &url, const QString &filePath) const
|
||||
{
|
||||
QNetworkRequest request((QUrl(url)));
|
||||
request.setTransferTimeout();
|
||||
QNetworkReply *reply = get(request);
|
||||
connect(reply, &QNetworkReply::finished, this, [=]() {
|
||||
if (reply->isOpen()) {
|
||||
|
|
|
@ -42,7 +42,7 @@ Q_SIGNALS:
|
|||
void feedUpdated(const QString &url);
|
||||
void feedDetailsUpdated(const QString &url, const QString &name, const QString &image, const QString &link, const QString &description, const QDateTime &lastUpdated);
|
||||
void feedUpdateFinished(const QString &url);
|
||||
void error(const QString &url, QNetworkReply::NetworkError errorId, const QString &errorString);
|
||||
void error(const QString &url, const QString &id, const int errorId, const QString &errorString);
|
||||
void entryAdded(const QString &feedurl, const QString &id);
|
||||
void downloadFinished(QString url) const;
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "queuemodel.h"
|
||||
#include "episodemodel.h"
|
||||
#include "downloadprogressmodel.h"
|
||||
#include "errorlogmodel.h"
|
||||
#include "datamanager.h"
|
||||
#include "audiomanager.h"
|
||||
#include "mpris2/mpris2.h"
|
||||
|
@ -76,6 +77,10 @@ int main(int argc, char *argv[])
|
|||
engine->setObjectOwnership(&DownloadProgressModel::instance(), QQmlEngine::CppOwnership);
|
||||
return &DownloadProgressModel::instance();
|
||||
});
|
||||
qmlRegisterSingletonType<ErrorLogModel>("org.kde.alligator", 1, 0, "ErrorLogModel", [](QQmlEngine *engine, QJSEngine *) -> QObject * {
|
||||
engine->setObjectOwnership(&ErrorLogModel::instance(), QQmlEngine::CppOwnership);
|
||||
return &ErrorLogModel::instance();
|
||||
});
|
||||
qmlRegisterType<AudioManager>("org.kde.alligator", 1, 0, "AudioManager");
|
||||
qmlRegisterType<Mpris2>("org.kde.alligator", 1, 0, "Mpris2");
|
||||
|
||||
|
@ -102,10 +107,9 @@ int main(int argc, char *argv[])
|
|||
QObject::connect(&app, &QCoreApplication::aboutToQuit, SettingsManager::self(), &SettingsManager::save);
|
||||
|
||||
Database::instance();
|
||||
|
||||
DataManager::instance();
|
||||
|
||||
DownloadProgressModel::instance();
|
||||
ErrorLogModel::instance();
|
||||
|
||||
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
|
||||
|
||||
|
|
|
@ -51,6 +51,11 @@ Kirigami.Page {
|
|||
height: tabBarHeight
|
||||
text: i18n("Completed")
|
||||
}
|
||||
Controls.TabButton {
|
||||
width: parent.parent.width/parent.count
|
||||
height: tabBarHeight
|
||||
text: i18n("Errors")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,5 +73,9 @@ Kirigami.Page {
|
|||
title: i18n("Completed")
|
||||
episodeType: EpisodeModel.Downloaded
|
||||
}
|
||||
|
||||
ErrorListPage {
|
||||
title: i18n("Errors")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14 as Controls
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtGraphicalEffects 1.15
|
||||
import QtMultimedia 5.15
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.alligator 1.0
|
||||
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
visible: errorList.count === 0
|
||||
|
||||
width: Kirigami.Units.gridUnit * 20
|
||||
anchors.centerIn: parent
|
||||
|
||||
text: i18n("No errors logged")
|
||||
}
|
||||
Component {
|
||||
id: errorListDelegate
|
||||
Controls.Label {
|
||||
text: error.string + error.date + error.string
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
id: errorList
|
||||
visible: count !== 0
|
||||
model: ErrorLogModel
|
||||
|
||||
delegate: Kirigami.DelegateRecycler {
|
||||
width: errorList.width
|
||||
sourceComponent: errorListDelegate
|
||||
}
|
||||
}
|
||||
actions.main: Kirigami.Action {
|
||||
text: i18n("Clear all errors")
|
||||
iconName: "edit-clear-all"
|
||||
onTriggered: ErrorLogModel.clearAll()
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
<file alias="FooterBar.qml">qml/FooterBar.qml</file>
|
||||
<file alias="QueuePage.qml">qml/QueuePage.qml</file>
|
||||
<file alias="EpisodeListPage.qml">qml/EpisodeListPage.qml</file>
|
||||
<file alias="ErrorListPage.qml">qml/ErrorListPage.qml</file>
|
||||
<file alias="EpisodeSwipePage.qml">qml/EpisodeSwipePage.qml</file>
|
||||
<file alias="DownloadSwipePage.qml">qml/DownloadSwipePage.qml</file>
|
||||
<file alias="GenericListHeader.qml">qml/GenericListHeader.qml</file>
|
||||
|
|
Loading…
Reference in New Issue