Skip to content

Commit

Permalink
Allow WebAPI to specify filename and mime type for result data
Browse files Browse the repository at this point in the history
PR #20377.
  • Loading branch information
glassez committed Feb 12, 2024
1 parent 8ef99b3 commit 60bb819
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 19 deletions.
23 changes: 16 additions & 7 deletions src/webui/api/apicontroller.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2018, 2022 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2018-2024 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -37,12 +37,19 @@

#include "apierror.h"

void APIResult::clear()
{
data.clear();
mimeType.clear();
filename.clear();
}

APIController::APIController(IApplication *app, QObject *parent)
: ApplicationComponent(app, parent)
{
}

QVariant APIController::run(const QString &action, const StringMap &params, const DataMap &data)
APIResult APIController::run(const QString &action, const StringMap &params, const DataMap &data)
{
m_result.clear(); // clear result
m_params = params;
Expand Down Expand Up @@ -79,20 +86,22 @@ void APIController::requireParams(const QVector<QString> &requiredParams) const

void APIController::setResult(const QString &result)
{
m_result = result;
m_result.data = result;
}

void APIController::setResult(const QJsonArray &result)
{
m_result = QJsonDocument(result);
m_result.data = QJsonDocument(result);
}

void APIController::setResult(const QJsonObject &result)
{
m_result = QJsonDocument(result);
m_result.data = QJsonDocument(result);
}

void APIController::setResult(const QByteArray &result)
void APIController::setResult(const QByteArray &result, const QString &mimeType, const QString &filename)
{
m_result = result;
m_result.data = result;
m_result.mimeType = mimeType;
m_result.filename = filename;
}
20 changes: 14 additions & 6 deletions src/webui/api/apicontroller.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2018, 2022 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2018-2024 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -30,15 +30,23 @@

#include <QtContainerFwd>
#include <QObject>
#include <QString>
#include <QVariant>

#include "base/applicationcomponent.h"

class QString;

using DataMap = QHash<QString, QByteArray>;
using StringMap = QHash<QString, QString>;

struct APIResult
{
QVariant data;
QString mimeType;
QString filename;

void clear();
};

class APIController : public ApplicationComponent<QObject>
{
Q_OBJECT
Expand All @@ -47,7 +55,7 @@ class APIController : public ApplicationComponent<QObject>
public:
explicit APIController(IApplication *app, QObject *parent = nullptr);

QVariant run(const QString &action, const StringMap &params, const DataMap &data = {});
APIResult run(const QString &action, const StringMap &params, const DataMap &data = {});

protected:
const StringMap &params() const;
Expand All @@ -57,10 +65,10 @@ class APIController : public ApplicationComponent<QObject>
void setResult(const QString &result);
void setResult(const QJsonArray &result);
void setResult(const QJsonObject &result);
void setResult(const QByteArray &result);
void setResult(const QByteArray &result, const QString &mimeType = {}, const QString &filename = {});

private:
StringMap m_params;
DataMap m_data;
QVariant m_result;
APIResult m_result;
};
2 changes: 1 addition & 1 deletion src/webui/api/torrentscontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1442,5 +1442,5 @@ void TorrentsController::exportAction()
if (!result)
throw APIError(APIErrorType::Conflict, tr("Unable to export torrent file. Error: %1").arg(result.error()));

setResult(result.value());
setResult(result.value(), u"application/x-bittorrent"_s, (id.toString() + u".torrent"));
}
17 changes: 12 additions & 5 deletions src/webui/webapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,18 +352,25 @@ void WebApplication::doProcessRequest()

try
{
const QVariant result = controller->run(action, m_params, data);
switch (result.userType())
const APIResult result = controller->run(action, m_params, data);
switch (result.data.userType())
{
case QMetaType::QJsonDocument:
print(result.toJsonDocument().toJson(QJsonDocument::Compact), Http::CONTENT_TYPE_JSON);
print(result.data.toJsonDocument().toJson(QJsonDocument::Compact), Http::CONTENT_TYPE_JSON);
break;
case QMetaType::QByteArray:
print(result.toByteArray(), Http::CONTENT_TYPE_TXT);
{
const auto resultData = result.data.toByteArray();
print(resultData, (!result.mimeType.isEmpty() ? result.mimeType : Http::CONTENT_TYPE_TXT));
if (!result.filename.isEmpty())
{
setHeader({u"Content-Disposition"_s, u"attachment; filename=\"%1\""_s.arg(result.filename)});
}
}
break;
case QMetaType::QString:
default:
print(result.toString(), Http::CONTENT_TYPE_TXT);
print(result.data.toString(), Http::CONTENT_TYPE_TXT);
break;
}
}
Expand Down

0 comments on commit 60bb819

Please sign in to comment.