From d89ef22d85d6828b5a7748da6018597b910d1c2f Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Mon, 23 Jul 2018 01:48:35 -0400 Subject: [PATCH 1/3] Require torrent category creation to be explicit --- src/base/bittorrent/torrenthandle.cpp | 6 ++---- src/webui/api/torrentscontroller.cpp | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 7fa4015e9..4960a94d0 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1214,10 +1214,8 @@ bool TorrentHandle::setCategory(const QString &category) { if (m_category != category) { if (!category.isEmpty()) { - if (!Session::isValidCategoryName(category)) return false; - if (!m_session->categories().contains(category)) - if (!m_session->addCategory(category)) - return false; + if (!Session::isValidCategoryName(category) || !m_session->categories().contains(category)) + return false; } QString oldCategory = m_category; diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index cdb5fd004..9eb3d1b65 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -811,6 +811,10 @@ void TorrentsController::setCategoryAction() const QString category {params()["category"].trimmed()}; applyToTorrents(hashes, [category](BitTorrent::TorrentHandle *torrent) { + auto *session = BitTorrent::Session::instance(); + const QStringList categories = session->categories().keys(); + if (!categories.contains(category) && !session->addCategory(category)) + throw APIError(APIErrorType::Conflict, tr("Unable to create category")); if (!torrent->setCategory(category)) throw APIError(APIErrorType::Conflict, tr("Incorrect category name")); }); From a0e6007fc19a8e84af4f592d05706ec12b683635 Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Mon, 23 Jul 2018 00:53:56 -0400 Subject: [PATCH 2/3] Include category save path in web api sync data --- src/webui/api/synccontroller.cpp | 15 ++++++++++----- src/webui/www/private/scripts/client.js | 7 ++++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp index d8fe4d464..9c1995f06 100644 --- a/src/webui/api/synccontroller.cpp +++ b/src/webui/api/synccontroller.cpp @@ -320,7 +320,7 @@ namespace // - "full_update": full data update flag // - "torrents": dictionary contains information about torrents. // - "torrents_removed": a list of hashes of removed torrents -// - "categories": list of categories +// - "categories": map of categories info // - "categories_removed": list of removed categories // - "server_state": map contains information about the state of the server // The keys of the 'torrents' dictionary are hashes of torrents. @@ -399,11 +399,16 @@ void SyncController::maindataAction() data["torrents"] = torrents; - QVariantList categories; - for (auto i = session->categories().cbegin(); i != session->categories().cend(); ++i) - categories << i.key(); + QVariantList categoriesList; + const auto categories = session->categories(); + for (auto key : categories.keys()) { + categoriesList << QVariantMap { + {"name", key}, + {"savePath", categories.value(key)}, + }; + } - data["categories"] = categories; + data["categories"] = categoriesList; QVariantMap serverState = getTranserInfo(); serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled(); diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index 5561c29ef..667298ce9 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -317,9 +317,10 @@ window.addEvent('load', function() { } if (response['categories']) { response['categories'].each(function(category) { - var categoryHash = genHash(category); + var categoryHash = genHash(category.name); category_list[categoryHash] = { - name: category, + name: category.name, + savePath: category.savePath, torrents: [] }; }); @@ -327,7 +328,7 @@ window.addEvent('load', function() { } if (response['categories_removed']) { response['categories_removed'].each(function(category) { - var categoryHash = genHash(category); + var categoryHash = genHash(category.name); delete category_list[categoryHash]; }); update_categories = true; From 63c53766b428b54cb69191e9f7eb0e6c04123082 Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Mon, 23 Jul 2018 01:49:34 -0400 Subject: [PATCH 3/3] Add save path and editing to WebUI new category dialog --- src/base/bittorrent/torrenthandle.cpp | 6 +- src/webui/api/synccontroller.cpp | 13 +- src/webui/api/torrentscontroller.cpp | 31 ++++- src/webui/api/torrentscontroller.h | 1 + src/webui/extra_translations.h | 3 +- src/webui/www/private/filters.html | 3 + src/webui/www/private/index.html | 1 + src/webui/www/private/newcategory.html | 136 +++++++++++++------ src/webui/www/private/scripts/client.js | 25 ++-- src/webui/www/private/scripts/contextmenu.js | 8 +- src/webui/www/private/scripts/misc.js | 11 ++ src/webui/www/private/scripts/mocha-init.js | 30 +++- 12 files changed, 197 insertions(+), 71 deletions(-) diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 4960a94d0..4750a6a84 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1213,10 +1213,8 @@ void TorrentHandle::setName(const QString &name) bool TorrentHandle::setCategory(const QString &category) { if (m_category != category) { - if (!category.isEmpty()) { - if (!Session::isValidCategoryName(category) || !m_session->categories().contains(category)) - return false; - } + if (!category.isEmpty() && !m_session->categories().contains(category)) + return false; QString oldCategory = m_category; m_category = category; diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp index 9c1995f06..597a207e3 100644 --- a/src/webui/api/synccontroller.cpp +++ b/src/webui/api/synccontroller.cpp @@ -399,16 +399,17 @@ void SyncController::maindataAction() data["torrents"] = torrents; - QVariantList categoriesList; - const auto categories = session->categories(); - for (auto key : categories.keys()) { - categoriesList << QVariantMap { + QVariantHash categories; + const auto categoriesList = session->categories(); + for (auto it = categoriesList.cbegin(); it != categoriesList.cend(); ++it) { + const auto key = it.key(); + categories[key] = QVariantMap { {"name", key}, - {"savePath", categories.value(key)}, + {"savePath", it.value()} }; } - data["categories"] = categoriesList; + data["categories"] = categories; QVariantMap serverState = getTranserInfo(); serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled(); diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 9eb3d1b65..0b23e1e94 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -738,7 +738,7 @@ void TorrentsController::setLocationAction() const QString newLocation {params()["location"].trimmed()}; if (newLocation.isEmpty()) - throw APIError(APIErrorType::BadParams, tr("Save path is empty")); + throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty")); // try to create the location if it does not exist if (!QDir(newLocation).mkpath(".")) @@ -809,12 +809,9 @@ void TorrentsController::setCategoryAction() const QStringList hashes {params()["hashes"].split('|')}; const QString category {params()["category"].trimmed()}; + applyToTorrents(hashes, [category](BitTorrent::TorrentHandle *torrent) { - auto *session = BitTorrent::Session::instance(); - const QStringList categories = session->categories().keys(); - if (!categories.contains(category) && !session->addCategory(category)) - throw APIError(APIErrorType::Conflict, tr("Unable to create category")); if (!torrent->setCategory(category)) throw APIError(APIErrorType::Conflict, tr("Incorrect category name")); }); @@ -825,10 +822,30 @@ void TorrentsController::createCategoryAction() checkParams({"category"}); const QString category {params()["category"].trimmed()}; - if (!BitTorrent::Session::isValidCategoryName(category) && !category.isEmpty()) + const QString savePath {params()["savePath"]}; + + if (category.isEmpty()) + throw APIError(APIErrorType::BadParams, tr("Category cannot be empty")); + + if (!BitTorrent::Session::isValidCategoryName(category)) throw APIError(APIErrorType::Conflict, tr("Incorrect category name")); - BitTorrent::Session::instance()->addCategory(category); + if (!BitTorrent::Session::instance()->addCategory(category, savePath)) + throw APIError(APIErrorType::Conflict, tr("Unable to create category")); +} + +void TorrentsController::editCategoryAction() +{ + checkParams({"category", "savePath"}); + + const QString category {params()["category"].trimmed()}; + const QString savePath {params()["savePath"]}; + + if (category.isEmpty()) + throw APIError(APIErrorType::BadParams, tr("Category cannot be empty")); + + if (!BitTorrent::Session::instance()->editCategory(category, savePath)) + throw APIError(APIErrorType::Conflict, tr("Unable to edit category")); } void TorrentsController::removeCategoriesAction() diff --git a/src/webui/api/torrentscontroller.h b/src/webui/api/torrentscontroller.h index 0abaa30a3..5ddcaf6b0 100644 --- a/src/webui/api/torrentscontroller.h +++ b/src/webui/api/torrentscontroller.h @@ -53,6 +53,7 @@ private slots: void renameAction(); void setCategoryAction(); void createCategoryAction(); + void editCategoryAction(); void removeCategoriesAction(); void addAction(); void deleteAction(); diff --git a/src/webui/extra_translations.h b/src/webui/extra_translations.h index d06ad9a0e..2d8ce1123 100644 --- a/src/webui/extra_translations.h +++ b/src/webui/extra_translations.h @@ -78,7 +78,8 @@ const char *QBT_WEBUI_TRANSLATIONS[] = { QT_TRANSLATE_NOOP("HttpServer", "Set location"), QT_TRANSLATE_NOOP("HttpServer", "Limit upload rate"), QT_TRANSLATE_NOOP("HttpServer", "Limit download rate"), - QT_TRANSLATE_NOOP("HttpServer", "Rename torrent") + QT_TRANSLATE_NOOP("HttpServer", "Rename torrent"), + QT_TRANSLATE_NOOP("HttpServer", "Unable to create category") }; const struct { const char *source; const char *comment; } QBT_WEBUI_COMMENTED_TRANSLATIONS[] = { diff --git a/src/webui/www/private/filters.html b/src/webui/www/private/filters.html index 890431a4b..afe65ecb6 100644 --- a/src/webui/www/private/filters.html +++ b/src/webui/www/private/filters.html @@ -23,6 +23,9 @@ CreateCategory: function(element, ref) { createCategoryFN(); }, + EditCategory: function(element, ref) { + editCategoryFN(element.id); + }, DeleteCategory: function(element, ref) { removeCategoryFN(element.id); }, diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html index 8947633ab..de6ccbb15 100644 --- a/src/webui/www/private/index.html +++ b/src/webui/www/private/index.html @@ -143,6 +143,7 @@
  • QBT_TR(Add category...)QBT_TR[CONTEXT=CategoryFilterWidget] QBT_TR(Add category...)QBT_TR[CONTEXT=CategoryFilterWidget]
  • +
  • QBT_TR(Edit category...)QBT_TR[CONTEXT=CategoryFilterWidget] QBT_TR(Edit category...)QBT_TR[CONTEXT=CategoryFilterWidget]
  • QBT_TR(Remove category)QBT_TR[CONTEXT=CategoryFilterWidget] QBT_TR(Remove category)QBT_TR[CONTEXT=CategoryFilterWidget]
  • QBT_TR(Remove unused categories)QBT_TR[CONTEXT=CategoryFilterWidget] QBT_TR(Remove unused categories)QBT_TR[CONTEXT=CategoryFilterWidget]
  • QBT_TR(Resume torrents)QBT_TR[CONTEXT=CategoryFilterWidget] QBT_TR(Resume torrents)QBT_TR[CONTEXT=CategoryFilterWidget]
  • diff --git a/src/webui/www/private/newcategory.html b/src/webui/www/private/newcategory.html index eaa62752c..57fd53490 100644 --- a/src/webui/www/private/newcategory.html +++ b/src/webui/www/private/newcategory.html @@ -7,12 +7,13 @@ +