WebUI: disallow unnecessary quotes in property name
[qBittorrent.git] / src / base / bittorrent / torrentcreationmanager.cpp
blob9ff0b531dd1fc9fa1d9a23c425bfda1989bd5204
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
4 * Copyright (C) 2024 Radu Carpa <radu.carpa@cern.ch>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * In addition, as a special exception, the copyright holders give permission to
21 * link this program with the OpenSSL project's "OpenSSL" library (or with
22 * modified versions of it that use the same license as the "OpenSSL" library),
23 * and distribute the linked executables. You must obey the GNU General Public
24 * License in all respects for all of the code used other than "OpenSSL". If you
25 * modify file(s), you may extend this exception to your version of the file(s),
26 * but you are not obligated to do so. If you do not wish to do so, delete this
27 * exception statement from your version.
30 #include "torrentcreationmanager.h"
32 #include <utility>
34 #include <boost/multi_index_container.hpp>
35 #include <boost/multi_index/composite_key.hpp>
36 #include <boost/multi_index/indexed_by.hpp>
37 #include <boost/multi_index/mem_fun.hpp>
38 #include <boost/multi_index/ordered_index.hpp>
40 #include <QUuid>
42 #define SETTINGS_KEY(name) u"TorrentCreator/Manager/" name
44 namespace BitTorrent
46 using namespace boost::multi_index;
48 class TorrentCreationManager::TaskSet final : public boost::multi_index_container<
49 std::shared_ptr<TorrentCreationTask>,
50 indexed_by<
51 ordered_unique<tag<struct ByID>, const_mem_fun<TorrentCreationTask, QString, &TorrentCreationTask::id>>,
52 ordered_non_unique<tag<struct ByCompletion>, composite_key<
53 TorrentCreationTask,
54 const_mem_fun<TorrentCreationTask, bool, &TorrentCreationTask::isFinished>,
55 const_mem_fun<TorrentCreationTask, QDateTime, &TorrentCreationTask::timeAdded>>>>>
60 BitTorrent::TorrentCreationManager::TorrentCreationManager(IApplication *app, QObject *parent)
61 : ApplicationComponent(app, parent)
62 , m_maxTasks {SETTINGS_KEY(u"MaxTasks"_s), 256}
63 , m_numThreads {SETTINGS_KEY(u"NumThreads"_s), 1}
64 , m_tasks {std::make_unique<TaskSet>()}
65 , m_threadPool(this)
67 m_threadPool.setObjectName("TorrentCreationManager m_threadPool");
69 if (m_numThreads > 0)
70 m_threadPool.setMaxThreadCount(m_numThreads);
73 BitTorrent::TorrentCreationManager::~TorrentCreationManager() = default;
75 std::shared_ptr<BitTorrent::TorrentCreationTask> BitTorrent::TorrentCreationManager::createTask(const TorrentCreatorParams &params, bool startSeeding)
77 if (std::cmp_greater_equal(m_tasks->size(), m_maxTasks.get()))
79 // Try to delete old finished tasks to stay under target
80 auto &tasksByCompletion = m_tasks->get<ByCompletion>();
81 auto [iter, endIter] = tasksByCompletion.equal_range(std::make_tuple(true));
82 while ((iter != endIter) && std::cmp_greater_equal(m_tasks->size(), m_maxTasks.get()))
84 iter = tasksByCompletion.erase(iter);
87 if (std::cmp_greater_equal(m_tasks->size(), m_maxTasks.get()))
88 return {};
90 const QString taskID = generateTaskID();
92 auto *torrentCreator = new TorrentCreator(params, this);
93 auto creationTask = std::make_shared<TorrentCreationTask>(app(), taskID, torrentCreator, startSeeding);
94 connect(creationTask.get(), &QObject::destroyed, torrentCreator, &BitTorrent::TorrentCreator::requestInterruption);
96 m_tasks->get<ByID>().insert(creationTask);
97 m_threadPool.start(torrentCreator);
99 return creationTask;
102 QString BitTorrent::TorrentCreationManager::generateTaskID() const
104 const auto &tasksByID = m_tasks->get<ByID>();
105 QString taskID = QUuid::createUuid().toString(QUuid::WithoutBraces);
106 while (tasksByID.find(taskID) != tasksByID.end())
107 taskID = QUuid::createUuid().toString(QUuid::WithoutBraces);
109 return taskID;
112 std::shared_ptr<BitTorrent::TorrentCreationTask> BitTorrent::TorrentCreationManager::getTask(const QString &id) const
114 const auto &tasksByID = m_tasks->get<ByID>();
115 const auto iter = tasksByID.find(id);
116 if (iter == tasksByID.end())
117 return nullptr;
119 return *iter;
122 QList<std::shared_ptr<BitTorrent::TorrentCreationTask>> BitTorrent::TorrentCreationManager::tasks() const
124 const auto &tasksByCompletion = m_tasks->get<ByCompletion>();
125 return {tasksByCompletion.cbegin(), tasksByCompletion.cend()};
128 bool BitTorrent::TorrentCreationManager::deleteTask(const QString &id)
130 auto &tasksByID = m_tasks->get<ByID>();
131 const auto iter = tasksByID.find(id);
132 if (iter == tasksByID.end())
133 return false;
135 tasksByID.erase(iter);
136 return true;