mirror of
https://github.com/transmission/transmission.git
synced 2026-02-15 07:26:49 +00:00
* fix: legacy RPC tag should ignore non-integers * refactor: delegate legacy RPC callback to api-compat * refactor: move `TR_KEY_alt_speed_down_kebab` handling * refactor: move `TR_KEY_alt_speed_enabled_kebab` handling * refactor: move `TR_KEY_alt_speed_time_begin_kebab` handling * refactor: move `TR_KEY_alt_speed_time_day_kebab` handling * refactor: move `TR_KEY_alt_speed_time_enabled_kebab` handling * refactor: move `TR_KEY_alt_speed_time_end_kebab` handling * refactor: move `TR_KEY_alt_speed_up_kebab` handling * refactor: move `TR_KEY_anti_brute_force_enabled_kebab` handling * refactor: move `TR_KEY_anti_brute_force_threshold_kebab` handling * refactor: move `TR_KEY_blocklist_enabled_kebab` handling * refactor: move `TR_KEY_blocklist_size_kebab` handling * refactor: move `TR_KEY_blocklist_url_kebab` handling * refactor: move `TR_KEY_cache_size_mb_kebab` handling * refactor: move `TR_KEY_config_dir_kebab` handling * refactor: move `TR_KEY_default_trackers_kebab` handling * refactor: move `TR_KEY_dht_enabled_kebab` handling * refactor: move `TR_KEY_download_dir_kebab` handling * refactor: move `TR_KEY_download_dir_free_space_kebab` handling * refactor: move `TR_KEY_download_queue_enabled_kebab` handling * refactor: move `TR_KEY_download_queue_size_kebab` handling * refactor: move `TR_KEY_idle_seeding_limit_kebab` handling * refactor: move `TR_KEY_idle_seeding_limit_enabled_kebab` handling * refactor: move `TR_KEY_incomplete_dir_kebab` handling * refactor: move `TR_KEY_incomplete_dir_enabled_kebab` handling * refactor: move `TR_KEY_lpd_enabled_kebab` handling * refactor: move `TR_KEY_peer_limit_global_kebab` handling * refactor: move `TR_KEY_peer_limit_per_torrent_kebab` handling * refactor: move `TR_KEY_peer_port_kebab` handling * refactor: move `TR_KEY_peer_port_random_on_start_kebab` handling * refactor: move `TR_KEY_pex_enabled_kebab` handling * refactor: move `TR_KEY_port_forwarding_enabled_kebab` handling * refactor: move `TR_KEY_queue_stalled_enabled_kebab` handling * refactor: move `TR_KEY_queue_stalled_minutes_kebab` handling * refactor: move `TR_KEY_rename_partial_files_kebab` handling * refactor: move `TR_KEY_rpc_version_kebab` handling * refactor: move `TR_KEY_rpc_version_minimum_kebab` handling * refactor: move `TR_KEY_rpc_version_semver_kebab` handling * refactor: move `TR_KEY_script_torrent_added_enabled_kebab` handling * refactor: move `TR_KEY_script_torrent_added_filename_kebab` handling * refactor: move `TR_KEY_script_torrent_done_enabled_kebab` handling * refactor: move `TR_KEY_script_torrent_done_filename_kebab` handling * refactor: move `TR_KEY_script_torrent_done_seeding_enabled_kebab` handling * refactor: move `TR_KEY_script_torrent_done_seeding_filename_kebab` handling * refactor: remove `tr_quark_convert` usage for `tr_session::Scripts` * refactor: move `TR_KEY_seed_ratio_limit_camel` handling * refactor: move `TR_KEY_seed_ratio_limited_camel` handling * refactor: move `TR_KEY_seed_queue_enabled_kebab` handling * refactor: move `TR_KEY_seed_queue_size_kebab` handling * refactor: move `TR_KEY_session_id_kebab` handling * refactor: move `TR_KEY_speed_limit_down_kebab` handling * refactor: move `TR_KEY_speed_limit_down_enabled_kebab` handling * refactor: move `TR_KEY_speed_limit_up_kebab` handling * refactor: move `TR_KEY_speed_limit_up_enabled_kebab` handling * refactor: move `TR_KEY_start_added_torrents_kebab` handling * refactor: move `TR_KEY_tcp_enabled_kebab` handling * refactor: move `TR_KEY_trash_original_torrent_files_kebab` handling * refactor: move `TR_KEY_utp_enabled_kebab` handling * refactor: move `TR_KEY_recently_active_kebab` handling * refactor: move `TR_KEY_delete_local_data_kebab` handling * refactor: move `TR_KEY_activity_date_camel` handling * refactor: move `TR_KEY_added_date_camel` handling * refactor: move `TR_KEY_bandwidth_priority_camel` handling * refactor: move `TR_KEY_bytes_completed_camel` handling * refactor: move `TR_KEY_corrupt_ever_camel` handling * refactor: move `TR_KEY_date_created_camel` handling * refactor: move `TR_KEY_desired_available_camel` handling * refactor: move `TR_KEY_done_date_camel` handling * refactor: move `TR_KEY_download_dir_camel` handling * refactor: move `TR_KEY_download_limit_camel` handling * refactor: move `TR_KEY_download_limited_camel` handling * refactor: move `TR_KEY_downloaded_ever_camel` handling * refactor: move `TR_KEY_edit_date_camel` handling * refactor: move `TR_KEY_error_string_camel` handling * refactor: move `TR_KEY_eta_idle_camel` handling * refactor: move `TR_KEY_file_stats_camel` handling * refactor: move `TR_KEY_file_count_kebab` handling * refactor: move `TR_KEY_hash_string_camel` handling * refactor: move `TR_KEY_have_unchecked_camel` handling * refactor: move `TR_KEY_have_valid_camel` handling * refactor: move `TR_KEY_honors_session_limits_camel` handling * refactor: move `TR_KEY_is_finished_camel` handling * refactor: move `TR_KEY_is_private_camel` handling * refactor: move `TR_KEY_is_stalled_camel` handling * refactor: move `TR_KEY_left_until_done_camel` handling * refactor: move `TR_KEY_magnet_link_camel` handling * refactor: move `TR_KEY_manual_announce_time_camel` handling * refactor: move `TR_KEY_max_connected_peers_camel` handling * refactor: move `TR_KEY_metadata_percent_complete_camel` handling * refactor: move `TR_KEY_peer_limit_kebab` handling * refactor: move `TR_KEY_peers_connected_camel` handling * refactor: move `TR_KEY_peers_from_camel` handling * refactor: move `TR_KEY_peers_getting_from_us_camel` handling * refactor: move `TR_KEY_peers_sending_to_us_camel` handling * refactor: move `TR_KEY_percent_complete_camel` handling * refactor: move `TR_KEY_percent_done_camel` handling * refactor: move `TR_KEY_piece_count_camel` handling * refactor: move `TR_KEY_piece_size_camel` handling * refactor: move `TR_KEY_primary_mime_type_kebab` handling * refactor: move `TR_KEY_queue_position_camel` handling * refactor: move `TR_KEY_rate_download_camel` handling * refactor: move `TR_KEY_rate_upload_camel` handling * refactor: move `TR_KEY_recheck_progress_camel` handling * refactor: move `TR_KEY_seconds_downloading_camel` handling * refactor: move `TR_KEY_seconds_seeding_camel` handling * refactor: move `TR_KEY_seed_idle_limit_camel` handling * refactor: move `TR_KEY_seed_idle_mode_camel` handling * refactor: move `TR_KEY_seed_ratio_mode_camel` handling * refactor: move `TR_KEY_size_when_done_camel` handling * refactor: move `TR_KEY_start_date_camel` handling * refactor: move `TR_KEY_torrent_file_camel` handling * refactor: move `TR_KEY_total_size_camel` handling * refactor: move `TR_KEY_tracker_list_camel` handling * refactor: move `TR_KEY_tracker_stats_camel` handling * refactor: move `TR_KEY_upload_limit_camel` handling * refactor: move `TR_KEY_upload_limited_camel` handling * refactor: move `TR_KEY_upload_ratio_camel` handling * refactor: move `TR_KEY_uploaded_ever_camel` handling * refactor: move `TR_KEY_webseeds_sending_to_us_camel` handling * refactor: move `TR_KEY_announce_state_camel` handling * refactor: move `TR_KEY_download_count_camel` handling * refactor: move `TR_KEY_has_announced_camel` handling * refactor: move `TR_KEY_has_scraped_camel` handling * refactor: move `TR_KEY_is_backup_camel` handling * refactor: move `TR_KEY_last_announce_peer_count_camel` handling * refactor: move `TR_KEY_last_announce_result_camel` handling * refactor: move `TR_KEY_last_announce_start_time_camel` handling * refactor: move `TR_KEY_last_announce_succeeded_camel` handling * refactor: move `TR_KEY_last_announce_time_camel` handling * refactor: move `TR_KEY_last_announce_timed_out_camel` handling * refactor: move `TR_KEY_last_scrape_result_camel` handling * refactor: move `TR_KEY_last_scrape_start_time_camel` handling * refactor: move `TR_KEY_last_scrape_succeeded_camel` handling * refactor: move `TR_KEY_last_scrape_time_camel` handling * refactor: move `TR_KEY_last_scrape_timed_out_camel` handling * refactor: move `TR_KEY_leecher_count_camel` handling * refactor: move `TR_KEY_next_announce_time_camel` handling * refactor: move `TR_KEY_next_scrape_time_camel` handling * refactor: move `TR_KEY_scrape_state_camel` handling * refactor: move `TR_KEY_seeder_count_camel` handling * refactor: move `TR_KEY_client_is_choked_camel` handling * refactor: move `TR_KEY_client_is_interested_camel` handling * refactor: move `TR_KEY_client_name_camel` handling * refactor: move `TR_KEY_flag_str_camel` handling * refactor: move `TR_KEY_is_downloading_from_camel` handling * refactor: move `TR_KEY_is_encrypted_camel` handling * refactor: move `TR_KEY_is_incoming_camel` handling * refactor: move `TR_KEY_is_utp_camel` handling * refactor: move `TR_KEY_is_uploading_to_camel` handling * refactor: move `TR_KEY_peer_is_choked_camel` handling * refactor: move `TR_KEY_peer_is_interested_camel` handling * refactor: move `TR_KEY_rate_to_client_camel` handling * refactor: move `TR_KEY_rate_to_peer_camel` handling * refactor: move `TR_KEY_from_cache_camel` handling * refactor: move `TR_KEY_from_dht_camel` handling * refactor: move `TR_KEY_from_incoming_camel` handling * refactor: move `TR_KEY_from_lpd_camel` handling * refactor: move `TR_KEY_from_ltep_camel` handling * refactor: move `TR_KEY_from_pex_camel` handling * refactor: move `TR_KEY_from_pex_camel` handling * refactor: move `TR_KEY_tracker_add_camel` handling * refactor: move `TR_KEY_tracker_remove_camel` handling * refactor: move `TR_KEY_tracker_replace_camel` handling * refactor: move `TR_KEY_downloaded_bytes_camel` handling * refactor: move `TR_KEY_files_added_camel` handling * refactor: move `TR_KEY_seconds_active_camel` handling * refactor: move `TR_KEY_session_count_camel` handling * refactor: move `TR_KEY_uploaded_bytes_camel` handling * refactor: move `TR_KEY_active_torrent_count_camel` handling * refactor: move `TR_KEY_cumulative_stats_kebab` handling * refactor: move `TR_KEY_cumulative_stats_kebab` handling * refactor: move `TR_KEY_download_speed_camel` handling * refactor: move `TR_KEY_paused_torrent_count_camel` handling * refactor: move `TR_KEY_torrent_count_camel` handling * refactor: move `TR_KEY_upload_speed_camel` handling * refactor: move `TR_KEY_files_unwanted_kebab` handling * refactor: move `TR_KEY_files_wanted_kebab` handling * refactor: move `TR_KEY_priority_high_kebab` handling * refactor: move `TR_KEY_priority_low_kebab` handling * refactor: move `TR_KEY_priority_normal_kebab` handling * refactor: move `TR_KEY_port_is_open_kebab` handling * refactor: move `TR_KEY_torrent_duplicate_kebab` handling * refactor: move `TR_KEY_torrent_added_kebab` handling * refactor: move `TR_KEY_memory_bytes_kebab` handling * refactor: move `TR_KEY_memory_units_kebab` handling * refactor: move `TR_KEY_size_bytes_kebab` handling * refactor: move `TR_KEY_size_units_kebab` handling * refactor: move `TR_KEY_speed_bytes_kebab` handling * refactor: move `TR_KEY_speed_units_kebab` handling * refactor: remove DoneCb * perf: adjust reserve capacity
108 lines
3.0 KiB
C++
108 lines
3.0 KiB
C++
// This file Copyright © Mnemosyne LLC.
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
// License text can be found in the licenses/ folder.
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint> // int64_t
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string_view>
|
|
#include <unordered_map>
|
|
|
|
#include <QFuture>
|
|
#include <QFutureInterface>
|
|
#include <QNetworkRequest>
|
|
#include <QNetworkReply>
|
|
#include <QObject>
|
|
#include <QString>
|
|
#include <QUrl>
|
|
|
|
#include <libtransmission/transmission.h>
|
|
|
|
#include <libtransmission/api-compat.h>
|
|
#include <libtransmission/quark.h>
|
|
#include <libtransmission/variant.h>
|
|
|
|
class QNetworkAccessManager;
|
|
|
|
using TrVariantPtr = std::shared_ptr<tr_variant>;
|
|
Q_DECLARE_METATYPE(TrVariantPtr)
|
|
|
|
extern "C"
|
|
{
|
|
struct tr_session;
|
|
}
|
|
|
|
struct RpcResponse
|
|
{
|
|
QString errmsg;
|
|
TrVariantPtr args;
|
|
bool success = false;
|
|
QNetworkReply::NetworkError networkError = QNetworkReply::NoError;
|
|
};
|
|
|
|
Q_DECLARE_METATYPE(QFutureInterface<RpcResponse>)
|
|
|
|
// The response future -- the RPC engine returns one for each request made.
|
|
using RpcResponseFuture = QFuture<RpcResponse>;
|
|
|
|
class RpcClient : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit RpcClient(QObject* parent = nullptr);
|
|
RpcClient(RpcClient&&) = delete;
|
|
RpcClient(RpcClient const&) = delete;
|
|
RpcClient& operator=(RpcClient&&) = delete;
|
|
RpcClient& operator=(RpcClient const&) = delete;
|
|
|
|
[[nodiscard]] constexpr auto const& url() const noexcept
|
|
{
|
|
return url_;
|
|
}
|
|
|
|
[[nodiscard]] constexpr auto isLocal() const noexcept
|
|
{
|
|
return session_ != nullptr || url_is_loopback_;
|
|
}
|
|
|
|
void stop();
|
|
void start(tr_session* session);
|
|
void start(QUrl const& url);
|
|
|
|
RpcResponseFuture exec(tr_quark method, tr_variant* args);
|
|
|
|
signals:
|
|
void httpAuthenticationRequired();
|
|
void dataReadProgress();
|
|
void dataSendProgress();
|
|
void networkResponse(QNetworkReply::NetworkError code, QString const& message);
|
|
|
|
private slots:
|
|
void networkRequestFinished(QNetworkReply* reply);
|
|
void localRequestFinished(TrVariantPtr response);
|
|
|
|
private:
|
|
QNetworkAccessManager* networkAccessManager();
|
|
|
|
void sendNetworkRequest(QByteArray const& body, QFutureInterface<RpcResponse> const& promise);
|
|
void sendLocalRequest(tr_variant& req, QFutureInterface<RpcResponse> const& promise, int64_t id);
|
|
[[nodiscard]] int64_t parseResponseId(tr_variant& response) const;
|
|
[[nodiscard]] RpcResponse parseResponseData(tr_variant& response) const;
|
|
|
|
// TODO: change this default in 5.0.0-beta.1
|
|
static auto constexpr DefaultNetworkStyle = libtransmission::api_compat::Style::Tr4;
|
|
|
|
libtransmission::api_compat::Style network_style_ = DefaultNetworkStyle;
|
|
tr_session* session_ = {};
|
|
QByteArray session_id_;
|
|
QUrl url_;
|
|
QNetworkAccessManager* nam_ = {};
|
|
std::unordered_map<int64_t, QFutureInterface<RpcResponse>> local_requests_;
|
|
bool const verbose_ = qEnvironmentVariableIsSet("TR_RPC_VERBOSE");
|
|
bool url_is_loopback_ = false;
|
|
};
|