19#ifndef JELLYFIN_SUPPORT_LOADER_H 
   20#define JELLYFIN_SUPPORT_LOADER_H 
   22#include <initializer_list> 
   28#include <QJsonDocument> 
   33#include <QtConcurrent/QtConcurrent> 
   45          : m_message(message.toStdString()) {}
 
 
   50    virtual const char *
what() const noexcept override;
 
   52    virtual QException *
clone() const override;
 
   53    virtual 
void raise() const override;
 
   55    std::
string m_message;
 
 
   58static const 
int HTTP_TIMEOUT = 30000; 
 
   67        : m_apiClient(apiClient) {}
 
 
  102    void error(QString message = QString());
 
  109    bool m_isRunning = 
false;
 
  113        emit this->error(message);
 
 
 
  133template <
typename R, 
typename P>
 
  146        return m_result.value();
 
 
  160        m_parameters = parameters;
 
 
  172        return std::make_optional<R>(result);
 
 
  176        return fromJsonValue<R>(QJsonValue());
 
 
 
  201        m_parameters = parameters;
 
 
 
  219template<
typename R, 
typename P>
 
  226        QJsonParseError error;
 
  227        QJsonDocument document = QJsonDocument::fromJson(response, &error);
 
  228        if (error.error != QJsonParseError::NoError) {
 
  229            qWarning() << response;
 
  230            this->stopWithError(error.errorString().toLocal8Bit().constData());
 
  232        if (document.isNull() || document.isEmpty()) {
 
  233            this->stopWithError(QStringLiteral(
"Unexpected empty JSON response"));
 
  234            return this->createFailureResult();
 
  235        } 
else if (document.isArray()) {
 
  236            return this->createSuccessResult(fromJsonValue<R>(document.array()));
 
  237        } 
else if (document.isObject()){
 
  238            return this->createSuccessResult(fromJsonValue<R>(document.object()));
 
  240            this->stopWithError(QStringLiteral(
"Unexpected JSON response"));
 
  241            return this->createFailureResult();
 
 
 
  252        : 
Loader<void, P> (apiClient) {}
 
 
  255        return statusCode == 204;
 
 
 
  264        : 
Loader<bool, P> (apiClient) {}
 
 
  267        QString text = QString::fromUtf8(response);
 
  269        if (text == QStringLiteral(
"true")) {
 
  271        } 
else if (text == QStringLiteral(
"false")) {
 
  274            this->stopWithError(QStringLiteral(
"Could not parse boolean response: %1").arg(text));
 
 
 
  284template <
typename R, 
typename P>
 
  293        if (m_reply != 
nullptr) {
 
  294            this->m_reply->deleteLater();
 
  296        if (!this->m_parameters) {
 
  297            this->stopWithError(
"No parameters set");
 
  299        this->m_isRunning = 
true;
 
  300        switch(operation()) {
 
  301        case QNetworkAccessManager::GetOperation:
 
  302            m_reply = this->m_apiClient->
get(path(this->m_parameters.value()), query(this->m_parameters.value()));
 
  304        case QNetworkAccessManager::PostOperation:
 
  305            m_reply = this->m_apiClient->
post(path(this->m_parameters.value()), body(this->m_parameters.value()), query(this->m_parameters.value()));
 
  308            this->stopWithError(QStringLiteral(
"Unsupported network okperation %1").arg(operation()));
 
 
  317        if (m_reply == 
nullptr) 
return;
 
  318        if (m_reply->isRunning()) {
 
  320            m_reply->deleteLater();
 
 
  326        if (this->m_apiClient == 
nullptr) {
 
  329        return this->m_apiClient->
online();
 
 
  338    virtual QString 
path(
const P ¶meters) 
const = 0;
 
  339    virtual QUrlQuery 
query(
const P ¶meters) 
const = 0;
 
  340    virtual QByteArray 
body(
const P ¶meters) 
const = 0;
 
  341    virtual QNetworkAccessManager::Operation 
operation() 
const = 0;
 
  343    QNetworkReply *m_reply = 
nullptr;
 
  344    QFutureWatcher<typename Loader<R, P>::ResultType> m_parsedWatcher;
 
  346    void onRequestFinished() {
 
  347        if (m_reply->error() != QNetworkReply::NoError) {
 
  348            m_reply->deleteLater();
 
  349            m_parsedWatcher.cancel();
 
  351            this->stopWithError(QStringLiteral(
"HTTP error: %1").arg(m_reply->errorString()));
 
  354        QByteArray array = m_reply->readAll();
 
  355        int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
 
  356        m_reply->deleteLater();
 
  358        m_parsedWatcher.setFuture(
 
  362                                      QByteArray, QByteArray>                
 
  367    void onResponseParsed() {
 
  368        Q_ASSERT(m_parsedWatcher.isFinished());
 
  373            if (m_parsedWatcher.result()) {
 
  374                this->m_result = m_parsedWatcher.result();
 
  375                this->m_isRunning = 
false;
 
  378                this->m_isRunning = 
false;
 
  380        }  
catch (QException &e) {
 
  381            this->stopWithError(e.what());
 
 
An Api client for Jellyfin. Handles requests and authentication.
Definition apiclient.h:90
QNetworkReply * get(const QString &path, const QUrlQuery ¶ms=QUrlQuery())
Definition apiclient.cpp:262
QNetworkReply * post(const QString &path, const QJsonDocument &data, const QUrlQuery ¶ms=QUrlQuery())
Definition apiclient.cpp:268
bool online
Definition apiclient.h:116
HttpLoaderBase(Jellyfin::ApiClient *apiClient)
Definition loader.h:263
Loader< bool, P >::ResultType parseResponse(int statusCode, QByteArray response)
Definition loader.h:266
Loader< void, P >::ResultType parseResponse(int statusCode, QByteArray response)
Definition loader.h:254
HttpLoaderBase(Jellyfin::ApiClient *apiClient)
Definition loader.h:251
Loader< R, P >::ResultType parseResponse(int, QByteArray response)
Definition loader.h:225
HttpLoaderBase(Jellyfin::ApiClient *apiClient)
Definition loader.h:222
virtual QString path(const P ¶meters) const =0
Subclasses should override this method to return the path to this endpoint, with all path parameters ...
HttpLoader(Jellyfin::ApiClient *apiClient)
Definition loader.h:287
virtual QByteArray body(const P ¶meters) const =0
virtual void cancel() override
Definition loader.h:316
virtual QNetworkAccessManager::Operation operation() const =0
bool isAvailable() const override
Heuristic to determine if this resource can be loaded via this loaded.
Definition loader.h:325
virtual QUrlQuery query(const P ¶meters) const =0
virtual void load() override
load Loads the given resource asynchronously.
Definition loader.h:292
virtual const char * what() const noexcept override
Definition loader.cpp:24
virtual QException * clone() const override
Definition loader.cpp:28
virtual void raise() const override
Definition loader.cpp:32
LoadException(const QString &message)
Definition loader.h:44
Base class for loaders that defines available signals.
Definition loader.h:63
LoaderBase(ApiClient *apiClient)
Definition loader.h:66
void setApiClient(ApiClient *newApiClient)
Definition loader.h:94
virtual bool isAvailable() const
Heuristic to determine if this resource can be loaded via this loaded.
Definition loader.h:93
virtual void cancel()
Definition loader.h:80
void stopWithError(QString message=QString())
Definition loader.h:111
void error(QString message=QString())
Emitted when an error has occurred during loading and no result is available.
ApiClient * apiClient() const
Definition loader.h:95
virtual void load()
load Loads the given resource asynchronously.
Definition loader.h:73
Jellyfin::ApiClient * m_apiClient
Definition loader.h:108
bool isRunning() const
Definition loader.h:82
void ready()
Emitted when data was successfully loaded.
Loader(ApiClient *apiClient)
Definition loader.h:185
ResultType createFailureResult()
Definition loader.h:208
static void createDummyResponse()
Definition loader.h:216
ResultType createSuccessResult(void)
Definition loader.h:212
std::optional< P > m_parameters
Definition loader.h:205
bool hasResult() const
Definition loader.h:190
ResultType m_result
Definition loader.h:206
bool ResultType
Definition loader.h:184
void setParameters(const P ¶meters)
Sets the parameters for this loader.
Definition loader.h:200
void result() const
Definition loader.h:188
ResultType m_result
Definition loader.h:165
std::optional< R > ResultType
Definition loader.h:136
static R createDummyResponse()
Definition loader.h:175
ResultType createFailureResult()
Definition loader.h:167
R result() const
Retrieves the loaded resource. Only valid after the ready signal has been emitted.
Definition loader.h:145
ResultType createSuccessResult(R &&result)
Definition loader.h:171
bool hasResult() const
Definition loader.h:149
Loader(ApiClient *apiClient)
Definition loader.h:137
void setParameters(const P ¶meters)
Sets the parameters for this loader.
Definition loader.h:159
std::optional< P > m_parameters
Definition loader.h:164
void writeRequestTypesFile R(File headerFile, File implementationFile, R endpoints) if(is(ElementType!R
Definition openapigenerator.d:278