2023-11-01 21:11:11 +00:00
|
|
|
// This file Copyright © Mnemosyne LLC.
|
2022-08-08 18:05:39 +00:00
|
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
2022-01-20 18:27:56 +00:00
|
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
|
|
// License text can be found in the licenses/ folder.
|
2009-04-09 18:55:47 +00:00
|
|
|
|
2016-03-29 16:37:21 +00:00
|
|
|
#pragma once
|
2009-04-09 18:55:47 +00:00
|
|
|
|
2024-01-21 22:50:26 +00:00
|
|
|
#include <array>
|
2022-04-08 01:50:26 +00:00
|
|
|
#include <cstdint> // int64_t
|
2020-08-15 15:42:51 +00:00
|
|
|
#include <map>
|
2024-01-21 22:50:26 +00:00
|
|
|
#include <optional>
|
2024-04-01 14:02:17 +00:00
|
|
|
#include <set>
|
2020-07-27 04:30:58 +00:00
|
|
|
#include <string_view>
|
2020-08-15 15:42:51 +00:00
|
|
|
#include <vector>
|
2020-07-27 04:30:58 +00:00
|
|
|
|
2009-04-09 18:55:47 +00:00
|
|
|
#include <QObject>
|
|
|
|
#include <QString>
|
2013-01-20 01:31:58 +00:00
|
|
|
#include <QStringList>
|
2020-08-27 01:42:41 +00:00
|
|
|
#include <QTimer>
|
2010-08-01 18:55:04 +00:00
|
|
|
|
2009-04-09 18:55:47 +00:00
|
|
|
#include <libtransmission/transmission.h>
|
2012-12-22 20:35:19 +00:00
|
|
|
#include <libtransmission/quark.h>
|
2021-12-14 08:43:27 +00:00
|
|
|
#include <libtransmission/tr-macros.h>
|
2009-04-09 18:55:47 +00:00
|
|
|
|
2015-06-10 21:27:11 +00:00
|
|
|
#include "RpcClient.h"
|
2020-07-29 16:56:23 +00:00
|
|
|
#include "RpcQueue.h"
|
2016-04-19 20:41:59 +00:00
|
|
|
#include "Torrent.h"
|
2019-11-12 01:37:05 +00:00
|
|
|
#include "Typedefs.h"
|
2014-12-27 20:03:10 +00:00
|
|
|
|
|
|
|
class AddData;
|
|
|
|
class Prefs;
|
|
|
|
|
2009-04-13 18:21:22 +00:00
|
|
|
extern "C"
|
|
|
|
{
|
2021-08-15 09:41:48 +00:00
|
|
|
struct tr_variant;
|
2009-04-13 18:21:22 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
class Session : public QObject
|
2009-04-09 18:55:47 +00:00
|
|
|
{
|
2013-02-03 19:40:20 +00:00
|
|
|
Q_OBJECT
|
2020-08-11 18:11:55 +00:00
|
|
|
TR_DISABLE_COPY_MOVE(Session)
|
2013-02-03 19:40:20 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
public:
|
2020-06-05 19:02:11 +00:00
|
|
|
Session(QString config_dir, Prefs& prefs);
|
2020-09-09 14:24:39 +00:00
|
|
|
~Session() override;
|
2013-02-03 19:40:20 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
void stop();
|
|
|
|
void restart();
|
2013-02-03 19:40:20 +00:00
|
|
|
|
2024-02-19 00:48:27 +00:00
|
|
|
[[nodiscard]] constexpr auto const& getRemoteUrl() const noexcept
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
return rpc_.url();
|
2017-04-19 12:04:45 +00:00
|
|
|
}
|
2013-02-03 19:40:20 +00:00
|
|
|
|
2022-06-13 03:59:30 +00:00
|
|
|
[[nodiscard]] constexpr auto const& getStats() const noexcept
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
return stats_;
|
2017-04-19 12:04:45 +00:00
|
|
|
}
|
|
|
|
|
2022-06-13 03:59:30 +00:00
|
|
|
[[nodiscard]] constexpr auto const& getCumulativeStats() const noexcept
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
return cumulative_stats_;
|
2017-04-19 12:04:45 +00:00
|
|
|
}
|
|
|
|
|
2022-06-13 03:59:30 +00:00
|
|
|
[[nodiscard]] constexpr auto const& sessionVersion() const noexcept
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
return session_version_;
|
2017-04-19 12:04:45 +00:00
|
|
|
}
|
|
|
|
|
2022-06-13 03:59:30 +00:00
|
|
|
[[nodiscard]] constexpr auto blocklistSize() const noexcept
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
return blocklist_size_;
|
2017-04-19 12:04:45 +00:00
|
|
|
}
|
|
|
|
|
2024-01-21 22:50:26 +00:00
|
|
|
enum PortTestIpProtocol : uint8_t
|
|
|
|
{
|
|
|
|
PORT_TEST_IPV4,
|
|
|
|
PORT_TEST_IPV6,
|
|
|
|
NUM_PORT_TEST_IP_PROTOCOL
|
|
|
|
};
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
void setBlocklistSize(int64_t i);
|
|
|
|
void updateBlocklist();
|
2024-01-21 22:50:26 +00:00
|
|
|
void portTest(PortTestIpProtocol ip_protocol);
|
2020-05-27 21:53:12 +00:00
|
|
|
void copyMagnetLinkToClipboard(int torrent_id);
|
2013-02-03 19:40:20 +00:00
|
|
|
|
2024-01-21 22:50:26 +00:00
|
|
|
bool portTestPending(PortTestIpProtocol ip_protocol) const noexcept;
|
|
|
|
|
2013-02-03 19:40:20 +00:00
|
|
|
/** returns true if the transmission session is being run inside this client */
|
2024-02-19 00:48:27 +00:00
|
|
|
[[nodiscard]] constexpr auto isServer() const noexcept
|
|
|
|
{
|
|
|
|
return session_ != nullptr;
|
|
|
|
}
|
2013-02-03 19:40:20 +00:00
|
|
|
|
2017-04-21 07:40:57 +00:00
|
|
|
/** returns true if isServer() is true or if the remote address is the localhost */
|
2024-02-19 00:48:27 +00:00
|
|
|
[[nodiscard]] auto isLocal() const noexcept
|
|
|
|
{
|
|
|
|
return !session_id_.isEmpty() ? is_definitely_local_session_ : rpc_.isLocal();
|
|
|
|
}
|
2017-04-19 12:04:45 +00:00
|
|
|
|
|
|
|
RpcResponseFuture exec(tr_quark method, tr_variant* args);
|
2020-07-27 04:30:58 +00:00
|
|
|
RpcResponseFuture exec(std::string_view method, tr_variant* args);
|
2017-04-20 16:02:19 +00:00
|
|
|
|
2020-07-29 16:56:23 +00:00
|
|
|
using Tag = RpcQueue::Tag;
|
2022-09-08 23:26:18 +00:00
|
|
|
Tag torrentSet(torrent_ids_t const& torrent_ids, tr_quark const key, bool val);
|
|
|
|
Tag torrentSet(torrent_ids_t const& torrent_ids, tr_quark const key, int val);
|
|
|
|
Tag torrentSet(torrent_ids_t const& torrent_ids, tr_quark const key, double val);
|
|
|
|
Tag torrentSet(torrent_ids_t const& torrent_ids, tr_quark const key, QString const& val);
|
2023-10-25 01:14:37 +00:00
|
|
|
Tag torrentSet(torrent_ids_t const& torrent_ids, tr_quark const key, std::vector<int> const& val);
|
2022-09-08 23:26:18 +00:00
|
|
|
Tag torrentSet(torrent_ids_t const& torrent_ids, tr_quark const key, QStringList const& val);
|
|
|
|
|
|
|
|
void torrentSetLocation(torrent_ids_t const& torrent_ids, QString const& path, bool do_move);
|
|
|
|
void torrentRenamePath(torrent_ids_t const& torrent_ids, QString const& oldpath, QString const& newname);
|
2023-11-04 18:14:08 +00:00
|
|
|
void addTorrent(AddData add_me, tr_variant* args_dict);
|
2019-11-12 01:37:05 +00:00
|
|
|
void initTorrents(torrent_ids_t const& ids = {});
|
2022-09-08 23:26:18 +00:00
|
|
|
void pauseTorrents(torrent_ids_t const& torrent_ids = {});
|
|
|
|
void startTorrents(torrent_ids_t const& torrent_ids = {});
|
|
|
|
void startTorrentsNow(torrent_ids_t const& torrent_ids = {});
|
2020-05-27 21:53:12 +00:00
|
|
|
void refreshDetailInfo(torrent_ids_t const& torrent_ids);
|
2017-04-19 12:04:45 +00:00
|
|
|
void refreshActiveTorrents();
|
|
|
|
void refreshAllTorrents();
|
2020-05-27 21:53:12 +00:00
|
|
|
void addNewlyCreatedTorrent(QString const& filename, QString const& local_path);
|
|
|
|
void verifyTorrents(torrent_ids_t const& torrent_ids);
|
|
|
|
void reannounceTorrents(torrent_ids_t const& torrent_ids);
|
2022-09-08 23:26:18 +00:00
|
|
|
void refreshExtraStats(torrent_ids_t const& torrent_ids);
|
2019-11-09 14:44:40 +00:00
|
|
|
|
2020-08-15 15:42:51 +00:00
|
|
|
enum class TorrentProperties
|
|
|
|
{
|
|
|
|
MainInfo,
|
|
|
|
MainStats,
|
|
|
|
MainAll,
|
|
|
|
DetailInfo,
|
|
|
|
DetailStat,
|
|
|
|
Rename
|
|
|
|
};
|
|
|
|
|
2024-04-01 14:02:17 +00:00
|
|
|
void addKeyName(TorrentProperties props, tr_quark const key)
|
|
|
|
{
|
|
|
|
// populate names cache with default values
|
|
|
|
if (names_[props].empty())
|
|
|
|
{
|
|
|
|
getKeyNames(props);
|
|
|
|
}
|
|
|
|
|
|
|
|
names_[props].emplace(tr_quark_get_string_view(key));
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeKeyName(TorrentProperties props, tr_quark const key)
|
|
|
|
{
|
|
|
|
// do not remove id because it must be in every torrent req
|
|
|
|
if (key != TR_KEY_id)
|
|
|
|
{
|
|
|
|
names_[props].erase(tr_quark_get_string_view(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-09 14:44:40 +00:00
|
|
|
public slots:
|
2022-09-08 23:26:18 +00:00
|
|
|
void addTorrent(AddData add_me);
|
2020-11-09 03:31:02 +00:00
|
|
|
void launchWebInterface() const;
|
2019-11-12 01:37:05 +00:00
|
|
|
void queueMoveBottom(torrent_ids_t const& torrentIds = {});
|
|
|
|
void queueMoveDown(torrent_ids_t const& torrentIds = {});
|
|
|
|
void queueMoveTop(torrent_ids_t const& torrentIds = {});
|
|
|
|
void queueMoveUp(torrent_ids_t const& torrentIds = {});
|
2019-11-09 14:44:40 +00:00
|
|
|
void refreshSessionInfo();
|
|
|
|
void refreshSessionStats();
|
2020-05-27 21:53:12 +00:00
|
|
|
void removeTorrents(torrent_ids_t const& torrent_ids, bool delete_files = false);
|
2017-04-19 12:04:45 +00:00
|
|
|
void updatePref(int key);
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void sourceChanged();
|
2024-01-21 22:50:26 +00:00
|
|
|
void portTested(std::optional<bool> status, PortTestIpProtocol ip_protocol);
|
2017-04-19 12:04:45 +00:00
|
|
|
void statsUpdated();
|
|
|
|
void sessionUpdated();
|
|
|
|
void blocklistUpdated(int);
|
2020-05-27 21:53:12 +00:00
|
|
|
void torrentsUpdated(tr_variant* torrent_list, bool complete_list);
|
|
|
|
void torrentsRemoved(tr_variant* torrent_list);
|
2020-07-29 16:56:23 +00:00
|
|
|
void sessionCalled(Tag);
|
2017-04-19 12:04:45 +00:00
|
|
|
void dataReadProgress();
|
|
|
|
void dataSendProgress();
|
2017-04-20 16:02:19 +00:00
|
|
|
void networkResponse(QNetworkReply::NetworkError code, QString const& message);
|
2017-04-19 12:04:45 +00:00
|
|
|
void httpAuthenticationRequired();
|
|
|
|
|
2020-11-05 22:46:21 +00:00
|
|
|
private slots:
|
|
|
|
void onDuplicatesTimer();
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
private:
|
|
|
|
void start();
|
|
|
|
|
2022-09-08 23:26:18 +00:00
|
|
|
void updateStats(tr_variant* args_dict);
|
|
|
|
void updateInfo(tr_variant* args_dict);
|
2017-04-19 12:04:45 +00:00
|
|
|
|
2020-07-29 16:56:23 +00:00
|
|
|
Tag torrentSetImpl(tr_variant* args);
|
2022-09-08 23:26:18 +00:00
|
|
|
void sessionSet(tr_quark const key, QVariant const& value);
|
2017-04-19 12:04:45 +00:00
|
|
|
void pumpRequests();
|
2020-07-27 04:30:58 +00:00
|
|
|
void sendTorrentRequest(std::string_view request, torrent_ids_t const& torrent_ids);
|
2020-08-15 15:42:51 +00:00
|
|
|
void refreshTorrents(torrent_ids_t const& ids, TorrentProperties props);
|
2024-04-01 14:02:17 +00:00
|
|
|
std::set<std::string_view> const& getKeyNames(TorrentProperties props);
|
2017-04-19 12:04:45 +00:00
|
|
|
|
2022-09-08 23:26:18 +00:00
|
|
|
static void updateStats(tr_variant* args_dict, tr_session_stats* stats);
|
2017-04-19 12:04:45 +00:00
|
|
|
|
2022-09-08 23:26:18 +00:00
|
|
|
void addOptionalIds(tr_variant* args_dict, torrent_ids_t const& torrent_ids) const;
|
2020-08-15 15:42:51 +00:00
|
|
|
|
2020-05-27 21:53:12 +00:00
|
|
|
QString const config_dir_;
|
|
|
|
Prefs& prefs_;
|
|
|
|
|
2024-04-01 14:02:17 +00:00
|
|
|
std::map<TorrentProperties, std::set<std::string_view>> names_;
|
2020-08-15 15:42:51 +00:00
|
|
|
|
2020-05-27 21:53:12 +00:00
|
|
|
int64_t blocklist_size_ = -1;
|
2024-01-21 22:50:26 +00:00
|
|
|
std::array<bool, NUM_PORT_TEST_IP_PROTOCOL> port_test_pending_ = {};
|
2020-05-27 21:53:12 +00:00
|
|
|
tr_session* session_ = {};
|
|
|
|
QStringList idle_json_;
|
2022-09-08 23:26:18 +00:00
|
|
|
tr_session_stats stats_ = EmptyStats;
|
|
|
|
tr_session_stats cumulative_stats_ = EmptyStats;
|
2020-05-27 21:53:12 +00:00
|
|
|
QString session_version_;
|
|
|
|
QString session_id_;
|
|
|
|
bool is_definitely_local_session_ = true;
|
|
|
|
RpcClient rpc_;
|
2020-08-15 15:42:51 +00:00
|
|
|
torrent_ids_t const RecentlyActiveIDs = { -1 };
|
2020-08-27 01:42:41 +00:00
|
|
|
|
|
|
|
std::map<QString, QString> duplicates_;
|
|
|
|
QTimer duplicates_timer_;
|
2022-09-08 23:26:18 +00:00
|
|
|
|
|
|
|
static auto constexpr EmptyStats = tr_session_stats{ TR_RATIO_NA, 0, 0, 0, 0, 0 };
|
2009-04-09 18:55:47 +00:00
|
|
|
};
|