Browse Source

Add support for exporting .torrent from WebUI

PR #16968.
adaptive-webui-19844
Tom Piccirello 2 years ago committed by GitHub
parent
commit
fb7f7d0c75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/webui/api/apicontroller.cpp
  2. 1
      src/webui/api/apicontroller.h
  3. 16
      src/webui/api/torrentscontroller.cpp
  4. 1
      src/webui/api/torrentscontroller.h
  5. 3
      src/webui/webapplication.cpp
  6. 2
      src/webui/webapplication.h
  7. 3
      src/webui/www/private/index.html
  8. 21
      src/webui/www/private/scripts/mocha-init.js
  9. 4
      src/webui/www/private/views/transferlist.html

5
src/webui/api/apicontroller.cpp

@ -91,3 +91,8 @@ void APIController::setResult(const QJsonObject &result)
{ {
m_result = QJsonDocument(result); m_result = QJsonDocument(result);
} }
void APIController::setResult(const QByteArray &result)
{
m_result = result;
}

1
src/webui/api/apicontroller.h

@ -55,6 +55,7 @@ protected:
void setResult(const QString &result); void setResult(const QString &result);
void setResult(const QJsonArray &result); void setResult(const QJsonArray &result);
void setResult(const QJsonObject &result); void setResult(const QJsonObject &result);
void setResult(const QByteArray &result);
private: private:
StringMap m_params; StringMap m_params;

16
src/webui/api/torrentscontroller.cpp

@ -1414,3 +1414,19 @@ void TorrentsController::renameFolderAction()
throw APIError(APIErrorType::Conflict, error.message()); throw APIError(APIErrorType::Conflict, error.message());
} }
} }
void TorrentsController::exportAction()
{
requireParams({u"hash"_qs});
const auto id = BitTorrent::TorrentID::fromString(params()[u"hash"_qs]);
const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent)
throw APIError(APIErrorType::NotFound);
const nonstd::expected<QByteArray, QString> result = torrent->exportToBuffer();
if (!result)
throw APIError(APIErrorType::Conflict, tr("Unable to export torrent file. Error: %1").arg(result.error()));
setResult(result.value());
}

1
src/webui/api/torrentscontroller.h

@ -87,4 +87,5 @@ private slots:
void toggleFirstLastPiecePrioAction(); void toggleFirstLastPiecePrioAction();
void renameFileAction(); void renameFileAction();
void renameFolderAction(); void renameFolderAction();
void exportAction();
}; };

3
src/webui/webapplication.cpp

@ -278,6 +278,9 @@ void WebApplication::doProcessRequest()
case QMetaType::QJsonDocument: case QMetaType::QJsonDocument:
print(result.toJsonDocument().toJson(QJsonDocument::Compact), Http::CONTENT_TYPE_JSON); print(result.toJsonDocument().toJson(QJsonDocument::Compact), Http::CONTENT_TYPE_JSON);
break; break;
case QMetaType::QByteArray:
print(result.toByteArray(), Http::CONTENT_TYPE_TXT);
break;
case QMetaType::QString: case QMetaType::QString:
default: default:
print(result.toString(), Http::CONTENT_TYPE_TXT); print(result.toString(), Http::CONTENT_TYPE_TXT);

2
src/webui/webapplication.h

@ -48,7 +48,7 @@
#include "base/utils/version.h" #include "base/utils/version.h"
#include "api/isessionmanager.h" #include "api/isessionmanager.h"
inline const Utils::Version<int, 3, 2> API_VERSION {2, 8, 10}; inline const Utils::Version<int, 3, 2> API_VERSION {2, 8, 11};
class APIController; class APIController;
class AuthController; class AuthController;

3
src/webui/www/private/index.html

@ -174,6 +174,9 @@
<li><a href="#" id="copyID" class="copyToClipboard"><img src="icons/edit-copy.svg" alt="QBT_TR(Torrent ID)QBT_TR[CONTEXT=TransferListWidget]" /> QBT_TR(Torrent ID)QBT_TR[CONTEXT=TransferListWidget]</a></li> <li><a href="#" id="copyID" class="copyToClipboard"><img src="icons/edit-copy.svg" alt="QBT_TR(Torrent ID)QBT_TR[CONTEXT=TransferListWidget]" /> QBT_TR(Torrent ID)QBT_TR[CONTEXT=TransferListWidget]</a></li>
</ul> </ul>
</li> </li>
<li>
<a href="#exportTorrent"><img src="icons/edit-copy.svg" alt="QBT_TR(Export .torrent)QBT_TR[CONTEXT=TransferListWidget]" /> QBT_TR(Export .torrent)QBT_TR[CONTEXT=TransferListWidget]</a>
</li>
</ul> </ul>
<ul id="categoriesFilterMenu" class="contextMenu"> <ul id="categoriesFilterMenu" class="contextMenu">
<li><a href="#createCategory"><img src="icons/list-add.svg" alt="QBT_TR(Add category...)QBT_TR[CONTEXT=CategoryFilterWidget]" /> QBT_TR(Add category...)QBT_TR[CONTEXT=CategoryFilterWidget]</a></li> <li><a href="#createCategory"><img src="icons/list-add.svg" alt="QBT_TR(Add category...)QBT_TR[CONTEXT=CategoryFilterWidget]" /> QBT_TR(Add category...)QBT_TR[CONTEXT=CategoryFilterWidget]</a></li>

21
src/webui/www/private/scripts/mocha-init.js

@ -88,6 +88,7 @@ let copyInfohashFN = function(policy) {};
let copyMagnetLinkFN = function() {}; let copyMagnetLinkFN = function() {};
let copyIdFN = function() {}; let copyIdFN = function() {};
let setQueuePositionFN = function() {}; let setQueuePositionFN = function() {};
let exportTorrentFN = function() {};
const initializeWindows = function() { const initializeWindows = function() {
saveWindowSize = function(windowId) { saveWindowSize = function(windowId) {
@ -957,6 +958,26 @@ const initializeWindows = function() {
return torrentsTable.selectedRowsIds().join("\n"); return torrentsTable.selectedRowsIds().join("\n");
}; };
exportTorrentFN = function() {
const hashes = torrentsTable.selectedRowsIds();
for (const hash of hashes) {
const row = torrentsTable.rows.get(hash);
if (!row) return
const name = row.full_data.name;
const url = new URI("api/v2/torrents/export");
url.setData("hash", hash);
// download response to file
const element = document.createElement("a");
element.setAttribute("href", url);
element.setAttribute("download", name + ".torrent");
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
};
['pause', 'resume'].each(function(item) { ['pause', 'resume'].each(function(item) {
addClickEvent(item + 'All', function(e) { addClickEvent(item + 'All', function(e) {
new Event(e).stop(); new Event(e).stop();

4
src/webui/www/private/views/transferlist.html

@ -97,6 +97,10 @@
superSeeding: function(element, ref) { superSeeding: function(element, ref) {
setSuperSeedingFN(!ref.getItemChecked('superSeeding')); setSuperSeedingFN(!ref.getItemChecked('superSeeding'));
},
exportTorrent: function(element, ref) {
exportTorrentFN();
} }
}, },
offsets: { offsets: {

Loading…
Cancel
Save